COP 4020 meeting -*- Outline -*- * Example: learning lambda Prolog ** motivation ------------------------------------------ MOTIVATIONS FOR LOGIC PROGRAMMING 1. write programs efficiently 2. execute specifications 3. separate directions about control and data structures How would you specify a sort routine? ------------------------------------------ ... sorted(List) = List' where ordered(List') and permutation(List, List') Q: How can we then use this specification to sort some list L? exist L' . sort(L) = L' Q: How could such a theorem be proved? - give the sorted list L' (constructive) - prove that every list can be sorted (nonconstructive) ** programming model ------------------------------------------ ABSTRACTING FROM THE EXAMPLE Model: programs are modeled as Specification of a problem: a problem to be solved is Answer to a problem: ------------------------------------------ ... relations between input and output ... a decription of facts and relationships and an existential conjecture about the existence of a relationship. for example, sorted(List, List') if ordered(List') and permutation(List,List'). exists O . L = [3,1,2] and sorted(L, O)? ... a constructive proof of the conjecture, which thus actually produces the output. e.g., the sorted list The problem (for the language designer/implementor) is: how to state such descriptions and conjectures how to instruct a system to do such constructive proofs how to do it fast Q: Why is the programming model important? it gives you an overall strategy for organizing programs ** Basic elements of a language *** Data (means of computation) ------------------------------------------ WHAT DATA? For logic programming use: data syntax - named entities - unknown entities - relationships ------------------------------------------ ... , dog, 3 ... X, Y ... , sorted, (sorted L1) ** means of combination ------------------------------------------ CONNECTIVES FOR EFFECTIVE SPECIFICATION Effectively describe L2? - (ordered L2) and (permutation L1 L2) - (ordered L2) or (empty L2) Effectively describe a relationship? - (sorted L1 L2) if ((ordered L2) and (permutation L1 L2)) - (less X Y) if not (greater X Y) ------------------------------------------ the key is effectiveness (compuatbility and efficiency of it) nondeterminism is ok (define it if needed) give real syntax after: and = "," or = ";" or is written using separate "clauses". implies = "=>" and ":-" in the other direction. Q: Does "not" give an effective computation? only if the search space is finite (closed world) Q: What about universal quantification? Existential quantification? existential quantification is fine, gives a search universal is also fine, if the search space is finite ------------------------------------------ CONNECTIVES FOR EFFECTIVE QUERYING Effectively ask for L2? - (ordered L2) and (permutation L1 L2) - (ordered L2) or (empty L2) ------------------------------------------ both of these work. Can write with , (and) and ; (or) ** means of abstraction (usually naming) *** facts and rules ------------------------------------------ FACTS AND RULES % file facts_rules.sig sig facts_rules. kind entity type. type flower entity. type spock entity. type good entity -> o. type logical entity -> o. % file facts_rules.mod % fact good flower. logical spock. % rule good X :- logical X. ------------------------------------------ **** compound terms in LambdaProlog use "curried" syntax these are the data structures of lambda 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: lambda 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 lambda 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 ... $ tjlink semantic_net $ 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