cs774 (Prasad) L5ArithStruc 1
Arithmetic ; Structures
http://www.knoesis.org/tkprasad/
Arithmetic?- X = 1 + 2.
• Succeeds with X bound to the term 1 + 2.
• To make the system evaluate the expression, we use “is” construct.
?- X is 1 + 2.• Succeeds with X bound to the term 3.
• If variables occur in the RHS expression, they must be bound to values (i.e., must be ground) before the expression can be evaluated.
?- Y = 1, X is Y + 2.
cs774 (Prasad) L5ArithStruc 2
(cont’d)?- Y is X+2, X=1.
• ERROR: Arguments are not sufficiently instantiated.
?- X = 1, Y = 2, Z is X * Y + 3.
• Succeeds with Z bound to the term 5.
• Re-ordering of (atomic) goals in the query can cause the query to fail.
• A different control strategy that delays evaluation of goals containing non-ground expressions may succeed in certain cases.
cs774 (Prasad) L5ArithStruc 3
cs774 (Prasad) L5ArithStruc 4
“Equalities” in Prolog• We have three different but related “equality”
operators:– X is Y evaluates Y and unifies the result with X:
3 is 1+2 succeeds, but 1+2 is 3 fails– X = Y unifies X and Y, with no evaluation: both 3 = 1+2 and 1+2 = 3 fail
– X =:= Y evaluates both and compares: both 3 =:= 1+2 and 1+2 =:= 3 succeed
• Any evaluated term must be fully instantiated.
Equalities and their negations
• Matching
T1 = T2 T1 \= T2
• Literal Equality
T1 == T2 T1 \== T2
5 \== 3+2
• Arithmetic Equality
5 =:= 3+2 5 =\= 2+2
• Arithmetic Relations
5 =< 8 5 >= 2
Sum of Squares
cs774 (Prasad) L5ArithStruc 6
b
ai
i2
sum(A,B,0) :- A > B.sum(A,A,Res) :- Res is A*A.sum(A,B,Res) :-
A < B, T is A + 1,sum(T, B, R),Res is A*A + R.
Factorial Function : Recursive definition
cs774 (Prasad) L5ArithStruc 7
!or 1
n
ini
rfact(0,1).rfact(N,R) :-
N > 0, M is N-1,rfact(M,S),R is N * S.
Alternative: Tail recursive definition
cs774 (Prasad) L5ArithStruc 8
!or 1
n
ini
fact(N,R) :- trfact(N,1,R).trfact(0,R,R). trfact(N,T,R) :-
N > 0, M is N-1,S is N * T,trfact(M,S,R).
Matching vs Arithmetic Comparison
?- 1 + 2 =:= 2 + 1.
YES
?- 1 + 2 = 2 + 1.
NO
?- A + 1 = 2 + B.
A = 2
B = 1
•
cs774 (Prasad) L5ArithStruc 9
Permutation Sort
cs774 (Prasad) L5ArithStruc 10
psort(L,R) :- permutation(L,R),sorted(R).
sorted([]). sorted([_]). sorted([X,Y|R]) :-
X =< Y, sorted([Y|R]).
Obviously correctbut prohibitively inefficient
Selection Sort
cs774 (Prasad) L5ArithStruc 11
ssort([],[]). ssort(L,[Min|Srest]) :-
least(L,Min,Rest),ssort(Rest,Srest).
least([Min],Min,[]). least([H|T],Min,Rest) :-
least(T,M,L), (M > H -> (Min, Rest) = (H,T);
(Min, Rest) = (M,[H|L])).
Quadratic
Structures via Travel Agent Example
cs774 (Prasad) L5ArithStruc 12
Travel Planning• Querying a database of flight information
timeTable(Place1, Place2, ListOfFlights).
• Form of flight itemdepTime / arrTime / fltNo / days
• One day travels
?- route(Place1, Place2, Day, Route).
cs774 (Prasad) L5ArithStruc 13
operator
Examples of Fact and Query
timetable(edinburgh, london,
[ 9:40 / 10:50 / ba4733 / alldays,
13:40 / 14:50 / ba4773 / alldays,
19:40 / 20:50 / ba4833 / [mo,we,fr]]).
• Note that ‘:’ should bind stronger than ‘/’.
?- route(london, paris, tu, Route)• Form of items in the route
from / to / fltNo / depTime
cs774 (Prasad) L5ArithStruc 14
Prolog Code% A Flight Route Planner
:- op(50, xfy, :).
% route(Place1, Place2, Day, Route).
% Route is a sequence of flights on Day, starting at Place1 and ending at Place2
route(P1, P2, Day, [P1 / P2 / Fnum / Deptime]) :-
flight(P1, P2, Day, Fnum, Deptime, _).
% direct flight
route(P1, P2, Day, [(P1 / P3 / Fnum1 / Dep1) | RestRoute]) :-
flight(P1, P3, Day, Fnum1, Dep1, Arr1),
route(P3, P2, Day, RestRoute),
deptime(RestRoute, Dep2),
transfer(Arr1, Dep2).
% Indirect flight - ensure enough transfer time
% optimize by propagating that constraint
cs774 (Prasad) L5ArithStruc 15
% decoding timetable
flight(Place1, Place2, Day, Fnum, Deptime, Arrtime) :-
timetable(Place1, Place2, Flightlist),
member(Deptime / Arrtime / Fnum / Daylist, Flightlist),
flyday(Day, Daylist).
flyday(Day, Daylist) :- member(Day, Daylist).
flyday(Day, alldays) :- member(Day, [mo,tu,we,th,fr,sa,su]).
deptime([( _ / _ / _ / Dep) | _], Dep).
transfer(Hours1:Mins1, Hours2:Mins2) :-
60 * (Hours2 - Hours1) + Mins2 - Mins1 >= 40.
% must have 40 min gap
cs774 (Prasad) L5ArithStruc 16
% A Flight Database
timetable(edinburgh, london,
[ 9:40 / 10:50 / ba4733 / alldays,
13:40 / 14:50 / ba4773 / alldays,
19:40 / 20:50 / ba4833 / [mo,tu,we,th,fr,su]]).
timetable(london, edinburgh,
[ 9:40 / 10:50 / ba4732 / alldays,
11:40 / 12:50 / ba4752 / alldays,
18:40 / 19:50 / ba4822 / [mo,tu,we,th,fr]]).
timetable(london, ljubljana,
[ 13:20 / 16:20 / jp212 / [mo,tu,we,fr,su],
16:30 / 19:30 / ba473 / [mo,we,th,sa]]).
cs774 (Prasad) L5ArithStruc 17
timetable(london, zurich,
[ 9:10 / 11:45 / ba614 / alldays,
14:45 / 17:20 / sr805 / alldays]).
timetable(london, milan,
[ 8:30 / 11:20 / ba510 / alldays,
11:00 / 13:50 / az459 / alldays]).
timetable(ljubljana, zurich,
[ 11:30 / 12:40 / jp322 / [tu,th]]).
timetable(ljubljana, london,
[ 11:10 / 12:20 / jp211 / [mo,tu,we,fr,su],
20:30 / 21:30 / ba472 / [mo,we,th,sa]]).
cs774 (Prasad) L5ArithStruc 18
timetable(milan, london,
[ 9:10 / 10:00 / az458 / alldays,
12:20 / 13:10 / ba511 / alldays]).
timetable(milan, zurich,
[ 9:25 / 10:15 / sr621 / alldays,
12:45 / 13:35 / sr623 / alldays]).
timetable(zurich, ljubljana,
[ 13:30 / 14:40 / jp323 / [tu,th]]).
timetable(zurich, london,
[ 9:00 / 9:40 / ba613 / [mo,tu,we,th,fr,sa],
16:10 / 16:55 / sr806 / [mo,tu,we,th,fr,su]]).
timetable(zurich, milan,
[ 7:55 / 8:45 / sr620 / alldays]).
cs774 (Prasad) L5ArithStruc 19
Queries• What days of the week is there is a direct
evening flight from Ljubljana to London?
?- flight(ljubljana, london, Day, _, DepHour:_,_), DepHour >= 18.
• How can I get from Ljubljana to London on Thursday?
?- route(ljubljana, london, th, R).
• Queries can result in infinite loops or stack overflow on Prolog.
cs774 (Prasad) L5ArithStruc 20
SWI-Prolog vs XSBXSB: tabletable route/4.
• How can I get from Ljubljana to Edinburgh on Thursday?
?- route(ljubljana, edinburgh, th, R).
SWI-Prolog: Out of local stack
XSB: [ ljubljana / zurich / jp322 / 11 : 30,
zurich / london / sr806 / 16 : 10,
london / edinburgh / ba4822 / 18 : 40];
cs774 (Prasad) L5ArithStruc 21
Chess : Eight Queens Problems
cs774 (Prasad) L5ArithStruc 22
Encoding of a solution : list(Column/Row)[1/1, 2/5, 3/8, 4/6, 5/3, 6/7, 7/2, 8/4]
solution([]).
solution([C/R | Others]) :-
solution(Others),
member(R,[1,2,3,4,5,6,7,8]),
noAttack(C/R, Others).
noAttack(_,[]).
noAttack(C/R, [C1/R1 | Others]) :-
R =\= R1, R1 – R =\= C1 – C,
R1 – R =\= C – C1,
noAttack(C/R, Others ).
template([1/_,2/_,3/_,4/_,5/_,6/_,7/_,8/_]).
?- template(S), solution(S).
cs774 (Prasad) L5ArithStruc 23
Eight Queens Solutions (92 in all)S = [1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/5, 8/1] ;
S = [1/5, 2/2, 3/4, 4/7, 5/3, 6/8, 7/6, 8/1] ;
S = [1/3, 2/5, 3/2, 4/8, 5/6, 6/4, 7/7, 8/1] ;
S = [1/3, 2/6, 3/4, 4/2, 5/8, 6/5, 7/7, 8/1] ;
…
S = [1/5, 2/7, 3/2, 4/6, 5/3, 6/1, 7/8, 8/4] ;
S = [1/3, 2/6, 3/2, 4/7, 5/5, 6/1, 7/8, 8/4] ;
S = [1/6, 2/2, 3/7, 4/1, 5/3, 6/5, 7/8, 8/4] ;
S = [1/3, 2/7, 3/2, 4/8, 5/6, 6/4, 7/1, 8/5] ;
S = [1/6, 2/3, 3/7, 4/2, 5/4, 6/8, 7/1, 8/5] ;
S = [1/4, 2/2, 3/7, 4/3, 5/6, 6/8, 7/1, 8/5] ;
… S = [1/8, 2/2, 3/4, 4/1, 5/7, 6/5, 7/3, 8/6] ;
S = [1/7, 2/2, 3/4, 4/1, 5/8, 6/5, 7/3, 8/6] .
cs774 (Prasad) L5ArithStruc 24
Top Related