Computational Logic 
The (ISO)Prolog Programming Language 
minipage0.9
itemize
Reading the first slides of the Ciao tutorial regarding the use
of the compiler, toplevel, debuggers, environment, module system,
etc. is suggested at this point.
Also, reading the corresponding parts of the Ciao manual.
Standard Notation  Operator Notation 
'+'(a,'/'(b,c))  a+b/c 
is(X, mod(34, 7))  X is 34 mod 7 
'<'('+'(3,4),8)  3+4 < 8 
'='(X,f(Y))  X = f(Y) 
''(3)  3 
spy('/'(foo,3))  spy foo/3 
':'(p(X),q(Y))  p(X) : q(Y) 
':'(p(X),','(q(Y),r(Z)))  p(X) : q(Y),r(Z) 
: op( 1200, xfx, [ :, > ]). : op( 1200, fx, [ :, ? ]). : op( 1150, fx, [ mode, public, dynamic, multifile, block, meta_predicate, parallel, sequential ]). : op( 1100, xfy, [ ; ]). : op( 1050, xfy, [ > ]). : op( 1000, xfy, [ ',' ]). : op( 900, fy, [ \+, spy, nospy ]). : op( 700, xfx, [ =, is, =.., ==, \==, @<, @>, @=<, @>=, =:=, =\=, <, >, =<, >= ]). : op( 550, xfy, [ : ]). : op( 500, yfx, [ +, , #, /\, \/ ]). : op( 500, fx, [ +,  ]). : op( 400, yfx, [ *, /, //, <<, >> ]). : op( 300, xfx, [ mod ]). : op( 200, xfy, [ ^ ]).
grandparent(C,G): parent(C,P), parent(P,G). parent(C,P): father(C,P). parent(C,P): mother(C,P). father(charles,philip). father(ana,george). mother(charles,ana).
p(X,Y): q(X,Z), r(Z,Y).
q(X,Z) : ...when the call to q/2 finishes (with ``success''), execution continues in the next procedure call (literal) in p/2, i.e., the call to r/2 (the forward continuation).
p(X,Y): q(X,Z), r(Z,Y).
q(X,Z) : ... q(X,Z) : ...if the call to q/2 succeeds, it is as above, but if it fails at any point, execution continues (``backtracks'') at the second clause of q/2 (the backward continuation).
The programmer has at least three important ways of controlling
execution:
p(X): X = 4. q(X, Y): X = 1, Y = a, ... p(X): X = 5. q(X, Y): X = 2, Y = b, ... q(X, Y): X = 4, Y = c, ... q(X, Y): X = 4, Y = d, ...p(X), q(X,Y) more efficient: execution of p/2 reduces the choices of q/2.
p(X): X = 4. q(X, Y): X = 4, Y = d, ... p(X): X = 5. q(X, Y): X = 4, Y = c. ... q(X, Y): X = 2, Y = b, ... q(X, Y): X = 1, Y = a, ...we get {X=4,Y=d} first and then {X=4,Y=c}.
[37]> ciao  Invoke the system 
Ciao 1.11 #211: Thu Mar 18 15:28:12 CET 2004  
? use_module(file).  Load your program file 
yes  
? query_containing_variable_X.  Query the program 
X = binding_for_X ;  See one answer, ask for another using ``;'' 
X = another_binding_for_X enter  Discard rest of answers using enter 
? another query.  Submit another query 
? .......  
? halt.  End the session, also with ^ D 
? compile(file).
? consult(file). ? [file].
? compile([file1,file2]). ? [file1,file2].
? [user].  append([],Ys,Ys).  append([XXs],Ys,[XZs]): append(Xs,Ys,Zs).  ^D {user consulted, 0 msec 480 bytes} yes ?
: module(member,[member/2]). member(X, [X_Rest]). member(X, [_YRest]): member(X, Rest).
? use_module(member). yes ? member(c,[a,b,c]). yes ? member(d,[a,b,c]). no ? member(X,[a,b,c]). X = a ? ; X = b ? (intro) yes
Ciao 1.13 #0: Fri Jul 8 11:46:55 CEST 2005 ? use_module('/home/logalg/public_html/slides/lmember.pl'). yes ? debug_module(lmember). {Consider reloading module lmember} {Modules selected for debugging: [lmember]} {No module is selected for source debugging} yes ? trace. {The debugger will first creep  showing everything (trace)} yes {trace} ?
? lmember(X,[a,b]). 1 1 Call: lmember:lmember(_282,[a,b]) ? 1 1 Exit: lmember:lmember(a,[a,b]) ? X = a ? ; 1 1 Redo: lmember:lmember(a,[a,b]) ? 2 2 Call: lmember:lmember(_282,[b]) ? 2 2 Exit: lmember:lmember(b,[b]) ? 1 1 Exit: lmember:lmember(b,[a,b]) ? X = b ? ; 1 1 Redo: lmember:lmember(b,[a,b]) ? 2 2 Redo: lmember:lmember(b,[b]) ? 3 3 Call: lmember:lmember(_282,[]) ? 3 3 Fail: lmember:lmember(_282,[]) ? 2 2 Fail: lmember:lmember(_282,[b]) ? 1 1 Fail: lmember:lmember(_282,[a,b]) ? no
h  Get help  gives this list (possibly with more options) 
c  Creep forward to the next event 
Advances execution until next call/exit/redo/fail  
intro  (same as above) 
s  Skip over the details of executing the current goal 
Resume tracing when execution returns from current goal  
l  Leap forward to next ``spypoint'' (see below) 
f  Make the current goal fail 
This forces the last pending branch to be taken  
a  Abort the current execution 
r  Redo the current goal execution 
very useful after a failure or exit with weird result  
b  Break  invoke a recursive top level 
Place a spypoint on predicate foo of arity 3  always trace events involving this predicate.
Remove the spypoint in foo/3.
Remove all spypoints.


plus(X,Y,Z): number(X),number(Y), Z is X + Y. plus(X,Y,Z): number(X),number(Z), Y is Z  X. plus(X,Y,Z): number(Y),number(Z), X is Z  Y.
Then:
? plus(3,Y,5). Y = 2 ?
? plus(X,Y,5). no
(in fact, this should raise an error, rather than simply failing).
Examples:
? _T=date(9,February,1947), arg(3,_T,X). X = 1947 ? _T=date(9,February,1947), _T=date(_,_,X). X = 1947 ? functor(Array,array,5), arg(1,Array,black), arg(5,Array,white). Array = array(black,_,_,_,white).
subterm(Term,Term). subterm(Sub,Term): functor(Term,F,N), subterm(N,Sub,Term). subterm(N,Sub,Term): arg(N,Term,Arg), % also checks N > 0 (arg/1 fails otherwise!) subterm(Sub,Arg). subterm(N,Sub,Term): N>1, N1 is N1, subterm(N1,Sub,Term).
add_arrays(A1,A2,A3): % Same N imposes equal length: functor(A1,array,N), functor(A2,array,N), functor(A3,array,N), add_elements(N,A1,A2,A3).
add_elements(0,_A1,_A2,_A3). add_elements(I,A1,A2,A3): I>0, arg(I,A1,X1), arg(I,A2,X2), arg(I,A3,X3), X3 is X1 + X2, I1 is I  1, add_elements(I1,A1,A2,A3).
add_arrays_lists([],[],[]). add_arrays_lists([XXs],[YYs],[ZZs]): Z is X + Y, add_arrays_lists(Xs,Ys,Zs).
? date(9,february,1947) =.. L. L = [date,9,february,1947]. ? _F = '+', X =.. [_F,a,b]. X = a + b.
Example: Extending derivative
derivative(sin(X),X,cos(X)). derivative(cos(X),X,sin(X)). derivative(FG_X, X, DF_G * DG_X): FG_X =.. [_, G_X], derivative(FG_X, G_X, DF_G), derivative(G_X, X, DG_X).
? name(hello,S). S = [104,101,108,108,111] ? name(A,[104,101,108,108,111]). A = hello ? name(A,"hello"). A = hello
length(Xs,N): var(Xs), integer(N), length_num(N,Xs). length(Xs,N): nonvar(Xs), length_list(Xs,N). length_num(0,[]). length_num(N,[_Xs]): N > 0, N1 is N  1, length_num(N1,Xs). length_list([],0). length_list([XXs],N): length_list(Xs,N1), N is N1 + 1.
subterm(Sub,Term): Sub == Term. subterm(Sub,Term): nonvar(Term), functor(Term,F,N), subterm(N,Sub,Term).
where subterm/3 is identical to the previous definition
insert([], Item, [Item]). insert([HT], Item, [HT]): H == Item. insert([HT], Item, [Item, HT]): H @> Item. insert([HT], Item, [HNewT]) : H @< Item, insert(T, Item, NewT).
insert([HT], Item, [ItemT]): H = Item.
Class  Predicate  Explanation 
I/O stream control  see(File)  File becomes the current input stream. 
seeing(File)  The current input stream is File.  
seen  Close the current input stream.  
tell(File)  File becomes the current output stream.  
telling(File)  The current output stream is File.  
told  Close the current output stream.  
Term I/O  write(X)  Write the term X on the current output stream. 
nl  Start a new line on the current output stream.  
read(X)  Read a term (finished by a full stop) from the current input stream and unify it with X.  
Character I/O  put_code(N)  Write the ASCII character code N. N can be a string of length one. 
get_code(N)  Read the next character code and unify its ASCII code with N. 
Class  Predicate  Explanation 
I/O stream control  open(File,M,S)  Open `File' with mode M and return in S the stream associated with the file. M may be read, write or append. 
close(Stream)  Close the stream `Stream'.  
Term I/O  write(S,X)  Write the term X on stream S. 
nl(S)  Start a new line on stream S.  
read(S,X)  Read a term (finished by a full stop) from the stream S and unify it with X.  
Character I/O  put_code(S,N)  Write the ASCII character code N on stream S. 
get_code(S,N)  Read from stream S the next character code and unify its ASCII code with N. 
write_list_to_file(L,F) : telling(OldOutput), % Grab current output stream. tell(F), write_list(L), told, % Write into F, close. tell(OldOutput). % Reset previous output stream. write_list([]). write_list([XXs]): write(X), nl, write_list(Xs).
s(a). p(X,Y): l(X), ... r(a). s(b). p(X,Y): r(X), !, ... r(b). p(X,Y): m(X), ...with query ? s(A),p(B,C).
s(a). p(X,Y): l(X), ... r(a). s(b). p(X,Y): r(X), !, ... r(b). p(X,Y): m(X), ...
max(X,Y,X): X > Y, !. max(X,Y,Y): X =< Y.They affect neither completeness nor correctness  use them freely.
address(X,Add): home_address(X,Add), !. address(X,Add): business_address(X,Add).
membercheck(X,[XXs]): !. membercheck(X,[YXs]): membercheck(X,Xs).They affect completeness but not correctness.
max(X,Y,X): X > Y,!. max(X,Y,Y).wrong answers to, e.g., ? max(5, 2, 2).
days_in_year(X,366): leap_year(X),!. days_in_year(X,365).wrong answers to, e.g., ? days_in_year(a, D).
Red cuts affect completeness and one can no longer rely on the strict declarative interpretation of the program for reasoning about correctness  avoid when possible.
q(a). p(X) : call(X). ? p(q(Y)). Y = a
q(a,b). apply(F,Args) : G =.. [FArgs], call(G). ? apply(q,[Y,Z]). Y = a Z = b




not(Goal) : call(Goal), !, fail. not(Goal).
unmarried_student(X): not(married(X)), student(X). student(joe). married(john).
ground(Term): var(Term), !, fail. ground(Term): nonvar(Term), functor(Term,F,N), ground(N,Term). ground(0,T). %% All subterms traversed ground(N,T): N>0, arg(N,T,Arg), ground(Arg), N1 is N1, ground(N1,T).
relate_numbers(X, Y): assert(related(X, Y)). unrelate_numbers(X, Y): retract(related(X, Y)).
? related(1, 2). {EXISTENCE ERROR: ...} ? relate_numbers(1, 2). yes ? related(1, 2). yes ? unrelate_numbers(1, 2). yes ? related(1, 2). no
fib(0, 0). fib(1, 1). fib(N, F): N > 1, N1 is N  1, N2 is N1  1, fib(N1, F1), fib(N2, F2), F is F1 + F2. 
lfib(N, F): lemma_fib(N, F), !. lfib(N, F): N > 1, N1 is N  1, N2 is N1  1, lfib(N1, F1), lfib(N2, F2), F is F1 + F2, assert(lemma_fib(N, F)). : dynamic lemma_fib/2. lemma_fib(0, 0). lemma_fib(1, 1). 
solve(true). solve((A,B)) : solve(A), solve(B). solve(A) : clause(A,B), solve(B).
dlist(XY) : var(X), !, X==Y. dlist([_DL]X) : dlist(DLX).(Non declarative!)
append_dl(XY,YZ,XZ).(actually, no call to append_dl is normally necessary)
qsort([],[]). qsort([XL],R) : partition(L,X,L1,L2), qsort(L2,R2), qsort(L1,R1), append(R1,[XR2],R). partition([],_B,[],[]). partition([ER],C,[ELeft1],Right): E < C, partition(R,C,Left1,Right). partition([ER],C,Left,[ERight1]): E >= C, partition(R,C,Left,Right1).
dlqsort(L,SL) : dlqsort_(L,SL,[]). dlqsort_([],R,R). dlqsort_([XL],R,R1) : partition(L,X,L1,L2), dlqsort_(L1,R,[XR0]), dlqsort_(L2,R0,R1). % Partition is the same as before.
%% ? myphrase([t,h,e,' ',p,l,a,n,e,' ',f,l,i,e,s]). myphrase(X) : append(A,T1,X), article(A), append(SP,T2,T1), spaces(SP), append(N,T3,T2), noun(N), append(SPN,V,T3), spaces(SPN), verb(V). article([a]). article([t,h,e]). spaces([' ']). spaces([' '  Y]) : spaces(Y). noun([c,a,r]). noun([p,l,a,n,e]). verb([f,l,i,e,s]). verb([d,r,i,v,e,s]).
%% ? myphrase([t,h,e,' ',p,l,a,n,e,' ',f,l,i,e,s],[]). myphrase(X,CV) : article(X,CA), spaces(CA,CS1), noun(CS1,CN), spaces(CN,CS2), verb(CS2,CV). article([t,h,eX],X). article([aX],X). spaces([' '  X],X). spaces([' '  Y],X) : spaces(Y,X). noun([p,l,a,n,e  X],X). noun([c,a,r  X],X). verb([f,l,i,e,s  X],X). verb([d,r,i,v,e,s  X],X).
%% ? myphrase("the plane flies",[]). myphrase(X,CV) : article(X,CA), spaces(CA,CS1), noun(CS1,CN), spaces(CN,CS2), verb(CS2,CV). article( "the"  X, X). article( "a"  X, X). spaces( " "  X, X). spaces( " "  Y, X) : spaces(Y, X). noun( "plane"  X, X). noun( "car"  X, X). verb( "flies"  X, X). verb( "drives"  X, X).
%% ? myphrase("the plane flies",[]). %% or, use ``phrase/2'' builtin: %% ? phrase(myphrase,"the plane flies"). : use_package(dcg). myphrase > article, spaces, noun, spaces, verb. article > "the". spaces > " ". article > "a". spaces > " ", spaces. noun > "plane". verb > "flies". noun > "car". verb > "drives".
%% ? myphrase(NChars,"the plane flies",[]). %% ? phrase(myphrase(N),"the plane flies"). : use_package(dcg). myphrase(N) > article(AC), spaces(S1), noun(NC), spaces(S2), verb(VC), { N is AC + S1 + NC + S2 + VC}. article(3) > "the". spaces(1) > " ". article(1) > "a". spaces(N) > " ", spaces(N1), { N is N1+1 }. noun(5) > "plane". verb(5) > "flies". noun(3) > "car". verb(6) > "drives".
Arrays  Assoc  Attributes  Heaps 
Lists  Term Utilities  Ordset  Queues 
Random  System Utilities  Tree  UGraphs 
WGraphs  Sockets  Linda/Distribution  Persistent DB 
CLPB  CLPQR  CLPFD  Objects 
GCLA  TclTk  Tracing  Chars I/O 
Runtime Utilities  Timeout  Xrefs  WWW 
Java Interface  ...  ...  ... 
Other systems may offer additional extensions. Some examples from Ciao: