Pure Prolog vs Extralogical Prolog n Pure Prolog

  • Slides: 16
Download presentation
Pure Prolog vs. Extralogical Prolog n Pure Prolog programs can be interpreted as logical

Pure Prolog vs. Extralogical Prolog n Pure Prolog programs can be interpreted as logical statements about what they compute. n n they are self-describing! You can read them at a high-level. term for such programs: declarative (Well, this is an ideal. . . not always true!) However, real-world requirements mean we have to use non-logical operations in Prolog programs in order for them to be practical. (a) input/output: reading from user, writing to screens, file I/O, . . . (b) control: making execution more efficient (c) low-level operations: inspecting the construction of constants, structures, . . . (d) database operations: creating, deleting, altering program clauses (e) plus other advanced tools n Unfortunately, these practical needs usually have no direct logical meaning like pure Prolog programs. n Their inclusion therefore ruins our logical interpretation COSC 2 P 93 : Extralogical Prolog 1

*** Rule of Thumb *** n Use declarative predicates when they are practical. n

*** Rule of Thumb *** n Use declarative predicates when they are practical. n Practical can mean. . . n n n It’s possible to do what is required. Efficient (speed, resources). Small programs. COSC 2 P 93 : Extralogical Prolog 2

listing, clause n n After you consult your program file(s), the clauses are asserted

listing, clause n n After you consult your program file(s), the clauses are asserted into the program database. To look at the clauses (*** after consult, not compile ***). (a) listing. - lists the whole program database (b) listing(functor/arity): lists one particular predicate n n functor: predicate name arity (optional): number of arguments eg. listing(append/3). listing(append). <-- acceptable if only one ‘append’ exists (c) clause(H, B): unifies H with a clause head, and B with its body n n backtracking will let it unify with the next clause unifying with H and B useful for grabbing clauses one after another COSC 2 P 93 : Extralogical Prolog 3

