:- module(_,_,[]).

% Meta-interpreters
% ----------------

% Ciao-specific: version of 'dynamic' package that makes dynamic
% clauses visible to clause/2
:- use_package(dynamic_clauses).

% Declares lappend/3 dynamic, and thus visible to clause/2
:- dynamic lappend/3.

lappend([],X,X).
lappend([X|Y],Z,[X|W]) :- lappend(Y,Z,W).

% Try (ask for several solutions):
% ?- clause(lappend(A,B,C),Body).

% Module qualification 'metaint' used to access clauses
% within the 'metaint'module.

% The 'vanilla' 3-line meta-interpreter:
solve( true  ) :- !.
solve( (A,B) ) :- !, solve(A),    solve(B).
solve( A     ) :- clause(A,B), solve(B).

% Try (asking for multiple solutions):
% ?- solve(lappend([1,2],[3,4],L)).
% ?- solve(lappend(X,Y,[1,2,3,4])).

% This meta interpreter also implements backtracking!

% An application:
% A version of the meta-interpreter that uses an extra argument to
% count the number of (forward) steps.
csolve( true,  0) :- !.
csolve( (A,B), N) :- !, csolve(A,NA), csolve(B,NB), N is NA+NB.
csolve( A,     N) :- clause(A,B),  csolve(B,N1), N is N1+1.

% Try:
% ?- csolve(lappend([1,2],[3,4],L),N).
% ?- csolve(lappend([1,2,a,b],[3,4],L),N).
% ?- csolve(lappend([1,2],[3,4,a,b],L),N).

% What does the cost (number of steps) of a call to append depend on?
