-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuildQuestionRules.clp
84 lines (82 loc) · 3.37 KB
/
buildQuestionRules.clp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
* Authored by Bennett Liu on October 30th, 2018
* Defines the functions necessary to build the rule to ask the question that optimally
* divides all remaining possible animals.
*/
/*
* Defines the buildQuestionString function, which given a round, generates the rule string
* to ask the question that optimally divides all remaining possible animals. This is done
* by finding the characteristic that minimizes the value max((Y+?) (N+?)). If this
* characteristic is able to eliminate any current possibility and it is not at the last
* question, it asks about that characteristic. Otherwise, it builds the TryAllRule to
* try all remaining animals until the question cap has been reached. Has negative salience
* to allow all countRules to run in time.
*
* Below is an example when 1 is entered as the round
*
*(defrule question1(declare (salience -100))
* =>
* (bind ?least ?*POSSIBILITIES*)
* (bind ?leastDex -1)
* (for (bind ?i 1) (<= ?i (length$ ?*CHARACTERISTICS*)) (++ ?i)
* (if (and (= (nth$ ?i ?*ASKED*) FALSE) (< (nth$ ?i ?*NO*) ?least) (< (nth$ ?i ?*YES*) ?least)) then
* (if (< (nth$ ?i ?*NO*) (nth$ ?i ?*YES*)) then
* (bind ?least (nth$ ?i ?*YES*))
* else
* (bind ?least (nth$ ?i ?*NO*))
* )
* (bind ?leastDex ?i)
* )
* (bind ?*NO* (replace$ ?*NO* ?i ?i (create$ 0)))
* (bind ?*YES* (replace$ ?*YES* ?i ?i (create$ 0)))
* )
* (if (and (<> ?leastDex -1) (< ?*QUESTION* ?*QUESTIONCAP*)) then
* (bind ?response (askCharacteristic (str-cat \"Question #\" (toString ?*QUESTION*) \": \" (nth$ ?leastDex ?*QUESTIONS*))))
* (bind ?*QUESTION* (+ ?*QUESTION* 1))
* (bind ?*ASKED* (replace$ ?*ASKED* ?leastDex ?leastDex (create$ TRUE)))
* (buildTransRule 2 ?leastDex ?response)
* (buildQuestionRule 2)
* (bind ?*POSSIBILITIES* 0)
* else
* (buildTryAllRule 1)
* )
*)
*/
(deffunction buildQuestionString (?round)
(bind ?ruleString (str-cat "(defrule question" (toString ?round) "(declare (salience -100))
=>
(bind ?least ?*POSSIBILITIES*)
(bind ?leastDex -1)
(for (bind ?i 1) (<= ?i (length$ ?*CHARACTERISTICS*)) (++ ?i)
(if (and (= (nth$ ?i ?*ASKED*) FALSE) (< (nth$ ?i ?*NO*) ?least) (< (nth$ ?i ?*YES*) ?least)) then
(if (< (nth$ ?i ?*NO*) (nth$ ?i ?*YES*)) then
(bind ?least (nth$ ?i ?*YES*))
else
(bind ?least (nth$ ?i ?*NO*))
)
(bind ?leastDex ?i)
)
(bind ?*NO* (replace$ ?*NO* ?i ?i (create$ 0)))
(bind ?*YES* (replace$ ?*YES* ?i ?i (create$ 0)))
)
(if (and (<> ?leastDex -1) (< ?*QUESTION* ?*QUESTIONCAP*)) then
(bind ?response (askCharacteristic (str-cat \"Question #\" (toString ?*QUESTION*) \": \" (nth$ ?leastDex ?*QUESTIONS*))))
(bind ?*QUESTION* (+ ?*QUESTION* 1))
(bind ?*ASKED* (replace$ ?*ASKED* ?leastDex ?leastDex (create$ TRUE)))
(buildTransRule " (toString (+ ?round 1)) " ?leastDex ?response)
(buildQuestionRule " (+ ?round 1) ")
(bind ?*POSSIBILITIES* 0)
else
(buildTryAllRule " ?round ")
)
)"))
(return ?ruleString)
)
/*
* Defines the buildQuestionRule function, which given a round, builds the rule string
* to ask the question that optimally divides all remaining possible animals.
*/
(deffunction buildQuestionRule (?round)
(build (buildQuestionString ?round))
(return)
)