Presentation is loading. Please wait.

Presentation is loading. Please wait.

Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 1 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt.

Similar presentations


Presentation on theme: "Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 1 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt."— Presentation transcript:

1 Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 1 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt Term-Equation-ADT.rkt Unify.rkt Lazy-Tree Lazy-Tree-ADT.rkt Answer-Query.rkt

2 % Signature: append(List1, List2, List3)/3 % Purpose: List3 is the concatenation of List1 and List2. append([], Xs, Xs). append([X|Xs], Y, [X|Zs]) :- append(Xs, Y, Zs). member(X, Ys) :- append(Zs, [X|Xs], Ys). % Signature: append(List1, List2, List3)/3 % Purpose: List3 is the concatenation of List1 and List2. append([], Xs, Xs). append([X|Xs], Y, [X|Zs]) :- append(Xs, Y, Zs). member(X, Ys) :- append(Zs, [X|Xs], Ys). ( ((append 3) (0 ((append empty (var Xs) (var Xs)) true)) (1 ((append (cons (var X) (var Xs)) (var Y) (cons (var X) (var Zs))) (append (var Xs) (var Y) (var Zs))))) ((member 2) (0 ((member (var X) (var Ys)) (append (var Zs) (cons (var X) (var Xs)) (var Ys)) )) ) ( ((append 3) (0 ((append empty (var Xs) (var Xs)) true)) (1 ((append (cons (var X) (var Xs)) (var Y) (cons (var X) (var Zs))) (append (var Xs) (var Y) (var Zs))))) ((member 2) (0 ((member (var X) (var Ys)) (append (var Zs) (cons (var X) (var Xs)) (var Ys)) )) ) LP Interpreter: LP-AST Example 1: The abstract representation of LP procedures o A program is represented as a list of the abstract representations of its procedures. o Note: this list actually represents a set. LP-AST

3 ;% Signature: part(Name). part(a). part(b). part(c). ;% Signature: part(Name). part(a). part(b). part(c). (define parta (make-fact '(part a))) (define partb (make-fact '(part b))) (define partc (make-fact '(part c))) (define part-proc (make-procedure (list parta partb partc))) (define parta (make-fact '(part a))) (define partb (make-fact '(part b))) (define partc (make-fact '(part c))) (define part-proc (make-procedure (list parta partb partc))) LP Interpreter: LP-AST Example 2: Using LP-AST to define a program. red(a). (define reda (make-fact '(red a))) (define red-proc (make-procedure (list reda))) (define reda (make-fact '(red a))) (define red-proc (make-procedure (list reda))) yellow(c) (define yellowc (make-fact '(yellow c))) (define yellow-proc (make-procedure (list yellowc))) (define yellowc (make-fact '(yellow c))) (define yellow-proc (make-procedure (list yellowc))) (define part-prog (make-program (list part-proc red-proc yellow-proc))) (define part-prog (make-program (list part-proc red-proc yellow-proc))) Defining queries, given a program: ; ?- part(X) (define query-partX (make-query (list '(part (var X))))) ; ?- part(X), red(X) (define query-part-redX (make-query (list '(part (var X)) '(red (var X))))) (define query-part-redX (make-query (list '(part (var X)) '(red (var X)))))

4 LP Interpreter: LP-AST (define term->vars (lambda (term) (cond ((variable? term) (list term)) ((atomic-term? term) empty) ((compound-term? term) (flatmap term->vars (compound-term->args term)))))) (define term->vars (lambda (term) (cond ((variable? term) (list term)) ((atomic-term? term) empty) ((compound-term? term) (flatmap term->vars (compound-term->args term)))))) ; Type: [Symbol * List(Term) -> Var] (define make-compound-term (lambda (functor terms) (cons functor terms))) ; Type: [Symbol * List(Term) -> Var] (define make-compound-term (lambda (functor terms) (cons functor terms))) Note: o The module includes an abstract-syntax ADT for every syntactical category. o For example, below are a few procedures from the compound-term ADT: ; Type: [Compound-term -> Symbol] (define compound-term->functor (lambda (term) (car term))) ; Type: [Compound-term -> Symbol] (define compound-term->functor (lambda (term) (car term))) ; Type: [Compound-term -> List(Term)] (define compound-term->args (lambda (term) (cdr term))) ; Type: [Compound-term -> List(Term)] (define compound-term->args (lambda (term) (cdr term))) ; Type: [T -> Boolean] (define compound-term? (lambda (x) (and (list? x) (symbol? (car x)) (andmap term? (cdr x))))) ; Type: [T -> Boolean] (define compound-term? (lambda (x) (and (list? x) (symbol? (car x)) (andmap term? (cdr x)))))

5 Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 5 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt Term-Equation-ADT.rkt Unify.rkt Lazy-Tree Lazy-Tree-ADT.rkt Answer-Query.rkt

6 LP Interpreter: Substitution-ADT The substitution-ADT and its operations: o An adaptation of the substitution-ADT module from the type-inference system:  Constructor (which also checks for circularity): make-sub(variables, terms)  Getters: sub->variables, sub->terms sub->get-var(sub,var) (returns the value of var if it is defined, or error otherwise).  Predicates: sub? empty-sub?, non-empty-sub? sub-equal?  Operations: Extension of a substitution: extend-sub(sub,var,term) Application of a substitution to LP terms, atomic formulas, rules and queries: sub-apply(sub,term), sub-apply-atomic-formula,... Restriction of a substitution: sub-restrict(sub, vars) Substitution combination: sub-combine(sub1,sub2)

7 LP Interpreter: Substitution-ADT Examples: > (sub-combine (make-sub '((var T7) (var T8)) '( Number (f (m (var T5) Number) (var T3)))) (make-sub '((var T5) (var T8)) '((var T7) Boolean))) '(sub ((var T5) (var T7) (var T8)) ((var T7) Number (f (m (var T7) Number) (var T3)))) > (sub-apply (make-sub '((var X)) '(1)) (make-compound-term 'f '((var X)))) '(f 1)

8 LP Interpreter: Term-equation-ADT The term-equation-ADT and its operations: o An adaptation of the equation-ADT module from the type-inference system:  Constructor: make-equation(term1, term2)  Getters: equation->left, equation->right  Predicates: equation?

9 Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 9 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt Term-Equation-ADT.rkt Unify.rkt Lazy-Tree Lazy-Tree-ADT.rkt Answer-Query.rkt

10 LP Interpreter: Unify Unification for atomic formulas and terms: o An adaptation of the solve module from the type inference system. o The unification algorithm uses the equation-solving method  For true / false: return the empty substitution if equal, or error otherwise.  For compound arguments: If both arguments have: same predicate (or functor), same arity, Then create equations from corresponding elements, Repeat unification. o Examples: > (unify-formulas 'true 'true) ‘(sub () ()) > (unify-formulas '(member (f (var X1)) (cons (f 2) empty)) '(member (var X) (var L))) '(sub ((var L) (var X)) ((cons (f 2) empty) (f (var X1)))))

11 Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 11 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt Term-Equation-ADT.rkt Unify.rkt Lazy-Tree Lazy-Tree-ADT.rkt Answer-Query.rkt

12 LP Interpreter: Lazy-Tree-ADT o A lazy tree is represented as a "lazy tree-list“ o The head is the root-node and the tail is a regular list of lazy-trees: (root. (lambda () (list lzt1 lzt2... lztn))) o This allows labeled trees with finite branching, but possibly infinite depth. Definition: oempty-lzt represents the empty lazy-tree o A leaf is represented by: (root. (lambda () empty-lzt)) o If n represents a node, and lzt1,...,lztn represent lazy-trees, then the above tree is represented by: (make-lzt n (lambda () (list (make-lzt n1 (lambda () (make-lzt...))) (make-lzt n2 (lambda () (make-lzt...)))... (make-lzt nm (lambda () (make-lzt...)))) ))

13 LP Interpreter: Lazy-Tree-ADT Constructors: ; Type: [Node * [() -> List(LZT(Node))] -> LZT(Node)] ; Tests: (make-lzt h (lambda () (list lzt1... lztn))) => '(h. # ) (define make-lzt cons) ; Type: [Node * [() -> List(LZT(Node))] -> LZT(Node)] ; Tests: (make-lzt h (lambda () (list lzt1... lztn))) => '(h. # ) (define make-lzt cons) ; Type: [Node * [() -> List(LZT(Node))] -> LZT(Node)] ; Tests: (make-lzt-leaf h (lambda () empty-lzt)) => '(h. # ) (define make-lzt-leaf cons) ; Type: [Node * [() -> List(LZT(Node))] -> LZT(Node)] ; Tests: (make-lzt-leaf h (lambda () empty-lzt)) => '(h. # ) (define make-lzt-leaf cons) ; Type: [Node * [Node -> List(LZT(Node))] -> LZT(Node)] ; Purpose: Main lzt constructor, using a node-expander procedure (define expand-lzt (lambda (root node-expander) (let ((child-nodes (node-expander root))) (make-lzt root (lambda () (map (lambda (node) (expand-lzt node node-expander)) child-nodes)))) )) ; Type: [Node * [Node -> List(LZT(Node))] -> LZT(Node)] ; Purpose: Main lzt constructor, using a node-expander procedure (define expand-lzt (lambda (root node-expander) (let ((child-nodes (node-expander root))) (make-lzt root (lambda () (map (lambda (node) (expand-lzt node node-expander)) child-nodes)))) )) (define empty-lzt empty)

14 LP Interpreter: Lazy-Tree-ADT Example – constructing a lazy-tree: ; Type: [Node * [Node -> List(LZT(Node))] -> LZT(Node)] ; Purpose: Main lzt constructor, using a node-expander procedure (define expand-lzt (lambda (root node-expander) (let ((child-nodes (node-expander root))) (make-lzt root (lambda () (map (lambda (node) (expand-lzt node node-expander)) child-nodes)))) )) ; Type: [Node * [Node -> List(LZT(Node))] -> LZT(Node)] ; Purpose: Main lzt constructor, using a node-expander procedure (define expand-lzt (lambda (root node-expander) (let ((child-nodes (node-expander root))) (make-lzt root (lambda () (map (lambda (node) (expand-lzt node node-expander)) child-nodes)))) )) > (define lzt1 (let ((kb '(10 20))) (expand-lzt 1 ( lambda (label) (if (> label 12) empty-lzt (map (lambda (kbi)(+ label kbi)) kb)) ) ))) > lzt1 '(1. # ) > ((cdr lzt1)) '((11. # ) (21. # ))

15 LP Interpreter: Lazy-Tree-ADT Getters: olzt->root: returns the root-value of a lazy-tree oleaf-data: returns the value in a leaf olzt->branches: returns the “next layer” of a lazy-tree, a list of lazy-trees. > (lzt->branches lzt1) '((11. # ) (21. # )) olzt->first-branch, lzt->rest-branches. olzt->take-branches(lzt,n): > (lzt->take-branches lzt1 2) '(1 (11 (21) (31)) (21)) olzt->nth-level(lzt, n): > (lzt->nth-level lzt1 0) 1 > (lzt->nth-level lzt1 2) '((21 31) ())

16 LP Interpreter: Lazy-Tree-ADT Operations – three procedures for scanning a lazy-tree: 1.lzt-filter : o returns a list of nodes that satisfy the filter predicate; o does not terminate on infinite lazy trees. ; Type: [LZT(Node) * [Node -> Boolean] -> List(Node)] ; Purpose: Collect filtered nodes in a finite lazy tree; Depth-first order (define lzt-filter (lambda (lzt filterP) (letrec ((collect (lambda (lzt) (let ((children (flatmap collect (lzt->branches lzt)))) (if (filterP (lzt->root lzt)) (cons (lzt->root lzt) children) children))))) (if (empty-lzt? lzt) empty (collect lzt))))) ; Type: [LZT(Node) * [Node -> Boolean] -> List(Node)] ; Purpose: Collect filtered nodes in a finite lazy tree; Depth-first order (define lzt-filter (lambda (lzt filterP) (letrec ((collect (lambda (lzt) (let ((children (flatmap collect (lzt->branches lzt)))) (if (filterP (lzt->root lzt)) (cons (lzt->root lzt) children) children))))) (if (empty-lzt? lzt) empty (collect lzt))))) 2.lzt-find-first(lzt, filterP) : o returns the first node that satisfies the filter predicate. o Might not terminate for infinite lazy trees. 3.lzt-filter->lzl(lzt, filterP) : o returns a lazy list of all noes that satisfy the filter predicate.

17 Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 17 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt Term-Equation-ADT.rkt Unify.rkt Lazy-Tree Lazy-Tree-ADT.rkt Answer-Query.rkt

18 LP Interpreter: Answer-query The main procedures:  answer-query: o Creates a proof tree (PT) as a lazy tree. o Nodes are defined as the data structure PT-node. o Each PT-node is labeled by a list of a query and a substitution. o The sub of each node is the combination of all subs up to that node. ; Type: [Query * Program -> List(Sub)] ; Purpose: collect all answers from a finite proof tree (define answer-query (lambda (query program) (letrec ((node-expander (lambda (node) (LP-node-expander node program)))) (let* ((pt (expand-lzt (make-PT-node query empty-sub) node-expander)) (answers (lzt-filter pt LP-success-leaf?))) (restrict-to-query-vars query (map PT-node->sub answers))) ))) ; Type: [Query * Program -> List(Sub)] ; Purpose: collect all answers from a finite proof tree (define answer-query (lambda (query program) (letrec ((node-expander (lambda (node) (LP-node-expander node program)))) (let* ((pt (expand-lzt (make-PT-node query empty-sub) node-expander)) (answers (lzt-filter pt LP-success-leaf?))) (restrict-to-query-vars query (map PT-node->sub answers))) )))  answer-query-first  answer-query-lzl

19 LP Interpreter: The procedure LP-node-expander Given a PT-node (comprising a query, Q=G1,…,Gn, and a substitution, S), and a program, P: 1.Applies Gsel on Q. the result is a goal, Gi. 2.Applies Rsel on Gi and P. The result is a list of rule-sub pairs: ((R1,S1),(R2,S2),…,(Rm,Sm)). 3.Each rule-sub pair is mapped to a new PT-node. 4.A list of PT-nodes is returned. ; Type: [PT-Node * Program -> List(PT-Node)] (define LP-node-expander (lambda (PT-node program) (let ((query (PT-node->query PT-node)) (sub (PT-node->sub PT-node))) (if (success-query? query) empty (let* ((selected-goal (Gsel query)) (rule-subs (Rsel selected-goal program)) (new-queries (map (lambda (rule-sub) (expand-query query selected-goal rule-sub)) rule-subs)) (new-subs (map (lambda (rule-sub) (sub-combine sub (rule-sub->sub rule-sub))) rule-subs))) (map make-PT-node new-queries new-subs)) )) ; Type: [PT-Node * Program -> List(PT-Node)] (define LP-node-expander (lambda (PT-node program) (let ((query (PT-node->query PT-node)) (sub (PT-node->sub PT-node))) (if (success-query? query) empty (let* ((selected-goal (Gsel query)) (rule-subs (Rsel selected-goal program)) (new-queries (map (lambda (rule-sub) (expand-query query selected-goal rule-sub)) rule-subs)) (new-subs (map (lambda (rule-sub) (sub-combine sub (rule-sub->sub rule-sub))) rule-subs))) (map make-PT-node new-queries new-subs)) ))


Download ppt "Logic Programming Interpreter Abstract Data Types: Equation and Substitution Abstract Syntax: LP-AST 1 LP-AST.rkt LP Interpreter: System Description Substitution-ADT.rkt."

Similar presentations


Ads by Google