;;;; Evaluate the following expression to load the example (CTRL x + e): (asdf:operate 'asdf:load-op :root-templates) (in-package :fcg) ;;;;; ########################################################################################## ;;;;; UNIFY AND MERGE ;;;;; ########################################################################################## ;;;;; Exercise 1: UNIFY/MATCH ;;;;; ------------------------------------------------------------------------------------------ ;;;;; (unify pattern source &optional bindings-list) ;;; Unify (or "match") essentially performs a pattern-match. A pattern always "matches" with a ;;; source if the pattern is equal to the source. (unify 'symbol 'symbol) (unify '(a larger pattern) '(a larger pattern)) (unify 'a 'b) (unify '(a pattern) '(a different pattern)) ;;; However, unify is more flexible than an equality test through the use of VARIABLES (which ;;; always start with a question mark). The pattern unifies with the source if at least one ;;; set of VARIABLE BINDINGS can be found so that if the variables are replaced by these bindings, ;;; the pattern becomes equal to the source. (unify '?variable 'symbol) (unify '?variable '(a larger pattern)) (unify '?variable '?another-variable) (unify '(a larger ?variable) '(a larger pattern)) ;;; Which of the following unifications is successful (i.e. returns non-nil)? ;;; Do you understand why? (unify 1 1) (unify 1 2) (unify 'a 'a) (unify 'a 'b) (unify '(1 2 3) '(1 2 3)) (unify '(1 2 3) '(1 3 2)) (unify '(a b (c)) '(a b (c))) (unify '(1 ((a) 2) 3) '(1 ((a) 2) 3)) (unify '() '()) ;; which is the same as (unify nil nil) (unify '((((())))) '((((()))))) (unify '(a b (c)) '(a b c)) (unify '(a b) '(b a)) ;;; With variables: (unify '?x 'a) (unify 1 1) (unify '?x '(a b)) (unify '?x '()) (unify '?x '?x) (unify '?x '?y) (unify '(a ?x c) '(a b c)) (unify '(?a b ?c) '(x ?y ?z)) (unify '(a ?x) '(?x ?x)) (unify '(a ?x) '(a (a b c (d)))) (unify '(a ?x) '(a a b c (d))) (unify '(?x a) '(a ?y)) (unify '(?x ?x) '(a a)) (unify '(?x ?x) '(a b)) ;; ! (unify '(?x a) '(a ?x)) ;; ! (unify '(?x b) '(a ?x)) (unify '((a (?z)) ?z) '((a (b)) b)) (unify '((a (?z)) ?z) '((a (b)) c)) (unify '(?x ?y (a b (?z))) '((a b (c)) a ?x)) ;; ! ;;; Why is the following unification successful? (unify '(?x + 2 = ?x) '(2 + 2 = ?x)) ;;;;; Exercise 2. MERGE ;;;;; ------------------------------------------------------------------------------------------ ;;;;; Merge = try to find the smallest superset that both patterns can unify with. ;;;;; FCG-MERGE takes three arguments: a target pattern, source pattern and a list of bindings. ;;;;; If there are no bindings, the symbol +no-bindings+ should be passed: (fcg-merge 'symbol 'symbol +no-bindings+) (fcg-merge 'a-symbol 'another-symbol +no-bindings+) (fcg-merge '(a pattern) '(a pattern) +no-bindings+) (fcg-merge '(a larger pattern) '(a pattern) +no-bindings+) (fcg-merge '(a b c) '(c b a) +no-bindings+) (fcg-merge '(a ?variable) '(a pattern) +no-bindings+) (fcg-merge '?a-variable '?another-variable +no-bindings+) ;;;;; Merging can be constrained by passing variable bindings: (fcg-merge '(?a ?b) '(x y) '((?a . x) (?b . y))) (fcg-merge '(?a ?b) '(x y) +no-bindings+) ;;;;;; Which is more lenient? Unify or merge? ;;;;; ########################################################################################## ;;;;; Exercise 3: INCREASING THE POWER OF UNIFY AND MERGE ;;;;; ########################################################################################## ;;;;; The == operator ;;;;; ------------------- ;;;;; The pattern must be a subset of the source. (unify '(a) '(a b)) (unify '(== a) '(a b)) ;; ! (unify '(== b) '(a b)) (unify '(== c) '(a b)) (unify '(== c) '(a c b)) (unify '(== a b c) '(b c a)) ;; ! (unify '(== a c) '(b c a)) (unify '(== a b c) '(a b)) (unify '(== (a (b c))) '((b c) a)) (unify '(== (a (b c))) '(a (c b))) ;; ! (unify '(== (a)) '((a b))) (unify '((== a)) '((a b))) ;; ! (unify '(== a (== b c)) '(a (b c))) ;;; Remark that this can return multiple different bindings (unify '(== ?x) '(a b)) (unify '(== ?x) '(a b c d e f g h)) (unify '(== ?x ?y) '(a b)) (unify '(== ?x ?y) '(a b c d e f g h)) ;; ! (unify '(== ?x ?x) '(a b)) (unify '(== ?x a ?y a) '(a a a a a b)) ;; And very soon hard to understand (unify '(== (a ?x) ?y ?z ((?q))) '(q (hello world) (a dog) (((()))))) ;; ! ;;; The ==1 operator (includes uniquely operator) (unify '(==1 a) '(a)) (unify '(==1 a) '(a b)) (unify '(==1 a b) '(a a b)) ;; ! (unify '(== a b) '(a a b)) (unify '(==1 ?x b) '(a b)) (unify '(==1 ?x b) '(a b ?x)) ;;;;;; Extra exercise: Figure out what these operators do by evaluating the following ;;;;;; expressions. ;;; ==p operator (permutation operator) (unify '(==p a) '(a)) (unify '(==p a) '(a b)) (unify '(==p a b) '(b a)) (unify '(==p ?x ?y c) '(c a b)) ;;; The ==0 operator (not includes operator) (unify '(==0 a) '(b)) (unify '(==0 a) '(a)) (unify '(==0 a) '(b a)) (unify '(a b (==0 c)) '(a b c)) (unify '(a b (==0 c)) '(a b (c))) (unify '(==0 ?x) '(a)) ;; !