FATIH UNIVERSITY Department of Computer Engineering More Built-in Predicates Notes for Ch.7 of Bratko For CENG421&553 Fall03
FATIH UNIVERSITY Department of Computer Engineering Testing the Type of Terms var( X) succeeds if X is an uninstantiated variable nonvar( X) atom( X) succeeds if X currently stands for an atom integer( X) float( X) number( X) number (integer or float) atomic( X) number or atom compound( X) structure See examples of the book data objects (terms) simple objects Compound objects (structures) constantsvariables atomsnumbers
FATIH UNIVERSITY Department of Computer Engineering Testing the type of terms Prolog has many built-in features, depending on the implementation. Some of the mostly used: Testing of the type. Useful to avoid error messages for not or wrongly instantiated variables:..., integer(X), integer(Y), Z is X + Y,...
FATIH UNIVERSITY Department of Computer Engineering Example /* count1(Atom,List,Number) if Number is the number of terms in List that unify with Atom */ count1( _,[],0). count1( A,[ A|T],N) :- !, count1( A,T,N1), N is N1+1. count1( A,[ _|L],N) :- count1( A,L,N). /* count2(Atom,List,Number) if Number is the number of atoms in List that are identical to Atom */ count2( _,[],0). count2(A,[ B|T],N) :- atom( B), A = B, !, % B is atom A? count2( A,T,N1), N is N1+1 ; count2( A,T,N).
FATIH UNIVERSITY Department of Computer Engineering Example: Counting Atoms ch7_1.pl We want to count actual occurrences of an atom, not terms that match an atom count1(Atom,List,Number) counts terms that match Atom 3 ?- count1(a,[a,b,X,Y],Na). X = a Y = a Na = 3 count2(Atom,List,Number) counts actual occurrences of Atom 5 ?- count2(a,[a,b,X,Y],Na). X = _G304 Y = _G307 Na = 1
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle SEND + MORE = MONEY Assign distinct decimal digits to distinct letters so that the sum is valid Albert Newell and Herbert Simon studied in depth puzzle like these in their study of human problem solving (Human Problem Solving, Prentice Hall, 1972) People use a mixture of trial and error and constraint processing: e.g., M must be 1, S must be 8 or 9, O must be 0, etc.
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle II sum( N1,N2,N) if N is N1+N2 Numbers are represented by lists of digits: the query is: ?-sum( [S,E,N,D],[M,O,R,E],[M,O,N,E,Y]). We need to define the sum relation; we generalize to a relation sum1, with Carry digit from the right (before summing, C1) Carry digit to the left (after summing, C) Set of digits available before summing (Digits1) Set of digits left after summing (Digits) sum1( N1,N2,N,C1,C,Digits1,Digits)
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle III Example: 1 ?- sum1([H,E],[6,E],[U,S],1,1,[1,3,4,7,8,9],Digits). H = 8 E = 1 U = 4 S = 3 Digits = [7, 9] There are several (four, in fact) other answers. 1<- <
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle IV We start off with all digits available, we do not want any carries at the end, and we do not care about which digits are left unused: sum(N1,N2,N) :- sum1(N1,N2,N,0,0,[0,1,2,3,4,5,6,7,8,9],_). We assume all three lists are of the same lengths, padding with zeros if necessary: ?- sum([0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]).
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle V sum1( [], [], [], C, C, Digits, Digits). sum1( [D1|N1], [D2|N2], [D|N], C1, C, Digs1, Digs) :- sum1( N1, N2, N, C1, C2, Digs1, Digs2), digitsum( D1, D2, C2, D, C, Digs2, Digs). digitsum( D1, D2, C1, D, C, Digs1, Digs) :- del_var( D1, Digs1, Digs2), % Select an available digit for D1 del_var( D2, Digs2, Digs3), % Select an available digit for D2 del_var( D, Digs3, Digs), % Select an available digit for D S is D1 + D2 + C1, D is S mod 10, % Reminder C is S // 10. % Integer division
FATIH UNIVERSITY Department of Computer Engineering Cryptarithmetic Puzzle VI Nonderministic deletion of variables del_var( A, L, L) :- nonvar(A), !. % A already instantiated del_var( A, [A|L], L). del_var( A, [B|L], [B|L1]) :- del_var(A, L, L1).
FATIH UNIVERSITY Department of Computer Engineering Constructing and Decomposing Terms Clauses are terms too! As in LISP, data and programs have a common representation: S-expressions (atoms or lists) in LISP, terms in Prolog 2 ?- consult(user). |: a. |: a :- b. |:quit. 3 ?- clause(a,X). X = true ; X = b ; No
FATIH UNIVERSITY Department of Computer Engineering Clauses are Terms The principal functor of a clause is its neck (:- ) 4 ?- consult(user). |: :-(b,c). |: quit. % user compiled 0.00 sec, 32 bytes Yes 5 ?- listing(b). b :- c. Yes
FATIH UNIVERSITY Department of Computer Engineering Constructing and decomposing terms Built-in predicates for constructing and decomposing terms: functor, arg, and ‘ =.. ’. First ‘ =.. ’, an infix operator, and read as ‘univ’: Term =.. L is true if L is a list containing the principal functor of Term, followed by its arguments. Examples: ?- f(a,b) =.. L. L = [f, a, b] ?- T =.. [rectangle,3,5]. T = rectangle(3, 5) ?- Z =.. [p, X, f(X,Y)]. Z = p(H2, f(H2, H4)) X = H2 Y = H4
FATIH UNIVERSITY Department of Computer Engineering Constructing and decomposing terms Necessity of ‘ =.. ’, suppose we want to manipulate geometric figures. Let us represent them as square(Side) triangle(Side1, Side2, Side3) circle(R) Operation to enlarge figures: enlarge(Fig1, Factor, Fig2) with Fig1 and Fig2 having the same functor and the arguments of Fig2 are those of Fig1 multiplied by Factor. Suppose that all variables are already instantiated. Then we can define enlarge as:
FATIH UNIVERSITY Department of Computer Engineering Constructing and decomposing terms enlarge(square(S), F, square(S1)) :- S1 is F * S. enlarge(circle(R), F, circle(R1)) :- R1 is F * R. enlarge(rectangle(A,B), F, rectangle(A1,B1)) :- A1 is F * A, B1 is F * B. This works but is awkward if we have many figure types. And in fact all definitions are similar! Other attempt: enlarge(Type(Par), F, Type(Par1)) :- Par1 is F * Par. This is not allowed in Prolog, since the functor should be an atom. Moreover, we still have to define enlarge for figure types with more arguments.
FATIH UNIVERSITY Department of Computer Engineering Constructing and decomposing terms Solution: use ‘ =.. ’ enlarge(Fig, F, Fig1) :- Fig =.. [Type | Pars], multiplylist( Pars, F, Pars1), Fig1 =.. [Type | Pars1]. multiplylist([], _, []). multiplylist([X|L], F, [X1|L1]) :- X1 is F * X, multiplylist(L, F, L1). Testing: ?- enlarge(ellipse(5,7), 2.5, X). X = ellipse(12.5, 17.5)
FATIH UNIVERSITY Department of Computer Engineering Constructing and decomposing terms To extract the functor and its arity of a structure, we can use ‘ =.. ’, but better is functor(Term, F, N) and to extract the Nth argument of a structure, use arg(N, Term, A) Examples to illustrate: ?- functor(triangle(1,2,3), Fun, Arity). Fun = triangle Arity = 3 ?- Date = date(december, 6, 2005), arg(1, Date, Month), arg(2, Date, Day), arg(3, Date, Year). Date = date(december, 6, 2005) Month = december Day = 6 Year = 2005
FATIH UNIVERSITY Department of Computer Engineering univ Term =.. L, if –L is a list containing the principal functor of Term, followed by Term’s argument –Examples on page –try_call :- % Here, Goal is a term Goal =.. [ member| [a, [a,b,c]]], Goal. % Here, Goal is a predicate –Example: substitute( Subterm,Term,Subterm1,Term1) ?-substitute( sin(x),2*sin(x)*f(sin(x)),t,F).
FATIH UNIVERSITY Department of Computer Engineering % Figure 7.3 A procedure for substituting a subterm of a term by another subterm. % substitute( Subterm, Term, Subterm1, Term1): % if all occurrences of Subterm in Term are substituted % with Subterm1 then we get Term1. % Case 1: Substitute whole term substitute( Term, Term, Term1, Term1) :- !. % Case 2: Nothing to substitute substitute( _, Term, _, Term) :- atomic(Term), !. % Case 3: Do substitution on arguments substitute( Sub, Term, Sub1, Term1) :- Term =.. [F|Args], % Get arguments substlist( Sub, Args, Sub1, Args1), % Perform substitution on them Term1 =.. [F|Args1]. substlist( _, [], _, []). substlist( Sub, [Term|Terms], Sub1, [Term1|Terms1]) :- substitute( Sub, Term, Sub1, Term1), substlist( Sub, Terms, Sub1, Terms1).
FATIH UNIVERSITY Department of Computer Engineering univ Example: –fig7_3.pl –substitute( Subterm,Term,Subterm1,Term1) –?-substitute( sin(x),2*sin(x)*f(sin(x)),t,F). An occurrence of Subterm in Term is something in Term that matches Subterm If Subterm = Term, then Term1 = Subterm1 Else if Term is atomic, then Term1 = Term Else carry out the substitution on the arguments of Term
FATIH UNIVERSITY Department of Computer Engineering Dynamic Goals Goals may be created at run time, as in: Obtain( Functor), Compute( Arglist), Goal =.. [ Functor|Arglist], Goal. % works in AMZI; with some Prologs, call( Goal) try_call :- Goal =.. [ member| [a, [a,b,c]]], % Goal is a term Goal. % Goal is a predicate This is also an example of Prolog’s ambiguous syntax: the first Goal is a term (a variable), while the second Goal is a predicate Examples on page
FATIH UNIVERSITY Department of Computer Engineering Equality and Comparison X = Y matching (unification) X is E matches arithmetic value E1 =:= E2 arithmetic E1 =\= E2 arithmetic inequality T1 == T2 literal equality of terms(same structure and all correponding components are the same) T1 \== T2 not identical T2 term comparison
FATIH UNIVERSITY Department of Computer Engineering Various kinds of equality and comparison Prolog has various interpretations of equality and hence different predicates to test equality. Already seen: X = Y which is true if X and Y match. Further X is E which is true if X matches the value of expression E. Also: E1 =:= E2 which is true if the values of the expressions E1 and E2 are equal. In contrast we use E1 =\= E2 when the values of the expressions E1 and E2 are not equal.
FATIH UNIVERSITY Department of Computer Engineering Another kind of equality is literal equality, written as T1 == T2 which is true if terms T1 and T2 are identical, i.e., exactly the same structure and all components are equal. The complementary relation: T1 \== T2 when the terms T1 and T2 are not identical. Some examples: ?- f(a,b) == f(a,b). yes ?- f(a,b) == f(a,X). no ?- f(a,X) == f(a,Y). no Various kinds of equality and comparison
FATIH UNIVERSITY Department of Computer Engineering Various kinds of equality and comparison Example: counting the number of literal occurrences of a term in a list: count(_, [], 0). count(Term, [Head | L], N) :- Term == Head, !, count(Term, L, N1), N is N1 + 1 ; count(Term, L, N).
FATIH UNIVERSITY Department of Computer Engineering Various kinds of equality and comparison Besides an arithmetic ordering relation (, >= ) Prolog also knows the alphabetical ordering, with I.e., ?- peter. yes The precedence for structures is determined first by their functor, and then by the components, from left to right: ?- f(3). yes ?- f(a, g(b), f(a, h(a), a). yes
FATIH UNIVERSITY Department of Computer Engineering Database manipulation A Prolog knowledge base is in fact a kind of database, with facts and rules. Besides consult/reconsult Prolog has several other predicates to manipulate it. Some of the most important ones: assert(C) adds clause C to the knowledge base. Depending on implementation, this will be at the front or at the back. For explicit control, use asserta (at the front) or assertz (at the back). To delete a clause, use retract(C) This deletes the first clause from the knowledge base matching C. To delete all clauses matching C at once, use retractall(C)
FATIH UNIVERSITY Department of Computer Engineering Database manipulation To show the contents of the knowledge base at the moment use listing. Alternatively, use listing(Pred) to show only the clauses for predicate Pred, irrespective of arity, or use listing(Pred/N) for a listing of the clauses for predicate Pred with arity N. Suppose we start a new Prolog session. The following user- Prolog conversation is illustrative: ?- listing. yes % the knowledge base is still empty ?- assert(getal(1)), listing. user:getal(1). % the first fact yes
FATIH UNIVERSITY Department of Computer Engineering Database manipulation ?- assert(getal(2)), assert(getal(3)), listing. user:getal(1). % new facts are added user:getal(2). % in Amzi! Prolog by default user:getal(3). % at the end Yes ?- asserta(getal(4)),assertz(getal(5)),listing. user:getal(4). % explicitly add a fact user:getal(1). % at the front user:getal(2). user:getal(3). user:getal(5). % or at the end yes
FATIH UNIVERSITY Department of Computer Engineering Database manipulation ?- retract(getal(2)), listing. user:getal(4). user:getal(1). % delete the clause getal (2) user:getal(3). user:getal(5). yes ?- retract(getal(_)), listing. user:getal(1). user:getal(3). % delete one clause for getal user:getal(5). % (the first one) yes ?- retractall(getal(_)), listing. yes % delete all clauses for getal
FATIH UNIVERSITY Department of Computer Engineering Database manipulation To add a rule, use the following syntax: ?- assert( (nice(X) :- not ugly(X)) ). Useful application of asserta : to store already computed answers. E.g., suppose we have a predicate solve(Problem, Solution) Then we can ask for a solution and store it, by ?- solve(problem1, Solution), asserta(solve(problem1, Solution)). The first time we call solve(problem1, Solution) it is stored at the front of the knowledge base (it is “memorized”). A second time this stored solution is used (and probably much quicker).
FATIH UNIVERSITY Department of Computer Engineering Database manipulation As an application: let us make and store a multiplication table for all pairs of numbers X and Y from 0 to 9. Using the fail goal we force backtracking, doing a next pair. maketable :- L = [0,1,2,3,4,5,6,7,8,9], member(X,L), member(Y,L), Z is X * Y, assert(product(X,Y,Z)), fail. The question: ?- maketable. will of course fail, but as a side effect produce the desired table.
FATIH UNIVERSITY Department of Computer Engineering Database manipulation E.g. ?- listing(product). user:product(0, 0, 0). user:product(0, 1, 0). user:product(0, 2, 0).... user:product(9, 9, 81). ?- product(M,N,8). M = 1 N = 8 ; M = 2 N = 4 ; M = 4 N = 2 ; M = 8 N = 1 ; no
FATIH UNIVERSITY Department of Computer Engineering Prolog Database Manipulation asserta/1 assertz/1 Same as assert/1 retract/1 Only dynamic predicates may be asserted, retracted, etc. dynamic +Functor/+Arity,... See..\amzi_6-2-14\docs\pro\prfrtop.htm See examples on page
FATIH UNIVERSITY Department of Computer Engineering Control Facilities once( P) –The predicate once/1 behaves like call/1 except it is only executed once. This is useful for isolating code that you don't intend to be backtracked into, and makes for more readable code than inserting lots of cuts (!). We already encountered: –! ; the cut, always succeeds –fail ; always fails –true ; always succeeds –not(P) or not P ; succeeds if P fails and vice versa (alternative syntax: \+ P) Two new goals: –call(P) ; succeeds if P succeeds –repeat ; always succeeds, but is non-deterministic. So every time it is reached by backtracking it generates a new execution branch. It is as defined by repeat. repeat :- repeat.
FATIH UNIVERSITY Department of Computer Engineering Control facilities Application of repeat : dosquares :- repeat, write('Input please: '), read(X), (X = stop, ! ; Y is X*X, write('The square of '), write(X), write(' is: '), write(Y), nl, fail ).
FATIH UNIVERSITY Department of Computer Engineering bagof, setof, and findall bagof( X,P,L) if L is the list of Xs such that P(X) holds setof( X,P,L) is like bagof, but without duplication and the list is ordered –Numbers ordered by < –Others alphabetically ordered –Functors,parameters... Compared respectively Read ^ as “there exists” in bagof and setof findall( X,P,L) is like bagof but collects all objects X regardless of (possibly) different solutions for variables in P that are not shared with X Code for findall is in fig7_4.pl renamed findall1, because findall is built-in
FATIH UNIVERSITY Department of Computer Engineering bagof, etc. Examples –age( peter,7). age( ann,5). age( pat,8). age( tom,5). ?- bagof( Child,age(Child,5),L). –L=[ann,tom] ?- bagof( Child,age(Child,Age),L). –Age=7 L=[peter] –Age=5 L=[ann,tom] –Age=8 L=[pat] ?- bagof( Child,Age^age(Child,Age),L). –L=[peter,ann,pat,tom] ?- bagof( Age,Child^age(Child,Age),L). –L = [7, 5, 8, 5] ?- setof( Age, Child^age(Child,Age),L). –L = [5, 7, 8] ?- setof( Age:Child,age(Child,Age),L). –L = [5:ann, 5:tom, 7:peter, 8:pat] ?-findall( Child,age( Child,Age),L). –L = [peter, ann, pat, tom]
FATIH UNIVERSITY Department of Computer Engineering bagof, setof and findall To generate a list of all solutions for a goal, use findall(X, P, L) This will produce a list L of all instantiations of X satisfying P. For instance likes(fred, juice). likes(tom, milk). likes(jane, juice). likes(jane, coke). ?- findall(X, likes(X,Y), L). L = [fred, tom, jane, jane] ?- findall(Y, likes(X,Y), L). L = [juice, milk, juice, coke]
FATIH UNIVERSITY Department of Computer Engineering bagof, setof and findall Bagof is similar, but instantiates “unqueried” variables: ?- bagof(X, likes(X, juice), L). L = [fred, jane] ?- bagof(X, likes(X,Y), L). Y = juice L = [fred, jane] ; Y = milk L = [tom] ; Y = coke L = [jane] ; no
FATIH UNIVERSITY Department of Computer Engineering bagof, setof and findall To state that we don’t care on the instantiation of an “unqueried” variable, use the infix operator ‘ ^ ’ between variable name and predicate: ?- bagof(X, Y^likes(X,Y), L). L = [fred, tom, jane, jane] The predicate setof is just like bagof, with two exceptions: 1.Duplicate terms, if any, will be removed 2.The output list is alphabetically ordered ?- setof(X, Y^likes(X,Y), L). L = [fred, jane, tom] ?- setof(Y, X^likes(X,Y), L). L = [juice, coke, milk]
FATIH UNIVERSITY Department of Computer Engineering % Figure 7.4 An implementation of the findall relation, findall1( X, Goal, Xlist) :- call( Goal), % Find a solution assertz( queue(X) ), % Assert it fail; % Try to find more solutions assertz( queue(bottom) ), % Mark end of solutions collect( Xlist). % Collect the solutions collect( L) :- retract( queue(X) ), !, % Retract next solution ( X == bottom, !, L = [] % End of solutions? ; L = [X | Rest], collect( Rest) ). % Otherwise collect the rest % age relation for examples age( peter,7). age( ann,5). age( pat,8). age( tom,5).