-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
314 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# Mac OS files | ||
*.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
## Prolog files for labs ## | ||
This folder contains Prolog files for lab exercises. | ||
Interactive online version of these is available [here](http://labs.simply-logical.space). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
biglist(Low,High,L):- | ||
bagof(X,between(Low,High,X),L). | ||
|
||
% between/3 is built-in but could have been defined as follows: | ||
% between(Low,_High,Low). | ||
% between(Low,High,Number):- | ||
% Low < High, | ||
% NewLow is Low+1, | ||
% between(NewLow,High,Number). | ||
|
||
/** <examples> | ||
?- biglist(1,25,L). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
% fib(N,F) <- F is the N-th Fibonacci number | ||
% inefficient doubly-recursive version | ||
fib(1,1). | ||
fib(2,1). | ||
fib(N,F):- | ||
N>2,N1 is N-1,N2 is N-2, | ||
fib(N1,F1),fib(N2,F2), | ||
F is F1+F2. | ||
|
||
/** <examples> | ||
?- fib(5,F). | ||
?- fib(10,F). | ||
?- fib(20,F). | ||
?- fib(25,F). | ||
?- fib(30,F). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
% fibn(N,Na,Nb,F) <- F is the N-th Fibonacci number | ||
% in the sequence starting with Na, Nb | ||
fibn(1,Na,_,Na). | ||
fibn(2,_,Nb,Nb). | ||
fibn(N,Na,Nb,F):- | ||
N>2, N1 is N-1, | ||
Nc is Na+Nb, | ||
fibn(N1,Nb,Nc,F). | ||
|
||
% the original Fibonacci sequence starts with 1, 1 | ||
fibn(N,F):- | ||
fibn(N,1,1,F). | ||
|
||
/** <examples> | ||
?- member(N,[10,20,50,100,200]), fibn(N,F). | ||
?- maplist(fibn, [10,20,50,100,200], L). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
% :-use_rendering(svgtree). % uncomment this line to see visualisations | ||
|
||
% fibt(N,E) <- E is an arithmetic expression | ||
% representing the N-th Fibonacci number | ||
% that can be rendered as a tree | ||
% and evaluated with is/2. | ||
fibt(1,1). | ||
fibt(2,1). | ||
fibt(N,(F1+F2)):- | ||
N>2,N1 is N-1,N2 is N-2, | ||
fibt(N1,F1),fibt(N2,F2). | ||
|
||
/** <examples> | ||
?- fibt(5,E), F is E. | ||
?- fibt(10,E), F is E. | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
% :-use_rendering(chess). % Uncomment this line for chess renderer | ||
|
||
nqueens(N,Columns) :- | ||
setof(X,between(1,N,X),Rows), | ||
perm(Rows,Columns), % generator | ||
safe(Columns). % tester | ||
|
||
%%% tester | ||
safe([]). | ||
safe([Column|Columns]) :- | ||
noattack(Column,Columns,1), | ||
safe(Columns). | ||
|
||
noattack(_,[],_). | ||
noattack(Y,[Y1|Ylist],Xdist) :- | ||
abs(Y-Y1) =\= Xdist, | ||
Xdist1 is Xdist+1, | ||
noattack(Y,Ylist,Xdist1). | ||
|
||
%%% generator | ||
perm([],[]). | ||
perm(L,[X|PR]):- | ||
remove_one(X,L,R), | ||
perm(R,PR). | ||
|
||
remove_one(X,[X|Ys],Ys). | ||
remove_one(X,[Y|Ys],[Y|Zs]):- | ||
remove_one(X,Ys,Zs). | ||
|
||
/** <examples> | ||
?- nqueens(8,Columns). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
% powerset(S,PS) <- PS is the list of all sublists of S | ||
% First try | ||
powerset1([],[[]]). | ||
powerset1([H|T],PowerSet):- | ||
powerset1(T,PowerSetOfT), | ||
extend_pset(H,PowerSetOfT,PowerSet). % not tail-recursive | ||
|
||
% extend_pset(X,S,ES) <- ES contains two copies of each list in S, | ||
% one with X and one without | ||
extend_pset(_,[],[]). | ||
extend_pset(H,[List|MoreLists],[List,[H|List]|More]):- | ||
extend_pset(H,MoreLists,More). | ||
|
||
% Second try: swap calls in recursive clause | ||
powerset2([],[[]]). | ||
powerset2([H|T],PowerSet):- | ||
extend_pset(H,PowerSetOfT,PowerSet), % generator (bad! why?) | ||
powerset2(T,PowerSetOfT). % tail-recursive | ||
|
||
% Third try: use accumulator | ||
powerset([],PowerSet,PowerSet). | ||
powerset([H|T],Acc,PowerSet):- | ||
extend_pset(H,Acc,Acc1), % efficient generator | ||
powerset(T,Acc1,PowerSet). % tail-recursive | ||
|
||
powerset(Set,PowerSet):-powerset(Set,[[]],PowerSet). | ||
|
||
/** <examples> | ||
?- powerset1([a,b,c,d,e,f],PS). | ||
?- powerset2([a,b,c,d,e,f],PS). | ||
?- powerset([a,b,c,d,e,f],PS). | ||
?- extend_pset(1,[[],[2],[3],[2,3]],ES). | ||
?- extend_pset(1,S,ES). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
prove(A):- | ||
( A=true -> true % we're done | ||
; A=not(B) -> not(prove(B)) % negation as failure | ||
; A=(B,C) -> prove(B),prove(C) % conjunctive query | ||
; otherwise -> cl(A,B),prove(B) % resolve against clause | ||
). | ||
|
||
% cl(H,B) <- (H:-B) is object-level clause | ||
cl(rectangle,(polygon(4),angles(90))). | ||
cl(square,(rectangle,regular)). | ||
cl(triangle,polygon(3)). | ||
cl(equilateral_triangle,(triangle,regular)). | ||
%%% facts | ||
cl(polygon(4),true). | ||
cl(regular,true). | ||
cl(angles(90),true). | ||
|
||
/** <examples> | ||
?- prove(rectangle). | ||
?- prove(square). | ||
?- prove(not(triangle)). | ||
?- prove(not((rectangle,triangle))). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
% display a proof tree | ||
prove_p(A):-prove_p(A,P),write_proof(P). | ||
|
||
prove_p(A,P):- | ||
( A=true -> P=[] | ||
; A=(B,C) -> cl(B,D),conj_append(D,C,E), | ||
prove_p(E,PE),P=[p(A,(B:-D))|PE] | ||
; otherwise -> cl(A,B),prove_p(B,PB), | ||
P=[p(A,(A:-B))|PB] | ||
). | ||
|
||
write_proof([]):- | ||
write('...............[]'),nl. | ||
write_proof([p(A,B)|Proof]):- | ||
write((:-A)),nl, | ||
write('.....|'),write('..........'),write(B),nl, | ||
write('.....|'),write('..................../'),nl, | ||
write_proof(Proof). | ||
|
||
conj_append(A,B,C):- | ||
( A=true -> B=C | ||
; A=(A1,A2) -> C=(A1,C2),conj_append(A2,B,C2) | ||
; otherwise -> C=(A,B) | ||
). | ||
|
||
% cl(H,B) <- (H:-B) is object-level clause | ||
cl(rectangle,(polygon(4),angles(90))). | ||
cl(square,(rectangle,regular)). | ||
cl(triangle,polygon(3)). | ||
cl(equilateral_triangle,(triangle,regular)). | ||
%%% facts | ||
cl(polygon(4),true). | ||
cl(regular,true). | ||
cl(angles(90),true). | ||
|
||
/** <examples> | ||
?- prove_p(rectangle). | ||
?- prove_p(square). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
prove_r(A):- | ||
writeln(A), % show current query | ||
( A=true -> true | ||
; A=not(B) -> not(prove_r(B)) | ||
; A=(B,C) -> cl(B,D),conj_append(D,C,E),prove_r(E) | ||
; otherwise -> cl(A,B),prove_r(B) | ||
). | ||
|
||
conj_append(A,B,C):- | ||
( A=true -> B=C | ||
; A=(A1,A2) -> C=(A1,C2),conj_append(A2,B,C2) | ||
; otherwise -> C=(A,B) | ||
). | ||
|
||
% cl(H,B) <- (H:-B) is object-level clause | ||
cl(rectangle,(polygon(4),angles(90))). | ||
cl(square,(rectangle,regular)). | ||
cl(triangle,polygon(3)). | ||
cl(equilateral_triangle,(triangle,regular)). | ||
%%% facts | ||
cl(polygon(4),true). | ||
cl(regular,true). | ||
cl(angles(90),true). | ||
|
||
/** <examples> | ||
?- prove_r(rectangle). | ||
?- prove_r(square). | ||
?- prove_r(not(triangle)). | ||
?- prove_r(not((rectangle,triangle))). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
:-use_module(library(random)). % for randseq/3 to generate random lists | ||
|
||
% psort(L,SL) <- L and SL contain the same elements, SL is sorted | ||
psort(L,SL):- | ||
perm(L,SL), % generator | ||
write('. '), % demonstrate inefficiency of generator | ||
sorted(SL). % tester | ||
|
||
% perm(L,PL) <- L and PL are permutations of each other | ||
perm([],[]). | ||
perm(L,[X|PR]):- | ||
remove_one(X,L,R), | ||
perm(R,PR). | ||
|
||
% remove_one(X,Ys,Zs) <- Zs is Ys minus one occurence of X | ||
remove_one(X,[X|Ys],Ys). | ||
remove_one(X,[Y|Ys],[Y|Zs]):- | ||
remove_one(X,Ys,Zs). | ||
|
||
% sorted(L) <- L is a sorted list | ||
sorted([]). | ||
sorted([_X]). | ||
sorted([X,Y|L]):- | ||
( compare('=', X, Y) | ||
; compare('<', X, Y) | ||
), sorted([Y|L]). | ||
|
||
/** <examples> | ||
?- randseq(5,100,In), psort(In,Out). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
% list of pairs | ||
p1(L,X,Y):- | ||
bagof((X,Y),(between(1,3,X),between(X,3,Y)),L). | ||
|
||
% one list for each X | ||
p2(L,X,Y):- | ||
bagof(Y,(between(1,3,X),between(X,3,Y)),L). | ||
|
||
% lists for each X combined | ||
p3(L,X,Y):- | ||
bagof(Y,X^(between(1,3,X),between(X,3,Y)),L). | ||
|
||
% one list for each Y | ||
p4(L,X,Y):- | ||
bagof(X,(between(1,3,X),between(X,3,Y)),L). | ||
|
||
% lists for each Y combined | ||
p5(L,X,Y):- | ||
bagof(X,Y^(between(1,3,X),between(X,3,Y)),L). | ||
|
||
/** <examples> | ||
?- p1(L,X,Y). | ||
?- p2(L,X,Y). | ||
?- p3(L,X,Y). | ||
?- p4(L,X,Y). | ||
?- p5(L,X,Y). | ||
*/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
:-use_module(library(random)). % for randseq/3 to generate random lists | ||
|
||
setof_sort(In,Out):- | ||
setof(X,member(X,In),Out). | ||
|
||
/** <examples> | ||
?- randseq(20,100,In), setof_sort(In,Out). | ||
*/ |