%% -*- mode: Prolog;  -*-

:- discontiguous about/1.
:- index(f(1,1,0,0,1,0)).
:- dynamic f/6.

%%% shorthand for creating structs

term_expansion(F = Slots ,L) :-
    findall(Y, def(F,Slots,Y), L).

def(F,Slots, f(Slot,F,Old,New,T0,T1)) :- 
	member(Slot,Slots),
        old2New(Slots,L0,L1,Slot,Old,New),
	T0 =.. [F|L0],
	T1 =.. [F|L1].

old2New([],[],[],_,_,_).
old2New([H0|T0],[H1|T1],[H2|T2],Want,Old,New) :-
	(H0 = Want -> Old = H1, New = H2 ;  H1 = H2),
	old2New(T0,T1,T2,Want,Old,New).

%%% query language

:- op(800,yfx,of).

swap(X,Y,Z,T0,T) :- 
	ok(X,T0),
	f(X,_,Y,Z,T0,T).

ok(X,T) :- 
	f(X,_,_,_,T,_)
        -> true 
        ;  functor(T,F,A),print(noCanDXo(F,A,X)),nl,fail.

o(X,T) :- o(X,T,_).

o([]       ,T ,T).
o([X|Y]    ,T0,T) :- o(X,T0,T1), o(Y,T1,T).

o(X =  Y  , T0,T) :- swap(X,Y,Y,T0,T).
o(X of Y  , T0,T) :- swap(Y,Old,New,T0,T), o(X,Old,New).
o(push(X,Y),T0,T) :- swap(X,Z,    [Z|Y],T0,T).
o(pop(X,Y), T0,T) :- swap(X,[Y|Z],    Z,T0,T).

o(X >= Y  , T ,T) :- o(X=Z,T,T), Z >= Y.
o(X >  Y  , T ,T) :- o(X=Z,T,T), Z >  Y.
o(X <  Y  , T ,T) :- o(X=Z,T,T), Z <  Y.
o(X =< Y  , T ,T) :- o(X=Z,T,T), Z =< Y.

%%% optimizer (must come AFTER query system).

:- dynamic xpand/1.
xpand(o(_,_)).
xpand(o(_,_,_)).
xpand(swap(_,_,_,_,_)).
xpand(f(_,_,_,_,_,_)).

do(ok(_,_)).

goal_expansion(X,true) :-
	do(X),
	X.

goal_expansion(X,Y) :- 
	xpand(X), singleton(X), clause(X,Y).

singleton(X) :- findall(_,clause(X,_),[_]).

%%% begin my code

state = [here,there,if,do].
locale = [here,lat,long].
pair = [x,y].
 
xx(X,Z,T) :-
	o([long=Z,
           x = X of there of lat],T).