View difference between Paste ID: RZhWBbPz and RmFNC4rN
SHOW: | | - or go back to the newest paste.
1
;; Backward chaining in Clojure
2
;; -- implemented as a parallel search
3
;; -- the search tree interleaves calling of solve-goal and solve-rule
4
;; -- solveGoals takes the first result available (OR)
5
;; -- solveRules collects all results before calculating an answer (AND)
6
;; -- technically this is called an AND-OR tree
7
8
(ns backward)
9
(import '(java.util.concurrent Executors ExecutorCompletionService))
10
11
(declare start solve-goal solve-rule collect unify)
12
13
;; Choose between using parallel collect or sequential collect.
14
(def use-parallel-collect true)
15
(def collect (if use-parallel-collect pmap map))
16-
(def completion-service (ExecutorCompletionService.
16+
17-
	(Executors/newCachedThreadPool)))
17+
18
	(loop []
19
		(print "Enter query: ") (flush)
20
		(let [query (read-line)
21-
		(loop []
21+
22-
			(if (not (nil? (.poll completion-service)))
22+
23-
				(recur)))
23+
24
25
;; The rule base
26
(defn fetch-rules [goal]
27
	(case goal
28
		g '[[a,b,c],[d,e,f]]
29
		a '[[e,f]]
30
		b '[[c,d,e,f]]
31
		c '[[e,f]]
32
		d '[[e,f]]
33
		e '[[]]
34
		f '[[]]
35
		true (throw (Exception. "No applicable rule"))))
36
37
(defn solve-goal [goal]
38
	(let [rules (fetch-rules goal)]
39
		(if (some empty? rules)
40
			1.0		; return a truth value
41
			(let [comp-service (ExecutorCompletionService.
42
					(Executors/newCachedThreadPool))]
43
				(doseq [rule rules]
44
					(.submit comp-service #(solve-rule rule)))
45
				(.get (.take comp-service))))))
46-
			(do
46+
47
(defn solve-rule [rule-tail]
48-
					(.submit completion-service #(solve-rule rule)))
48+
49-
				(.get (.take completion-service))))))
49+
		(apply + truths)))		; sum up truth values -- for testing