clause n (c) clause (cont) n eg. if our database has: member(X, [X|_]). member(X,

clause n (c) clause (cont) n eg. if our database has: member(X, [X|_]). member(X, [_|Y]) : - member(X, Y). ? - clause(X, Y). X = member(X, [X|_]) Y = true ; X = member(X, [_|Y]) Y= member(X, Y) ; no ? - clause(member(a, [a, b, c, d]), Y). Y = true ; Y = member(a, [b, c, d]). n n facts are stored as: member(X, [X|_]) : - true is a builtin that always succeeds (its definition: COSC 2 P 93 : Extralogical Prolog true. ) 4

Assert, retract n (d) assert(X) : asserts the clause X into the program database

Assert, retract n (d) assert(X) : asserts the clause X into the program database asserta(X): asserts clause X as the first clause in its predicate assertz(X): asserts clause X as the lasst clause in its predicate n eg. if program is: parent(tom, bob). parent(mary, bob). ? - asserta(parent(kim, nixon)). yes. ? - assertz(parent(X, Y) : - father(X. Y)). yes. ? - listing(parent). parent(kim, nixon). parent(tom, bob). parent(mary, bob). parent(X, Y) : - father(X, Y). COSC 2 P 93 : Extralogical Prolog 5

Assert, retract n (e) retract(X): finds first clause that unifies with X, and removes

Assert, retract n (e) retract(X): finds first clause that unifies with X, and removes it ? - retract(parent(mary, X)), X = bob <-- note that it shows result of unification ? - listing(parent). parent(kim, nixon). parent(tom, bob). parent(X, Y) : - father(X, Y). n (f) abolish(functor/arity): removes entire predicate ? - abolish(parent/2). yes ? - listing(parent). yes n using assert and retract, you can create & assert new facts and rules in your program, which can be executed as normal Prolog clauses COSC 2 P 93 : Extralogical Prolog 6

Assert, Retract eg. create a list of numbers from 1 to N, and assert

Assert, Retract eg. create a list of numbers from 1 to N, and assert that list for use later make_num_list(N) : make_list(N, List), asserta(my_list(List)). make_list(N, [ ]) : - N =< 0. make_list(N, [N | Rest]) : N > 0, N 2 is N - 1, make_list(N 2, Rest). n Thereafter, there exists a fact: my_list([1, 2, 3, . . . ] ): ? - make_num_list(10), my_list(L). L=[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] COSC 2 P 93 : Extralogical Prolog 7

n Consider the following: Assert/Retract ? - make_num_list(12). yes ? - listing(my_list). my_list([1, 2,

n Consider the following: Assert/Retract ? - make_num_list(12). yes ? - listing(my_list). my_list([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]). yes ? - make_num_list(8). yes ? - listing(my_list). my_list([1, 2, 3, 4, 5, 6, 7, 8]). my_list([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]). If we only want one my_list, we need to remove the previous one: make_num_list(N) : abolish(my_list/1), % always succeeds, even if my_list doesn’t exist make_list(N, List), asserta(my_list(List)). n COSC 2 P 93 : Extralogical Prolog 8

Warning about assert & retract “Danger! Danger Will Robinson!” n You need to be

Warning about assert & retract “Danger! Danger Will Robinson!” n You need to be disciplined when you use assert and retract n n n you should never use it as a regular means to pass data among predicates eg. in the last example, we could just as easily create the list and pass it to other predicates. . . ? - make_list(N, L), do_something(L), do_something_else(L), . . . often assert & retract are used for very large data items which are ‘global’ in nature, and in which passing the data is too inconvenient assert & retract are side effects! n n side effect: with respect to Prolog, any activity other than unifying logical variables when you call make_num_list, a side effect is the creation of a new fact. There is no way to know make_num_list will do this from looking at its arguments; you must look at its code in detail to know this Very bad effect on program clarity, declarativity, etc COSC 2 P 93 : Extralogical Prolog 9

Prolog Input & Output n Writing terms: write(X) - writes the term X to

Prolog Input & Output n Writing terms: write(X) - writes the term X to screen upon backtracking, write will fail nl - write a newline eg. simple debugging: make_list(N, [ ]) : - N =< 0, write(first), write(N), nl. make_list(N, [N | Rest]) : N > 0, write(second), write(N), N 2 is N - 1, make_list(N 2, Rest), write(second), write(‘finished make_list!’), nl. n Note: ‘finish make_list!’ is one constant; need single quotes! COSC 2 P 93 : Extralogical Prolog 10

I/O n eg. write out all the parent clauses to the screen write_parent :

I/O n eg. write out all the parent clauses to the screen write_parent : clause(parent(X, Y), B), write(parent(X, Y)), write(‘: -’), write(B), write(‘. ’), nl, fail. write_parent. % when clause above finally finishes, this will let write_parent % gracefully succeed (rather than fail) n n n This is a failure-driven loop. fail: always fails! (a builtin clause that isn’t defined anywhere) Improvements we can make: 1. facts are printed strangely: parent(bob, bill) : - true. 2. tedious to write things term by term 3. would be nice to make this more general, and not specific to parent COSC 2 P 93 : Extralogical Prolog 11

Improved write_clauses ? - dynamic write_list/1. % to use as example clause write_clauses(P) :

Improved write_clauses ? - dynamic write_list/1. % to use as example clause write_clauses(P) : clause(P, B), write_one_clause(P, B), fail. write_clauses(_). write_one_clause(P, true) : write_list([P, '. ', nl]). write_one_clause(P, B) : + (B == true), write_list([P, ': -', nl, tab(5), B, '. ', nl]). write_list([nl|R]) : - nl, write_list(R). write_list([tab(N)|R]) : - tab(N), write_list(R). write_list([T|R]) : - + (T=nl; T=tab(_)), write(T), write_list(R). COSC 2 P 93 : Extralogical Prolog 12

tab tab(0). tab(K) : K > 0, write(' '), K 2 is K-1, tab(K

tab tab(0). tab(K) : K > 0, write(' '), K 2 is K-1, tab(K 2). COSC 2 P 93 : Extralogical Prolog 13

Other I/O n read(X) - reads next term from input stream n n n

Other I/O n read(X) - reads next term from input stream n n n input terminated by ‘. ’ fails upon backtracking Prolog will try to unify user input with read argument; eg. n p(X) : - write(“What is your name? ”), read(X). get(X) - read a single character put(X) - write a single character . . . plus many more COSC 2 P 93 : Extralogical Prolog 14

File I/O see (X) - opens input stream to come from file ‘X’ n

File I/O see (X) - opens input stream to come from file ‘X’ n n error if X uninstantiated, or file X doesn’t exist default: ‘user’ (terminal keyboard, standard input) seeing(X) - indicates where you are currently reading input from seen - closes input stream, resets input as ‘user’ tell(X) - opens file X as target for output stream n default: ‘user’ telling(X) - where you are writing to told - closes output stream, resets to ‘user’ COSC 2 P 93 : Extralogical Prolog 15

Example file I/O % write_to_file(File, List): writes entire List to File, one line per

Example file I/O % write_to_file(File, List): writes entire List to File, one line per entry write_to_file(File, List) : telling(Old), % save old output stream name tell(File), % open new output stream dump_list(List), told, tell(Old). % this resets output to previous destination write_to_file(File, _) : - write(‘unable to write to file ‘), write(File). dump_list([ ]). dump_list([X| T]) : - write(X), nl, dump_list(T). COSC 2 P 93 : Extralogical Prolog 16