Presentation on theme: "Logic Programming Chapter 15 Part 2. Prolog Lists The list is Prolog’s basic data structure Lists are a series of Prolog terms, separated by commas Each."— Presentation transcript:
Prolog Lists The list is Prolog’s basic data structure Lists are a series of Prolog terms, separated by commas Each list element can be a(n) –atom –variable –sublist –etc.
Examples of Lists The empty list: [ ] List with embedded list: [boys, [like, girls]] List with variables: [x, V1, y, V2, [A, B]] –V1, V2, A, and B are variables that may be instantiated with data at a later time. Multi-type lists: [boy, [1, 2, 3], ran] [A, _, Z] –The _ means “don’t care” – sometimes referred to as an unbound variable.
Working with Lists [Head|Tail] notation simplifies processing: –The vertical bar is an operator that separates a list into its Head (the first list element), and its Tail (a list that represents everything else). –Head can be any Prolog term (list, variable, atom, predicate, etc.) –If L = [a, b, c] then Head = a and Tail = [b,c] –Tail is always another list. What is the head of [a]? The tail?
Working with Lists What is the head of [ ]? Of [a]? 4 ?- [ ] = [Head|Tail]. false. 5 ?- [a] = [Head|Tail]. Head = a, Tail = .
The append Function append is a built-in Prolog function that concatenates two lists. append(A, B, L) concatenates the lists A and B and returns them as L. append([my, cat], [is, fat], L). yields L = [my, cat, is, fat]
The Append Function append(L1, L2, L3): append([ ], X, X). %base case append([Head|Tail], Y,[Head|Tail2]) :- append(Tail, Y, Tail2). This definition says: –The empty list concatenated with any list (X) returns an unchanged list (X again). –Append [H|T] to Y and get a new list that has the same 1 st element but a new tail: the list you would get if you appended Tail to Y –Each recursive call reduces the size of the first list by one element until it becomes the empty list and then the calls terminate and begin the series of returns.
?- Append([english, russian], [spanish], L). H=english, T=[russian], Y=[spanish], L=[english,Z] 1 and Z = [russian, spanish] Append([russian],[spanish], [Z]). H = russian, T=[ ], Y=[spanish], Z=[russian|Z 1 ] 2 Append([ ], [spanish], [Z 1 ]). So Z1= [spanish] X=[spanish], Z 1 =[spanish] 3 Append([ ], [spanish], [spanish]). append([ ], X, X). append([Head|Tail], Y,[Head|Tail2]) :- append(Tail, Y, Tail2)
Using append prefix(X, Z) :- append(X, Y, Z). (finds all prefixes of a list Z) suffix(Y, Z) :- append(X, Y, Z). (finds all suffixes of Z)
Recursion/ member The function returns ‘yes’ or ‘true’ if X is a member of a given list. member(X, [X | _ ]). member(X, [ _ | Y]) :- member(X, Y).
Member(X,Y) The test for membership succeeds if either: –X is the head of the list [X |_] –X is not the head of the list [_| Y], but X is a member of the list Y (the tail). Notes: pattern matching governs tests for equality. Don ’ t care entries (_) mark parts of a list that aren ’ t important to the rule.
Naming Lists Defining a set of lists: a([single]). a([a, b, c]). a([cat, dog, sheep]). When a query such as a(L), prefix(X, L). Is posed, all three lists can be processed. Other lists, such as b([red, yellow, green]), would be ignored.
a([single]). a([a, b, c]). a([cat, dog, sheep]). prefix(X, Z) :- append(X, _, Z). suffix(Y, Z) :- append(_, Y, Z). % To make queries about lists in the database: % suffix(X, [the, cat, is, fat]). % a(L), prefix(X, L). A Sample List Program
?- a(L), prefix(X, L). L = [single] X =  ; L = [single] X = [single] ; L = [a, b, c] X =  ; L = [a, b, c] X = [a] ; L = [a, b, c] X = [a, b] ; L = [a, b, c] X = [a, b, c] ; L = [cat, dog, sheep] X =  Sample Output Based on the program on the previous slide.
35 ?- a(L), append([cat], L, M). L = [single] M = [cat, single] ; L = [a, b, c] M = [cat, a, b, c] ; L = [cat, dog, sheep] M = [cat, cat, dog, sheep] ; Sample Output
Logic Programming 15.2.2: Practical Aspects 15.3: Example Applications
Recursive Factorial Program To see the dynamics of a function call, use the trace function. For example,given the following function: factorial(0, 1). factorial(N, Result):- N > 0, M is N-1, factorial(M, SubRes), Result is N * SubRes. % ‘is’ ~ temporary assignment
Using the Trace Function At the prompt, type “trace.” Then type the query. Prolog will show the rules it uses and the instantiation of unbound constants. Useful for understanding what is happening in a search process, or in a recursive function. NOTE – the following is based on previous versions of Prolog. Current version is a little different.
Tracing Output ?- trace(factorial/2). ?- factorial(4, X). Call: ( 7) factorial(4, _G173) Call: ( 8) factorial(3, _L131) Call: ( 9) factorial(2, _L144) Call: ( 10) factorial(1, _L157) Call: ( 11) factorial(0, _L170) Exit: ( 11) factorial(0, 1) Exit: ( 10) factorial(1, 1) Exit: ( 9) factorial(2, 2) Exit: ( 8) factorial(3, 6) Exit: ( 7) factorial(4, 24) X = 24 These are temporary variables These are levels in the search tree factorial(0, 1). factorial(N, Result):- N > 0, M is N-1, factorial(M, SubRes), Result is N * SubRes.
%remove() removes an element from a list. %To Call: remove(a, List, Remainder). % or remove(X, List, Remainder). % First parameter is the removed item, % 2nd parameter is the original list, % third is the final list remove(X, [X|R], R). remove(X, [H|R], [H|S]):- remove(X, R, S).
Simple Arithmetic Integer “variables” and integer operations are possible, but imperative language “assignment statements” don’t exist.
Sample Program speed(fred, 60). speed(carol, 75). time(fred, 20). time(carol, 21). distance(Person, Dist) :- speed(Person, Speed), time(Person, Time), Dist is Speed * Time. area_square(S, A) :- A is S * S.
Sample Program There are limits imposed by the need to have variables instantiated area_square(S, A) :- A is S * S. 1 ?- area_square(3.5, A). A = 12.25. 2 ?- area_square(S, 16). ERROR: is/2: Arguments are not sufficiently instantiated 3 ?- S*S isn’t computable since S has not been instantiated.
Prolog Operators is can be used to cause a variable to be temporarily instantiated with a value. Compare to assignment statements in declarative languages, where variables are permanently assigned values. The not operator is used to indicate goal failure. For example not(P) is true when P is false.
Arithmetic Originally, Prolog used prefix notation +(7, X) Modern versions have infix notation X is Y*C + 3. Qualification: Y and C must be instantiated, as in the Speed program, but X cannot be (It’s not a traditional assignment statement). –X = X + Y is illegal. –X is X + Y is illegal. “ Arguments are not sufficiently instantiated ”
More About Arithmetic Example of simple arithmetic, using something similar to Python’s calculator mode (not as part of a program). –?- X is 3 + 7. –X = 10 Arithmetic operators: +, -, *, /, ^ ( exponentiation) Relational operators:, =, = =, \=
Search Tree for the Query d(x, 2*x+1, Ans) Figure 15.11 d(u*v) = udv + vdu = 2*dx + x * d2) d(u + v) = du + dv
Executing a Prolog Program Create a file containing facts and rules; e.g., familytree.pl or download the sample program on K drive, change the extension from. txt to.pl, and experiment with it. Follow instructions in handout, which is posted in K:\LABS\424.
SWIplEdit “compile” error If SWI-Prolog finds an error in the.pl file it will give a message such as ERROR: c:/temp/prologprogs/remove.pl: 18:0: Syntax error: Illegal start of term (18 is the line number)
Runtime Error Message The function samelength was called with one parameter when it needed 2: 21 ?- samelength(X). ERROR:Undefined procedure: samelength/1 ERROR:However, there are definitions for: samelength/2
Runtime Errors Here, the error is an error of omission: 22 ?- samelength([a, b, c,],[a, b]) | Queries must end with a period. If you hit enter without typing a period SWIpl just thinks you aren’t through.
Using SWI Prolog If there is an error that you can’t figure out (for example you don’t get any answers, you don’t get a prompt, typing a semicolon doesn’t help) try “interrupt” under the Run button. If changes are made to the program, don’t forget to save the file and “consult” again.