CS 541 Lecture -*- Outline -*- * Pure Prolog ** Syntax reminders See grammar file (for lambda prolog) *** Don't forget those periods! *** comment convention is % to the end of the line *** Case sensitive: variables begin with captial letter ** facts and rules ------------------------------------------ FACTS AND RULES % fact good prolog. % rule good X :- logical X. ------------------------------------------ *** compound terms in LambdaProlog use "curried" syntax these are the data structures of Prolog Traditional Prolog terminology for operator is functor functor like a noun. ------------------------------------------ COMPOUND TERMS (tree Subtree1 Root Subtree2) (((tree Subtree1) Root) Subtree2) %lists: a::b::nil (sentence (np (n ron)) (vp (v gave) (np (art a) (n paper)) (compls (prep to) (np (n sue))))) ------------------------------------------ Note: prolog doesn't really *understand* any of this! *** scope of variables ------------------------------------------ SCOPE OF VARIABLES (understand L X) :- (know terms L X), (know syntax L X), (know semantics L X). (grandparent K L) :- (parent K P), (parent P L). ------------------------------------------ Q: Which L's should mean the same person? Q: So what does that mean the scope of a variable is in Prolog? scope of L and X is just one clause! think of it as forall L,X ... has nothing to do with the L in grandparent rule. similarly for scope of P. ** kinds and types ------------------------------------------ KINDS AND TYPES % declaration of a type kind event type. kind person type. % declaration of type of a name type actor event -> person -> o. ------------------------------------------ read these off... explain "o" as 'truth values' (name from A. Church) ** Examples *** assertions ------------------------------------------ % A SEMANTIC NETWORK sig semantic_net. kind event type. kind person type. kind thing type. kind verb type. type event1 event. type paper thing. type sue person. type ron person. type gave verb. type event2 event. type football thing. type swen person. type object event -> thing -> o. type recipient event -> person -> o. type actor event -> person -> o. type action event -> verb -> o. ------------------------------------------ ------------------------------------------ module semantic_net. % a semantic network object event1 paper. recipient event1 sue. actor event1 ron. action event1 gave. ------------------------------------------ *** queries note that "?- " is the system prompt run the compiler and simulator as follows... $ tjcc semantic_net Reading module signature ... $ tjsim semantic_net Welcome to Teyjus ... [semantic_net] ?- % was the object of event1 a paper? object event1 paper. yes [semantic_net] ?- % what was given in event1? object event1 What. The answer substitution: What = paper More solutions (y/n)? y no (more) solutions [semantic_net] ?- actor Event Who , action Event gave. The answer substitution: Who = ron Event = event1 More solutions (y/n)? y no (more) solutions [semantic_net] ?- (actor X Y) , (action X Z). The answer substitution: Z = gave Y = ron X = event1 More solutions (y/n)? y no (more) solutions [semantic_net] ?- stop. $ Q: what is the result of the query: recipient event1 Who. ? Q: how would you add the fact that in event2, sue gave the football to swen? ** Lists ------------------------------------------ % LISTS sig list. % this is all built in to lambda Prolog % but this shows how it would be done. kind list type -> type. type nil (list T). type '::' T -> (list T) -> (list T). infixr '::' 5. ------------------------------------------ nil is empty list (3::L) is a list with head 3, tail L like (cons 3 L) in LISP exactly like 3::L in SML or 3:L in Haskell (1::2::3::nil) (1::2::L) is list with head 1, tail (2::L) In Teyjus: can also write nil as [], (1::2::3::nil) as [1,2,3] Lambda Prolog's built-in notation for lists isn't special... ------------------------------------------ LIST NOTATION ISN'T SPECIAL % signature file sig lisp_lists. kind lisp_list type -> type. type the_empty_list (lisp_list T). type cons T -> (lisp_list T) -> (lisp_list T). type to_list (lisp_list T) -> (list T) -> o. end % the module module lisp_lists. % an inductive definition to_list the_empty_list nil. to_list (cons Head Tail) (Head::PL) :- to_list Tail PL. end ------------------------------------------ Q: what are these type decls like in Haskell? *** example using lists ------------------------------------------ sig addtoend1. type addtoend (list T) -> T -> (list T) -> o. module addtoend1. addtoend ------------------------------------------ Q: How would we write this? ... addtoend nil X (X::nil). addtoend (Y::L) X (Y::M) :- (addtoend L X M). talk about this as a *relation*! note the differences from pattern matching in SML or Haskell, the two Y's are the same... try the queries (addtoend (3::nil) 4 Out). (addtoend Out 4 (2::4::nil)). % backwards! (addtoend (3::nil) 4 (3::4::nil)). % just checking! (addtoend A B C). % what would work? ** Interpretations of clauses ------------------------------------------ INTERPRETATIONS OF CLAUSES (h X) :- (b1 Y), (b2 Z), (b3 W). declarative interpretation: procedural interpretation: ------------------------------------------ ... (h X) if (b1 Y) & (b2 Z) & (b3 W) ... procedure with head: (h X) and body: (b1 Y), (b2 Z), (b3 W). *** declarative to solve problem of form h, need to solve {b1,b2,b3}. in logic this is an implication): (b1 Y) and (b2 Z) and (b3 W) imply (h X) Knowledge based systems rule (if-then rule), with antecedents (b1 Y), ... and consequent (h X). *** Procedural reading (programming language) head h identifies form of call it can answer, body {b1,b2,b3} is an ordered list of procedure calls. ** tracing queries paper tracing: ?- (addtoend (3::nil) 4 L). prime all the variables in the program, then unify by { Y' |-> 3, L' |-> nil, X' |-> 4, L |-> (3::M') } so get new goal ?- (addtoend nil 4 M'). unify with first clause in addtoend... by {X'' |-> 4, M' |-> (4::nil)} which means we're done so answer is L = (3::M'), where M' = (4::nil) so L = (3::(4::nil)) = (3::4::nil) ** variation on addtoend ------------------------------------------ % VARIATION ON ADDTOEND sig addtoend2. type equals T -> T -> o. type addtoend (list T) -> T -> (list T). module addtoend2. equals (addtoend nil X) (X::nil). equals (addtoend (Y::L) X) (Y::M) :- equals (addtoend L X) M. ------------------------------------------ try the query equals (addtoend (3::nil) 4) L. Q: can you trace this? ** reverse develop a version of reverse/2 sig reverse. type reverse (list T) -> (list T) -> o. end module reverse reverse nil nil. reverse (X::Xs) Ys :- reverse Xs Zs, addtoend Zs X Ys. end Q: can you write append of type (list T) -> (list T) -> (list T) -> o ? run them forwards and backwards See list_examples.mod