Skip to content

Commit

Permalink
Lab files
Browse files Browse the repository at this point in the history
  • Loading branch information
So-Cool committed Feb 9, 2017
1 parent a26ad9a commit 18f3181
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Mac OS files
*.DS_Store
3 changes: 3 additions & 0 deletions labs/README.md
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).
15 changes: 15 additions & 0 deletions labs/biglist.pl
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).

/** &lt;examples&gt;
?- biglist(1,25,L).
*/
18 changes: 18 additions & 0 deletions labs/fib.pl
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.

/** &lt;examples&gt;
?- fib(5,F).
?- fib(10,F).
?- fib(20,F).
?- fib(25,F).
?- fib(30,F).
*/
19 changes: 19 additions & 0 deletions labs/fibn.pl
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).

/** &lt;examples&gt;
?- member(N,[10,20,50,100,200]), fibn(N,F).
?- maplist(fibn, [10,20,50,100,200], L).
*/
18 changes: 18 additions & 0 deletions labs/fibt.pl
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).

/** &lt;examples&gt;
?- fibt(5,E), F is E.
?- fibt(10,E), F is E.
*/
34 changes: 34 additions & 0 deletions labs/nqueens.pl
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).

/** &lt;examples&gt;
?- nqueens(8,Columns).
*/
36 changes: 36 additions & 0 deletions labs/powerset.pl
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).

/** &lt;examples&gt;
?- 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).
*/
25 changes: 25 additions & 0 deletions labs/prove.pl
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).

/** &lt;examples&gt;
?- prove(rectangle).
?- prove(square).
?- prove(not(triangle)).
?- prove(not((rectangle,triangle))).
*/
41 changes: 41 additions & 0 deletions labs/prove_p.pl
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).

/** &lt;examples&gt;
?- prove_p(rectangle).
?- prove_p(square).
*/
32 changes: 32 additions & 0 deletions labs/prove_r.pl
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).

/** &lt;examples&gt;
?- prove_r(rectangle).
?- prove_r(square).
?- prove_r(not(triangle)).
?- prove_r(not((rectangle,triangle))).
*/
32 changes: 32 additions & 0 deletions labs/psort.pl
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]).

/** &lt;examples&gt;
?- randseq(5,100,In), psort(In,Out).
*/
29 changes: 29 additions & 0 deletions labs/secondorder.pl
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).

/** &lt;examples&gt;
?- p1(L,X,Y).
?- p2(L,X,Y).
?- p3(L,X,Y).
?- p4(L,X,Y).
?- p5(L,X,Y).
*/
10 changes: 10 additions & 0 deletions labs/setof_sort.pl
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).

/** &lt;examples&gt;
?- randseq(20,100,In), setof_sort(In,Out).
*/

0 comments on commit 18f3181

Please sign in to comment.