25
8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative predicates : – call. asserta, assertz. – retract.

8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

Embed Size (px)

Citation preview

Page 1: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.18.1

8. Higher Order Predicates8. Higher Order Predicates

• Higher order predicates in PROLOG.

• Higher order declarative predicates :

– findall

– bagof

– setof

– =..

• Higher order non-declarative predicates :

– call.

– asserta, assertz.

– retract.

Page 2: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.28.2

Higher Order Predicates in PROLOGHigher Order Predicates in PROLOG

• PROLOG implements a subset of classical logic.

– Horn Clause Predicate Calculus.

• Can only write facts and rules about terms.

– Cannot have facts and rules about predicates.

• PROLOG also provides a set of predicates which operate on other predicates : higher order predicates.

• Some are declarative :

– findall, bagof, setof, =...

• Some are not :

– call, asserta, assertz, retract.

Page 3: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.38.3

Back To The RomansBack To The Romans

• Suppose we have the following database :

consul(metellus, 80). consul(sulla, 80).consul(cicero, 63). consul(antonius, 63).consul(caesar, 59). consul(bibulus, 59).consul(pompeius, 55). consul(crassus, 55).consul(ahenobarabus,54). consul(pulcher, 54).consul(pompeius, 52). consul(metellus, 52).consul(caesar, 48). consul(servilius,48).consul(caesar, 46). consul(lepidus, 46).consul(caesar, 45).consul(caesar, 44). consul(antonius, 44).consul(pansa, 43). consul(octavius, 43).

• Some of the Consuls of the late Roman republic.

– Supposed to be two each year.

– Julius Caesar was sole Consul in 45BC. Julius Caesar was an unusual man.

Page 4: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.48.4

Finding ConsulsFinding Consuls

• Easy to write queries about Consuls :

| ?- consul(C, _).C = metellus ;C = sulla ;C = ciceroyes| ?- consul(C, 59).C = caesar ;C = bibulus ;no| ?-

• By using ; to force backtracking we can find all the Consuls in the database.

• A bit tedious. More convenient to have PROLOG give us all the answers at once in a list structure.

Page 5: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.58.5

Using findallUsing findall

• The higher order predicate findall allows us to get all the answers at once.

| ?- findall(C, consul(C, _), L).L = [metellus, ..., octavius]| ?- findall(C, consul(C, 59), L).L = [caesar, bibulus]yes| ?-

• Instantiate L to be the list of all values of C for which the query (the second parameter of findall) is true. If there are no such values then instantiate L to be the empty list.

Page 6: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.68.6

findall More Formallyfindall More Formally

• In general

findall(Term[V], Query[V], L).

means instantiate L to be the list of values of Term[V] for which the query Query[V] is true. If there are no such values then L is instantiated to [].

– Term[V] is an arbitrary term containing the logical variable V.

– Query[V] is an arbitrary query containing the logical variable V.

| ?- findall([C,was,in,59,bc],consul(C,59),L).L = [[caesar,was,in,59,bc], [bibulus,was,in,59,bc]]yes| ?-

Page 7: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.78.7

findall More Formally IIfindall More Formally II

• Term[V] is the selector term.

• Query[V] is the generator query.

• L is the result list.

• The selector term is often just a single logical variable but it can be any term.

– The variable in the selector does not have to appear in the generator.

– Not much point doing that though. The results are (usually) not useful.

– Using GNU PROLOG :

| ?- findall(X,consul(C,_),L).L = [_,_, ... ,_]| ?-

Page 8: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.88.8

bagof and setofbagof and setof

• findall is actually a generalisation of two other higher-order predicates : bagof and setof.

| ?- bagof(W, consul(caesar, W), L).W = [59,48,46,45,44]| ?- setof(W, consul(caesar, W), L).W = [44,45,46,48,59]| ?- bagof(C, consul(C, _), L).L = [pansa,octavius] ? ;L = [caesar,antonius] ? yes| ?- setof(C, consul(C, _), L).L = [octavius,pansa] ? ;L = [antonius,caesar] ? yes| ?-

• _ does not work properly with bagof or setof.

Page 9: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.98.9

