%%% Meta-interpreter for Prolog with the freeze predicate by Jacques Cohen


%%% replace lists with , operator in tail.

solve(Goal) :-
	solve(Goal, [], OutFreezer),
	format('~NFreezer contains: ~w~n', [OutFreezer]).

%solve(true, Freezer, Freezer).

solve(Goal, Freezer, NewFreezer) :- 
	Goal =.. [Pred|Args],
	length(Args,Arity),
	direct(Pred/Arity),
	!,
	Goal,
	defrost(Freezer,NewFreezer).

solve((Goal,RestGoal), Freezer, NewFreezer) :-
	solve(Goal, Freezer, TempFreezer),
	solve(RestGoal, TempFreezer, NewFreezer).

solve(Goal, Freezer, NewFreezer) :-
	clause(Goal, Tail),
	defrost(Freezer,TempFreezer),
	solve(Tail, TempFreezer, NewFreezer).

solve(freeze(X,Goal), Freezer, [ [X|Goal] | Freezer]) :-
	var(X).

solve(freeze(X,Goal), Freezer, NewFreezer) :-
	nonvar(X),
	solve(Goal,Freezer,NewFreezer).


defrost([],[]).

defrost( [ [X|Goal] | Freezer], [ [X|Goal] | NewFreezer] ) :-
	var(X),
	defrost(Freezer, NewFreezer).

defrost( [ [X|Goal] | Freezer], NewFreezer) :-
	nonvar(X),
	defrost(Freezer, TempFreezer),
	solve(Goal, TempFreezer, NewFreezer).


:- dynamic foo/0.

foo :- freeze(X, print(X)), print(a), X=b.

direct(true/0).
direct(print/1).
direct('='/2).

