Ciao Preprocessor (integrated Alpha version)
 | This is an alpha distribution, meant only for testing. Please do let us 
 | know at ciaopp-bugclip.dia.fi.upm.es any problems you may have.

{Reading /tmp/tmpGW2ZbU/qplan.pl
}
{In /tmp/tmpGW2ZbU/qplan.pl
{loaded in 3444.216 msec.}
{preprocessed for plai in 16.002 msec.}
{analyzed by plai using det with local-control off in 4.0 msec.}
{written file /tmp/tmpGW2ZbU/qplan_det_co.pl}
:- module(_1,[qplan/2],[assertions]).

:- op(900,xfx,`=).

:- op(900,xfx,=+).

:- op(900,xfx,=:).

:- op(450,xfy,:).

:- op(400,xfy,##).

:- op(300,fx,`).

:- op(200,xfx,--).

:- op(359,xf,ject).

:- entry qplan(A,B)
         : ground(A).

:- true pred qplan(A,B)
         : ( native_props:mshare([[B]]), ground([A]), gnd(A), term(B) )
        => ( ground([A,B]), gnd(A), gnd(B) )
         + ( is_det, mut_exclusive ).

qplan((P:-Q),(P1:-Q1)) :-
        qplan(P,Q,P1,Q1),
        !.
qplan(P,P).

:- true pred qplan(X0,P0,X,P)
         : ( native_props:mshare([[X],[X,P],[P]]), ground([X0,P0]), gnd(X0), gnd(P0), term(X), term(P) ).

qplan(X0,P0,X,P) :-
        qplan:numbervars(X0,0,I),
        variables(X0,0,Vg),
        qplan:numbervars(P0,I,N),
        mark(P0,L,0,Vl),
        schedule(L,Vg,P1),
        quantificate(Vl,0,P1,P2),
        functor(VA,$,N),
        variablise(X0,VA,X),
        variablise(P2,VA,P).

mark(X^P,L,Q0,Q) :-
        !,
        variables(X,Q0,Q1),
        mark(P,L,Q1,Q).
mark((P1,P2),L,Q0,Q) :-
        !,
        mark(P1,L1,Q0,Q1),
        mark(P2,L2,Q1,Q),
        recombine(L1,L2,L).
mark(\+P,L,Q,Q) :-
        !,
        mark(P,L0,0,Vl),
        negate(L0,Vl,L).
mark(SQ,[m(V,C,SQ1)],Q0,Q0) :-
        subquery(SQ,SQ1,X,P,N,Q),
        !,
        mark(P,L,0,Vl),
        L=[Q],
        marked(Q,Vq,C0,_1),
        variables(X,Vl,Vlx),
        setminus(Vq,Vlx,V0),
        setofcost(V0,C0,C),
        variables(N,V0,V).
mark(P,[m(V,C,P)],Q,Q) :-
        variables(P,0,V),
        cost(P,V,C).

subquery(setof(X,P,S),setof(X,Q,S),X,P,S,Q).
subquery(numberof(X,P,N),numberof(X,Q,N),X,P,N,Q).

negate([],_1,[]).
negate([P|L],Vl,[m(Vg,C,\+P)|L1]) :-
        freevars(P,V),
        setminus(V,Vl,Vg),
        negationcost(Vg,C),
        negate(L,Vl,L1).

negationcost(0,0) :- !.
negationcost(V,1000).

setofcost(0,_1,0) :- !.
setofcost(_1,C,C).

variables('$MYVAR'(N),V0,V) :-
        !,
        setplusitem(V0,N,V).
variables(T,V,V) :-
        atomic(T),
        !.
variables(T,V0,V) :-
        functor(T,_1,N),
        variables(N,T,V0,V).

variables(0,_1,V,V) :- !.
variables(N,T,V0,V) :-
        N1 is N-1,
        arg(N,T,X),
        variables(X,V0,V1),
        variables(N1,T,V1,V).

quantificate(W-V,N,P0,P) :-
        !,
        N1 is N+18,
        quantificate(V,N,P1,P),
        quantificate(W,N1,P0,P1).
quantificate(0,_1,P,P) :- !.
quantificate(V,N,P0,'$MYVAR'(Nr)^P) :-
        Vr is V/\ -V,
        log2(Vr,I),
        Nr is N+I,
        N1 is Nr+1,
        V1 is V>>(I+1),
        quantificate(V1,N1,P0,P).

log2(1,0) :- !.
log2(2,1) :- !.
log2(4,2) :- !.
log2(8,3) :- !.
log2(N,I) :-
        N1 is N>>4,
        N1=\=0,
        log2(N1,I1),
        I is I1+4.

schedule([P],Vg,Q) :-
        !,
        schedule1(P,Vg,Q).
schedule([P1|P2],Vg,(Q1,Q2)) :-
        !,
        schedule1(P1,Vg,Q1),
        schedule(P2,Vg,Q2).

schedule1(m(V,C,P),Vg,Q) :-
        maybe_cut(V,Vg,Q0,Q),
        plan(P,V,C,Vg,Q0).

maybe_cut(V,Vg,P,{P}) :-
        disjoint(V,Vg),
        !.
maybe_cut(V,Vg,P,P).

plan(\+P,Vg,_1,_2,\+Q) :-
        !,
        Vg=0,
        marked(P,V,C,P1),
        plan(P1,V,C,Vg,Q1),
        quantificate(V,0,Q1,Q).
plan(SQ,Vg,_1,_2,SQ1) :-
        subquery(SQ,SQ1,X,P,_3,Q),
        !,
        marked(P,V,C,P1),
        variables(X,Vg,Vgx),
        setminus(V,Vgx,Vl),
        quantificate(Vl,0,Q1,Q),
        plan(P1,V,C,Vgx,Q1).
plan(P,V,C,Vg,(Q,R)) :-
        is_conjunction(P),
        !,
        best_goal(P,V,C,P0,V0,PP),
        plan(P0,V0,C,Vg,Q),
        instantiate(PP,V0,L),
        add_keys(L,L1),
        qplan:keysort(L1,L2),
        strip_keys(L2,L3),
        schedule(L3,Vg,R).
plan(P,_1,_2,_3,P).

is_conjunction((_1,_2)).

marked(m(V,C,P),V,C,P).

freevars(m(V,_1,_2),V).

best_goal((P1,P2),V,C,P0,V0,m(V,C,Q)) :-
        !,
        'best_goal/6/1/$disj/1'(C,P1,P2,Q,Va,Pa,Pb),
        !,
        best_goal(Pa,Va,C,P0,V0,Pb).
best_goal(P,V,C,P,V,true).

'best_goal/6/1/$disj/1'(C,P1,P2,Q,Va,Pa,Pb) :-
        marked(P1,Va,C,Pa),
        Q=(Pb,P2).
'best_goal/6/1/$disj/1'(C,P1,P2,Q,Va,Pa,Pb) :-
        marked(P2,Va,C,Pa),
        Q=(P1,Pb).

instantiate(true,_1,[]) :- !.
instantiate(P,Vi,[P]) :-
        freevars(P,V),
        disjoint(V,Vi),
        !.
instantiate(m(V,_1,P),Vi,L) :-
        instantiate0(P,V,Vi,L).

instantiate0((P1,P2),_1,Vi,L) :-
        instantiate(P1,Vi,L1),
        instantiate(P2,Vi,L2),
        recombine(L1,L2,L).
instantiate0(\+P,V,Vi,L) :-
        !,
        instantiate(P,Vi,L0),
        freevars(P,Vf),
        setminus(Vf,V,Vl),
        negate(L0,Vl,L).
instantiate0(SQ,Vg,Vi,[m(V,C,SQ1)]) :-
        subquery(SQ,SQ1,X,P,_1,Q),
        !,
        instantiate(P,Vi,L),
        L=[Q],
        marked(Q,Vq,C0,_2),
        setminus(Vg,Vi,V),
        variables(X,0,Vx),
        setminus(V,Vx,V0),
        setofcost(V0,C0,C).
instantiate0(P,V,Vi,[m(V1,C,P)]) :-
        setminus(V,Vi,V1),
        cost(P,V1,C).

recombine(L,[],L) :- !.
recombine([],L,L).
recombine([P1|L1],[P2|L2],L) :-
        marked(P1,V1,C1,_1),
        nonempty(V1),
        incorporate(P1,V1,C1,P2,L2,L3),
        !,
        recombine(L1,L3,L).
recombine([P|L1],L2,[P|L]) :-
        recombine(L1,L2,L).

incorporate(P0,V0,C0,P1,L1,L) :-
        marked(P1,V1,C1,_1),
        intersect(V0,V1),
        !,
        setplus(V0,V1,V),
        minimum(C0,C1,C),
        incorporate0(m(V,C,(P0,P1)),V,C,L1,L).
incorporate(P0,V0,C0,P1,[P2|L1],[P1|L]) :-
        incorporate(P0,V0,C0,P2,L1,L).

incorporate0(P0,V0,C0,[P1|L1],L) :-
        incorporate(P0,V0,C0,P1,L1,L),
        !.
incorporate0(P,_1,_2,L,[P|L]).

minimum(N1,N2,N1) :-
        N1=,99,51,51).
nd(>=,99,51,51).

nd(aggregate,103,3,100,51).
nd(ratio,99,51,51,3).
nd(flows,19,16,22,22).