Added the simplifier, although it's not currently used, I don't think
This commit is contained in:
parent
717097070a
commit
547edbe56a
|
@ -12,7 +12,7 @@
|
|||
:url "http://www.gnu.org/licenses/gpl-2.0.html"}
|
||||
:plugins [[lein-marginalia "0.7.1"]]
|
||||
:dependencies [[org.clojure/clojure "1.6.0"]
|
||||
[org.clojure/tools.trace "0.7.8"]
|
||||
[instaparse "1.3.5"]
|
||||
[org.clojure/tools.trace "0.7.9"]
|
||||
[instaparse "1.4.1"]
|
||||
[mw-engine "0.1.5-SNAPSHOT"]
|
||||
])
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
DISJUNCT-CONDITION := CONDITION SPACE OR SPACE CONDITIONS;
|
||||
CONJUNCT-CONDITION := CONDITION SPACE AND SPACE CONDITIONS;
|
||||
CONDITION := NEIGHBOURS-CONDITION | PROPERTY-CONDITION;
|
||||
NEIGHBOURS-CONDITION := QUANTIFIER SPACE NEIGHBOURS SPACE IS SPACE PROPERTY-CONDITION | QUANTIFIER SPACE NEIGHBOURS IS EXPRESSION | QUALIFIER SPACE NEIGHBOURS-CONDITION;
|
||||
WITHIN-CONDITION := NEIGHBOURS-CONDITION SPACE WITHIN SPACE NUMERIC-EXPRESSION;
|
||||
NEIGHBOURS-CONDITION := WITHIN-CONDITION | QUANTIFIER SPACE NEIGHBOURS SPACE IS SPACE PROPERTY-CONDITION | QUANTIFIER SPACE NEIGHBOURS IS EXPRESSION | QUALIFIER SPACE NEIGHBOURS-CONDITION;
|
||||
PROPERTY-CONDITION := PROPERTY SPACE QUALIFIER SPACE EXPRESSION;
|
||||
EXPRESSION := SIMPLE-EXPRESSION | RANGE-EXPRESSION | NUMERIC-EXPRESSION | DISJUNCT-EXPRESSION | VALUE;
|
||||
SIMPLE-EXPRESSION := QUALIFIER SPACE EXPRESSION | VALUE;
|
||||
|
@ -46,6 +47,7 @@
|
|||
NONE := 'no';
|
||||
ALL := 'all'
|
||||
BETWEEN := 'between';
|
||||
WITHIN := 'within';
|
||||
IN := 'in';
|
||||
MORE := 'more';
|
||||
LESS := 'less' | 'fewer';
|
||||
|
@ -178,22 +180,57 @@
|
|||
:SYMBOL (list (keyword (second (second tree))) 'cell)
|
||||
(generate (second tree))))
|
||||
|
||||
;; (defn generate-neighbours-condition
|
||||
;; "Generate code for a condition which refers to neighbours."
|
||||
;; ([tree]
|
||||
;; (let [q (second tree)]
|
||||
;; (if (number? q)
|
||||
;; (generate-neighbours-condition '= q
|
||||
;; ([comp1 quantity property value remainder comp2 distance]
|
||||
;; [(list comp1
|
||||
;; (list 'count
|
||||
;; (list 'get-neighbours-with-property-value 'world
|
||||
;; '(cell :x) '(cell :y) distance
|
||||
;; (keyword property) (keyword-or-numeric value) comp2))
|
||||
;; quantity)
|
||||
;; remainder])
|
||||
;; ([comp1 quantity property value remainder comp2]
|
||||
;; (gen-neighbours-condition comp1 quantity property value remainder comp2 1)))
|
||||
(defn generate-neighbours-condition
|
||||
"Generate code for a condition which refers to neighbours."
|
||||
([tree]
|
||||
(generate-neighbours-condition tree (first (second tree))))
|
||||
([tree quantifier-type]
|
||||
(let [quantifier (second (second tree))
|
||||
pc (generate (nth tree 4))]
|
||||
(case quantifier-type
|
||||
:NUMBER (generate-neighbours-condition '= (read-string quantifier) pc 1)
|
||||
:SOME (generate-neighbours-condition '> 0 pc 1)
|
||||
:QUANTIFIER
|
||||
(let [comparative (generate (simplify (second quantifier)))
|
||||
value (simplify (nth quantifier 5))]
|
||||
(generate-neighbours-condition comparative value pc 1)))))
|
||||
([comp1 quantity property-condition distance]
|
||||
(list comp1
|
||||
(list 'count (list 'remove false (list 'map (list 'fn ['cell] property-condition) '(get-neighbours cell world distance)))) quantity))
|
||||
([comp1 quantity property-condition]
|
||||
(generate-neighbours-condition comp1 quantity property-condition 1)))
|
||||
|
||||
;; (def s1 "if 3 neighbours have state equal to forest then state should be forest")
|
||||
;; (def s2 "if some neighbours have state equal to forest then state should be forest")
|
||||
;; (def s3 "if more than 3 neighbours have state equal to forest then state should be forest")
|
||||
;; (def s4 "if fewer than 3 neighbours have state equal to forest then state should be forest")
|
||||
;; (def s5 "if all neighbours have state equal to forest then state should be forest")
|
||||
;; (def s6 "if more than 3 neighbours within 2 have state equal to forest then state should be forest")
|
||||
|
||||
;; (nth (simplify (parse-rule s1)) 2)
|
||||
;; (second (nth (simplify (parse-rule s1)) 2))
|
||||
;; (nth (simplify (parse-rule s2)) 2)
|
||||
;; (map simplify (nth (simplify (parse-rule s2)) 2))
|
||||
;; ;; (second (nth (simplify (parse-rule s2)) 2))
|
||||
;; ;; (nth (simplify (parse-rule s3)) 2)
|
||||
;; (second (nth (simplify (parse-rule s3)) 2))
|
||||
;; (map simplify (second (nth (simplify (parse-rule s3)) 2)))
|
||||
;; ;; (nth (simplify (parse-rule s4)) 2)
|
||||
;; ;; (second (nth (simplify (parse-rule s4)) 2))
|
||||
;; ;; (nth (simplify (parse-rule s5)) 2)
|
||||
;; ;; (second (nth (simplify (parse-rule s5)) 2))
|
||||
;; ;; (nth (simplify (parse-rule s6)) 2)
|
||||
;; ;; (second (nth (simplify (parse-rule s6)) 2))
|
||||
|
||||
;; ;; (generate (nth (nth (simplify (parse-rule s5)) 2) 4))
|
||||
;; ;; (generate (nth (simplify (parse-rule s2)) 2))
|
||||
;; ;; (generate (nth (simplify (parse-rule s1)) 2))
|
||||
|
||||
|
||||
;; (generate-neighbours-condition '= 3 '(= (:state cell) :forest) 1)
|
||||
;; (generate-neighbours-condition (nth (simplify (parse-rule s3)) 2))
|
||||
;; (generate-neighbours-condition (nth (simplify (parse-rule s2)) 2))
|
||||
;; (generate-neighbours-condition (nth (simplify (parse-rule s1)) 2))
|
||||
|
||||
|
||||
(defn generate
|
||||
|
@ -209,7 +246,6 @@
|
|||
:CONDITIONS (generate-conditions tree)
|
||||
:CONJUNCT-CONDITION (generate-conjunct-condition tree)
|
||||
:DISJUNCT-CONDITION (generate-disjunct-condition tree)
|
||||
:PROPERTY-CONDITION (generate-property-condition tree)
|
||||
:DISJUNCT-EXPRESSION (generate (nth tree 2))
|
||||
:DISJUNCT-VALUE (generate-disjunct-value tree)
|
||||
:EQUIVALENCE '=
|
||||
|
@ -220,10 +256,11 @@
|
|||
= 'not=
|
||||
> '<
|
||||
< '>)
|
||||
;; :NEIGHBOURS-CONDITION (generate-neighbours-condition tree)
|
||||
:NEIGHBOURS-CONDITION (generate-neighbours-condition tree)
|
||||
:NUMERIC-EXPRESSION (generate-numeric-expression tree)
|
||||
:NUMBER (read-string (second tree))
|
||||
:PROPERTY (list (generate (second tree)) 'cell) ;; dubious - may not be right
|
||||
:PROPERTY-CONDITION (generate-property-condition tree)
|
||||
:QUALIFIER (generate (second tree))
|
||||
:RULE (generate-rule tree)
|
||||
:SIMPLE-ACTION (generate-simple-action tree)
|
||||
|
@ -271,7 +308,7 @@
|
|||
:CONDITION (simplify-second-of-two tree)
|
||||
:CONDITIONS (simplify-second-of-two tree)
|
||||
:EXPRESSION (simplify-second-of-two tree)
|
||||
:QUANTIFIER (simplify-second-of-two tree)
|
||||
;; :QUANTIFIER (simplify-second-of-two tree)
|
||||
:NOT nil
|
||||
:PROPERTY (simplify-second-of-two tree)
|
||||
:SPACE nil
|
||||
|
|
92
src/mw_parser/simplifier.clj
Normal file
92
src/mw_parser/simplifier.clj
Normal file
|
@ -0,0 +1,92 @@
|
|||
(ns mw-parser.simplifier
|
||||
(:use mw-engine.utils
|
||||
mw-parser.parser))
|
||||
|
||||
(declare simplify)
|
||||
|
||||
(defn simplify-qualifier
|
||||
"Given that this `tree` fragment represents a qualifier, what
|
||||
qualifier is that?"
|
||||
[tree]
|
||||
(cond
|
||||
(empty? tree) nil
|
||||
(and (coll? tree)
|
||||
(member? (first tree) '(:EQUIVALENCE :COMPARATIVE))) tree
|
||||
(coll? (first tree)) (or (simplify-qualifier (first tree))
|
||||
(simplify-qualifier (rest tree)))
|
||||
(coll? tree) (simplify-qualifier (rest tree))
|
||||
true tree))
|
||||
|
||||
(defn simplify-second-of-two
|
||||
"There are a number of possible simplifications such that if the `tree` has
|
||||
only two elements, the second is semantically sufficient."
|
||||
[tree]
|
||||
(if (= (count tree) 2) (simplify (nth tree 1)) tree))
|
||||
|
||||
|
||||
(defn simplify-some
|
||||
"'some' is the same as 'more than zero'"
|
||||
[tree]
|
||||
[:COMPARATIVE '> 0])
|
||||
|
||||
(defn simplify-none
|
||||
"'none' is the same as 'zero'"
|
||||
[tree]
|
||||
[:COMPARATIVE '= 0])
|
||||
|
||||
(defn simplify-all
|
||||
"'all' isn't actually the same as 'eight', because cells at the edges of the world have
|
||||
fewer than eight neighbours; but it's a simplifying (ha!) assumption for now."
|
||||
[tree]
|
||||
[:COMPARATIVE '= 8])
|
||||
|
||||
(defn simplify-quantifier
|
||||
"If this quantifier is a number, 'simplifiy' it into a comparative whose operator is '='
|
||||
and whose quantity is that number. This is actually more complicated but makes generation easier."
|
||||
[tree]
|
||||
(if (number? (second tree)) [:COMPARATIVE '= (second tree)] (simplify (second tree))))
|
||||
|
||||
(defn simplify
|
||||
"Simplify/canonicalise this `tree`. Opportunistically replace complex fragments with
|
||||
semantically identical simpler fragments"
|
||||
[tree]
|
||||
(if
|
||||
(coll? tree)
|
||||
(case (first tree)
|
||||
:SPACE nil
|
||||
:QUALIFIER (simplify-qualifier tree)
|
||||
:CONDITIONS (simplify-second-of-two tree)
|
||||
:CONDITION (simplify-second-of-two tree)
|
||||
:EXPRESSION (simplify-second-of-two tree)
|
||||
:COMPARATIVE (simplify-second-of-two tree)
|
||||
:QUANTIFIER (simplify-quantifier tree)
|
||||
:VALUE (simplify-second-of-two tree)
|
||||
:PROPERTY (simplify-second-of-two tree)
|
||||
:ACTIONS (simplify-second-of-two tree)
|
||||
:ACTION (simplify-second-of-two tree)
|
||||
:ALL (simplify-all tree)
|
||||
:SOME (simplify-some tree)
|
||||
:NONE (simplify-none tree)
|
||||
(remove nil? (map simplify tree)))
|
||||
tree))
|
||||
|
||||
(simplify (parse-rule "if state is climax and 4 neighbours have state equal to fire then 3 chance in 5 state should be fire"))
|
||||
(simplify (parse-rule "if state is climax and no neighbours have state equal to fire then 3 chance in 5 state should be fire"))
|
||||
|
||||
(simplify (parse-rule "if state is in grassland or pasture or heath and more than 4 neighbours have state equal to water then state should be village"))
|
||||
|
||||
(simplify (parse-rule "if 6 neighbours have state equal to water then state should be village"))
|
||||
|
||||
(simplify (parse-rule "if fertility is between 55 and 75 then state should be climax"))
|
||||
|
||||
(simplify (parse-rule "if state is forest then state should be climax"))
|
||||
|
||||
|
||||
(simplify (parse-rule "if state is in grassland or pasture or heath and more than 4 neighbours have state equal to water then state should be village"))
|
||||
(simplify (parse-rule "if altitude is less than 100 and state is forest then state should be climax and deer should be 3"))
|
||||
(simplify (parse-rule "if altitude is 100 or fertility is 25 then state should be heath and fertility should be 24.3"))
|
||||
(simplify (parse-rule "if altitude is 100 or fertility is 25 then state should be heath"))
|
||||
|
||||
(simplify (parse-rule "if deer is more than 2 and wolves is 0 and fertility is more than 20 then deer should be deer + 2"))
|
||||
(simplify (parse-rule "if deer is more than 1 and wolves is more than 1 then deer should be deer - wolves"))
|
||||
(simplify (parse-rule "if state is grassland and 4 neighbours have state equal to water then state should be village"))
|
Loading…
Reference in a new issue