aboutsummaryrefslogtreecommitdiff
path: root/chap4/part4.rkt
diff options
context:
space:
mode:
Diffstat (limited to 'chap4/part4.rkt')
-rw-r--r--chap4/part4.rkt177
1 files changed, 154 insertions, 23 deletions
diff --git a/chap4/part4.rkt b/chap4/part4.rkt
index 779437e..a6b94d9 100644
--- a/chap4/part4.rkt
+++ b/chap4/part4.rkt
@@ -114,19 +114,13 @@
(define (make-assertion x) (list 'assert! x))
-(#%provide q-defs)
-(define q-defs
- (map
- make-assertion
- (append personel-defs rule-defs)))
-
#| 4.57 |#
(define can-replace-def
'(rule (can-replace ?p1 ?p2)
(and
(job ?p1 ?p1-job)
- (job ?p2 ?p2-job)
+ (job ?p2 ?p2-job)
(or
(same ?p1-job ?p2-job)
(can-do-job ?p1-job ?p2-job))
@@ -151,7 +145,7 @@
(not
(and
(supervisor ?x ?sup)
- (job ?sup (?div . ?rest-2))))))
+ (job ?sup (?div . ?rest-2)))))))
#| 4.59 |#
@@ -176,25 +170,104 @@
(define meeting-time-query
'(meeting-time (Hacker Alyssa P) (Wednesday . ?time)))
-(rule (append-to-form () ?y ?y))
-(rule (append-to-form () (?u . ?v) ?y (?u . ?z))
- (append-to-form ?v ?y ?z))
+(define append-rules
+ '((rule (append-to-form () ?y ?y))
+ (rule (append-to-form (?u . ?v) ?y (?u . ?z))
+ (append-to-form ?v ?y ?z))))
+
+(define (flatten lists)
+ (if (null? lists)
+ '()
+ (append (car lists) (flatten (cdr lists)))))
#| 4.61 |#
+
+(define next-to-defs
+ '((rule (?x next-to ?y in (?x ?y . ?u)))
+ (rule (?x next-to ?y in (?v . ?z))
+ (?x next-to ?y in ?z))))
+
#| 4.62 |#
+
+(define last-pair-defs
+ '((rule (last-pair (?x) ?x))
+ (rule (last-pair (?v . ?z) ?x)
+ (last-pair ?z ?x))))
+
#| 4.63 |#
+(define genealogy-defs
+ '((son Adam Cain)
+ (son Cain Enoch)
+ (son Enoch Irad)
+ (son Irad Mehujael)
+ (son Mehujael Methusael)
+ (son Methusael Lamech)
+ (wife Lamech Ada)
+ (son Ada Jabal)
+ (son Ada Jubal)
+ (rule (son-of ?f ?s)
+ (or
+ (son ?f ?s)
+ (and
+ (wife ?f ?w)
+ (son ?w ?s))))
+ (rule (grandson ?g ?s)
+ (and
+ (son-of ?f ?s)
+ (son-of ?g ?f)))))
+
;; How the Query System Works
;; Is Logic Programming Mathematical Logic
#| 4.64 |#
-#| 4.65 |#
-#| 4.66 |#
-#| 4.67 |#
+
+(define outranked-bad-def
+ '(rule (outranked-by ?staff-person ?boss)
+ (or
+ (supervisor ?staff-person ?boss)
+ (and
+ (outranked-by ?middle-manager ?boss)
+ (supervisor ?staff-person ?middle-manager)))))
+
#| 4.68 |#
+
+(define reverse-rules
+ '((rule (reverse () ()))
+ (rule (reverse (?x . ?xs) ?sxx)
+ (and
+ (reverse ?xs ?sx)
+ (append-to-form ?sx (?x) ?sxx)))))
+
#| 4.69 |#
+(define great-grandson-rules
+ '((rule (end-in-grandson (grandson) grandson))
+ (rule (end-in-grandson (great . ?rel) (?great . ?rel))
+ (end-in-grandson ?rel ?rel-))
+ (rule ((great . ?rel) ?x ?y)
+ (and
+ (son-of ?x ?s)
+ (?rel- ?s ?y)
+ (end-in-grandson ?rel ?rel-)))))
+
+(#%provide q-defs)
+(define q-defs
+ (map
+ make-assertion
+ (flatten
+ (list
+ personel-defs
+ rule-defs
+ append-rules
+ next-to-defs
+ last-pair-defs
+ genealogy-defs
+ reverse-rules
+ great-grandson-rules
+ ))))
+
;; Implementing the Query System
(define (stream-car stream) (car stream))
@@ -209,6 +282,15 @@
(proc (stream-car s))
(stream-map proc (stream-cdr s)))))
+(define (stream-filter pred stream)
+ (cond
+ ((stream-null? stream) the-empty-stream)
+ ((pred (stream-car stream))
+ (cons-stream
+ (stream-car stream)
+ (stream-filter pred (stream-cdr stream))))
+ (else (stream-filter pred (stream-cdr stream)))))
+
(define (stream-for-each proc s)
(if (stream-null? s)
'done
@@ -368,7 +450,7 @@
(put 'or 'qeval disjoin)
(define (negate operands frame-stream)
- (stream-flatmap
+ (simple-stream-flatmap
(lambda (frame)
(if
(stream-null?
@@ -382,7 +464,7 @@
(put 'not 'qeval negate)
(define (lisp-value call frame-stream)
- (stream-flatmap
+ (simple-stream-flatmap
(lambda (frame)
(if
(execute
@@ -409,7 +491,7 @@
(put 'always-true 'qeval always-true)
(define (find-assertions pattern frame)
- (stream-flatmap
+ (simple-stream-flatmap
(lambda (datum)
(check-an-assertion datum pattern frame))
(fetch-assertions pattern frame)))
@@ -737,12 +819,61 @@
#| 4.70 |#
+#| (define (add-assertion!-bad assertion) |#
+#| (store-assertion-in-index assertion) |#
+#| (set! THE-ASSERTIONS |#
+#| (cons-stream assertion THE-ASSERTION)) |#
+#| 'ok) |#
+
+;; bad because the second argument of cons-stream is delayed
+;; this would form an unwanted cycle
+
#| 4.71 |#
-#| 4.72 |#
-#| 4.73 |#
+
+(define (simple-query-bad query-pattern frame-stream)
+ (stream-flatmap
+ (lambda (frame)
+ (stream-append
+ (find-assertions query-pattern frame)
+ (apply-rules query-pattern frame)))
+ frame-stream))
+
#| 4.74 |#
+
+(define (simple-stream-flatmap proc s)
+ (simple-flatten (stream-map proc s)))
+
+(define (simple-flatten stream)
+ (stream-map
+ car
+ (stream-filter (lambda (x) (not (null? x))) stream)))
+
#| 4.75 |#
-#| 4.76 |#
-#| 4.77 |#
-#| 4.78 |#
-#| 4.79 |#
+
+(define (unique-query exps) (car exps))
+
+(define (stream-singleton? stream)
+ (cond
+ ((null? stream) false)
+ ((null? (stream-cdr stream)) true)
+ (else false)))
+
+(define (uniquely-asserted operands frame-stream)
+ (simple-stream-flatmap
+ (lambda (frame)
+ (let
+ ((result
+ (qeval
+ (unique-query operands)
+ (singleton-stream frame))))
+ (if (stream-singleton? result)
+ result
+ the-empty-stream)))
+ frame-stream))
+
+(put 'unique 'qeval uniquely-asserted)
+
+(define unique-test
+ '(and
+ (supervisor ?x ?y)
+ (unique (supervisor ?x ?anyone))))