%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% define operators 

:- op(999, xfx, if).
:- op(998, xfx, then).
:- op(997, xfy, or).
:- op(996, xfy, and).
:- op(995,  fx, not).
:- op(994, xfy, has).
:- op(993, xfx, of).
:- op(992, xfx, in).
:- op(991, xfx, to).
:- op(1,   xfx, for).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% define a file within which we unwind singletons

myspace(File) :-
	working_directory(X,X),
	atom_concat(X,'zmyspace.pl',File).

mine(X) :- 
	nonvar(X), 
	myspace(File), 
	predicate_property(X,file(File)).

goal_expansion(Head,Body) :- 
	mine(Head),
	singleton(Head,Body).

clauses(Head,All) :- 
	findall(Head/Body,clause(Head,Body),All).

singleton(Head,Body) :- 
	clauses(Head,[Head/Body]).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% genetic syntactic sugar tricks 

%term_expansion(A if B,(A :- B)).
goal_expansion(call(X),X).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% rule compiler 

:- discontiguous match/3, act/3.
:- index(match(1,1,0)).
:- index(act(1,1,0)).

term_expansion(R for Cxt if X then Y, [If,Then]) :-
	print(11),nl,
	xpandr(R for Cxt if X then Y, If,Then).

xpandr(R for Cxt if X then Y, If,Then) :-
	expand_term((match(R,Cxt,Shared) :- X), If),
    expand_term((act(  R,Cxt,Shared) :- Y), Then),
	sharedVars(X,Y,Shared).

sharedVars(T1,T2,V) :- 
	vars(T1,V1), 
	vars(T2,V2), 
    sharedVars1(V1,V2,V),!.
sharedVars(_,_,[]).

sharedVars1([],    _,[]).
sharedVars1([H|T0],L,[H|T]) :- 
	member(X,L),H == X,!,
   	sharedVars1(T0,L,T).
sharedVars1([_|T0],L,T) :- 
	sharedVars1(T0,L,T).

vars(Term,All) :- setof(One,vars1(Term,One),All).

vars1(Term,V) :- subterm(Term,V), var(V).

subterm(X,X).
subterm(In, X) :- 
	compound(In), 
	arg(_,In,Arg),
    subterm(Arg,X).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% forward chaining

fchain :- reset, run(start), report.

:- dynamic used/3.
:- index(used(1,1,0)).

reset :- retractall(used(_,_,_)).

run(Cxt) :- 
	match(   R,Cxt,Vars), 
	select1( R,Cxt,Vars), !,
	act(     R,Cxt,Vars),
	run(Cxt).
run(_).

report :- listing(used).

select1(R,Cxt,Vars) :- 
	not(   used(R,Cxt,Vars)), 
	assert(used(R,Cxt,Vars)).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% load the spec

spec :- 
	myspace(X),print(loading(X)),nl,load_files([X]).

:- spec.