The All Values ConstructThe All Values Construct

• bagof and setof produce a separate solution for each of the different values of the second argument to consul even if the second argument is _.

• To make bagof and setof collect all the values regardless of the values of the parameters not mentioned in the selector term we must use ^.

| ?- bagof(C,When^consul(C,When),L).L = [metellus, ..., octavius]yes| ?- setof(C,When^consul(C,When),L).L = [ahenobarabus, ..., sulla]yes| ?-

• setof produces its results in < order and with duplicates removed.

Page 10: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.108.10

Sets vs. BagsSets vs. Bags

• Using bagof the same answer may appear several times in the result list.

– e.g. Caesar was Consul several times.

• A bag is a mathematical concept meaning a collection of things.

• A set is a mathematical concept meaning a collection of things without duplicates.

• In mathematics a set is unordered.

• In PROLOG setof always orders its results since this makes removing duplicates easier.

– The ordering is almost always the ordering you would expect.

– Numerical for numbers.

– Lexicographical for alphanumerics.

Page 11: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.118.11

setof, bagof and findallsetof, bagof and findall

• If there are no values for which the generator term succeeds then findall succeeds and binds the result list to [].

• setof and bagof will fail in this case.

| ?- findall(C,consul(C,79),L).L = []yes| ?- bagof(C,consul(C,79),L).no| ?- setof(C,consul(C,79),L).no| ?-

Page 12: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.128.12

setof, bagof and findall IIsetof, bagof and findall II

• findall, bagof and setof will not work if the generator query is a logical variable.

– PROLOG cannot perform higher order matching.

– findall, bagof and setof are functional rather than relational. Still declarative though.

| ?- findall(1, Q, [1]).uncaught exception : ...| ?-

• findall, bagof and setof are similar to the list comprehension operators found in functional programming languages.

Page 13: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.138.13

Making Structures From ListsMaking Structures From Lists

| ?- T =.. [consul, X, Y].T = consul(X, Y).yes| ?-

• =.. converts its right hand argument from a list into a structure.

– The first element is used as the functor.

– The rest of the elements are the components.

• The structure is then matched with the left hand argument.

• =.. is declarative (but not relational). However, it is often used with call which is not declarative.

Page 14: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.148.14

Making Goals From ListsMaking Goals From Lists

| ?- T =.. [consul, X, Y], call(T).T = consul(metellus, 80)X = metellusY = 80 ;T = consul(sulla, 80)X = sullaY = 80yes| ?-

• The argument of call can be any structure. call treats the structure as a goal (i.e. a query) and solves it.

• Seems a lot of trouble to go to just to solve consul(X, Y).

• The pay off is that we can use =.. and call to evaluate any arbitrary list as a goal.

– e.g. a list generated by a previous goal.

– We can generate goals to solve as the program runs.

Page 15: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.158.15

Making Goals From Lists IIMaking Goals From Lists II

• In effect, we can write programs that compute goals for themselves as they go on.

– Very useful in AI where programs must exhibit adaptive behaviour.

• This can make debugging somewhat difficult : a program could produce incorrect results, or even crash, by attempting to solve a goal which did not exist in the text of the program when it was written.

• To make debugging even more fun PROLOG allows programs to actually add and remove predicates as they run by using the asserta, assertz and retract higher order predicates.

Page 16: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.168.16

asserting Factsasserting Facts

| ?- move(A, B).uncaught exception : ... | ?- assertz(move(newcastle, durham)).yes| ?- move(A, B).A = newcastleB = durham ;no| ?- assertz(move(durham, sunderland)).yes| ?- move(A,B).A = newcastleB = durham ;A = durhamB = sunderland ;no| ?-

Page 17: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.178.17

asserting Facts IIasserting Facts II

• Initially there are no predicates about move in the database so the query causes an exception.

• We then use assertz to add the clause move(newcastle,durham) to the end of the database. The query now succeeds once.

• We then use assertz to add the clause move(durham, sunderland) to the end of the database. The query now succeeds twice.

• The two new facts are added to the database held within GNU PROLOG.

– The copy on disk is unaffected.

