240 likes | 335 Views
Arithmetic ; Structures. t.k.prasad@wright.edu 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 .
E N D
Arithmetic ; Structures t.k.prasad@wright.edu http://www.knoesis.org/tkprasad/ L5ArithStruc
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. • Succeedswith 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. L5ArithStruc
(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. L5ArithStruc
“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. L5ArithStruc
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 L5ArithStruc
Sum of Squares 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. L5ArithStruc
Factorial Function : Recursive definition rfact(0,1). rfact(N,R) :- N > 0, M is N-1, rfact(M,S), R is N * S. L5ArithStruc
Alternative: Tail recursive definition 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). L5ArithStruc
Matching vs Arithmetic Comparison ?- 1 + 2 =:= 2 + 1. YES ?- 1 + 2 = 2 + 1. NO ?- A + 1 = 2 + B. A = 2 B = 1 L5ArithStruc
Permutation Sort psort(L,R) :- permutation(L,R), sorted(R). sorted([]). sorted([_]). sorted([X,Y|R]) :- X =< Y, sorted([Y|R]). Obviously correct but prohibitively inefficient L5ArithStruc
Selection Sort 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 L5ArithStruc
Structures via Travel Agent Example L5ArithStruc
Travel Planning • Querying a database of flight information timeTable(Place1, Place2, ListOfFlights). • Form of flight item depTime / arrTime / fltNo / days • One day travels ?- route(Place1, Place2, Day, Route). operator L5ArithStruc
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 L5ArithStruc
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 L5ArithStruc
% 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 L5ArithStruc
% 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]]). L5ArithStruc
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]]). L5ArithStruc
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]). L5ArithStruc
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. L5ArithStruc
SWI-Prolog vs XSB XSB:tableroute/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]; L5ArithStruc
Chess : Eight Queens Problems Encoding of a solution : list(Column/Row) [1/1, 2/5, 3/8, 4/6, 5/3, 6/7, 7/2, 8/4] L5ArithStruc
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). L5ArithStruc
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] . L5ArithStruc