• In contrast, call does not modify the database. It throws away the goal once it has been solved.

Page 18: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.188.18

asserting Rulesasserting Rules

| ?- assertz((move(X,Y):-move(X,Z),move(Z,Y))).yes| ?- move(A, B).A = newcastleB = durham ;A = durhamB = sunderland ;A = newcastleB = sunderland ;yes| ?-

• Note that an extra pair of brackets are required when asserting a rule.

• asserted rules can be very memory hungry in some PROLOG systems (for example, in GNU PROLOG).

Page 19: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.198.19

retracting Predicatesretracting Predicates

• Predicates can be removed from the database using retract.

| ?- retract((move(X,Y):-move(X,Z),move(Z,Y))).yes| ?- move(A, B).A = newcastleB = durham ;A = durhamB = sunderlandyes| ?-

• Note that an extra pair of brackets are required when retracting a rule.

• To retract a fact or rule it must be listed in full.

Page 20: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.208.20

retracting Predicates IIretracting Predicates II

| ?- retract((move(durham,sunderland))).yes| ?- move(A, B).A = newcastleB = durhamyes| ?- retract((consul(pansa,43)).uncaught exception : ...| ?-

• GNU PROLOG only lets us retract predicates which we have asserted at run time. Some PROLOGs will allow predicates from the original database to be retracted as well.

• retract doesn’t affect the program on disk.

Page 21: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.218.21

Using =.. With assert And retractUsing =.. With assert And retract

• Can use =.. to convert an arbitrary (i.e. program generated) list into a structure and then either assert or retract it.

| ?- T =.. [move,london,newcastle], assertz(T).T = move(london,newcastle)yes| ?- move(A, B).A = newcastleB = durham ;A = londonB = newcastleyes| ?- T =.. [move,newcastle,durham], retract(T).T = move(newcastle,durham)yes| ?- move(A, B).A = londonB = newcastleyes| ?-

Page 22: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.228.22

Self Modifying Code : AdvantagesSelf Modifying Code : Advantages

• Using =.., asserta, assertz and retract we can write self modifying code.

– Code that changes its behaviour as it runs.

• This is very useful for AI systems as it supports adaptive behaviour.

– A similar facility is provided in LISP via the eval ‘function’.

• asserta, assertz and retract can be used in the same way as any other predicate.

– In particular, you can put calls to them in the rules in your program.

– Very flexible.

– Very powerful.

Page 23: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.238.23

Self Modifying Code : DisadvantagesSelf Modifying Code : Disadvantages

• call is bad enough for debugging : a bug can be caused by a call of a goal which is not in the original program.

• asserta, assertz and retract are even worse.

– A bug can be caused by a fact or a rule which does not exist in the original program but which was asserted at run time.

– With some PROLOG systems, a bug can be caused by a call of a fact or a rule which does exist in the original program but which was retracted at run time.

• asserta, assertz and retract are less declarative than the C++ goto statement.

• asserta, assertz, retract, =.. and call are extremely powerful constructs. They should be used with caution.

– Caution = Don’t use them unless you have to.

Page 24: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.248.24

SummarySummary

• findall, bagof and setof return all the successful answers for a query.

findall(Term[V], Query[V], L)

• Term[V] is the selector term.

• Query[V] is the generator query.

• L is the result list.

• bagof and setof have the same argument format as findall.

• setof orders its results and removes duplicates. findall and bagof do not.

• _ doesn’t work properly with setof and bagof. Must use the all values construct.

Page 25: 8.1 8. Higher Order Predicates Higher order predicates in PROLOG. Higher order declarative predicates : – findall – bagof – setof – =.. Higher order non-declarative

8.258.25

Summary IISummary II

• =.., call, asserta, assertz and retract allow us to write self modifying code.

• =.. converts its list argument into a structure.

• call treats its structure argument as a goal and solves it.

• asserta treats its structure argument as a clause and adds it to the start of the database.

• assertz treats its structure argument as a clause and adds it to the end of the database.

• retract treats its structure argument as a clause and removes it from the database.

– Using GNU PROLOG we can only retract clauses asserted at run time.

• Self modifying code is dangerous.