Major overhaul of the parsing of disjunct expressions

... which it turns out have NEVER worked, and badly written tests were masking the problem. Also tagging rules with metadata as first step towards mixing production and flow rules.
This commit is contained in:
Simon Brooke 2023-07-12 20:31:07 +01:00
parent fb39f1ee9c
commit 256f9efd5e
16 changed files with 4997 additions and 778 deletions

View file

@ -91,37 +91,37 @@
</tr> </tr>
<tr> <tr>
<td><a href="mw_parser/generate.clj.html">mw-parser.generate</a></td><td class="with-bar"><div class="covered" <td><a href="mw_parser/generate.clj.html">mw-parser.generate</a></td><td class="with-bar"><div class="covered"
style="width:79.65179542981501%; style="width:75.6989247311828%;
float:left;"> 732 </div><div class="not-covered" float:left;"> 704 </div><div class="not-covered"
style="width:20.348204570184983%; style="width:24.301075268817204%;
float:left;"> 187 </div></td> float:left;"> 226 </div></td>
<td class="with-number">79.65 %</td> <td class="with-number">75.70 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:79.42857142857143%; style="width:75.67567567567568%;
float:left;"> 139 </div><div class="partial" float:left;"> 140 </div><div class="partial"
style="width:3.4285714285714284%; style="width:3.2432432432432434%;
float:left;"> 6 </div><div class="not-covered" float:left;"> 6 </div><div class="not-covered"
style="width:17.142857142857142%; style="width:21.08108108108108%;
float:left;"> 30 </div></td> float:left;"> 39 </div></td>
<td class="with-number">82.86 %</td> <td class="with-number">78.92 %</td>
<td class="with-number">318</td><td class="with-number">32</td><td class="with-number">175</td> <td class="with-number">328</td><td class="with-number">24</td><td class="with-number">185</td>
</tr> </tr>
<tr> <tr>
<td><a href="mw_parser/simplify.clj.html">mw-parser.simplify</a></td><td class="with-bar"><div class="covered" <td><a href="mw_parser/simplify.clj.html">mw-parser.simplify</a></td><td class="with-bar"><div class="covered"
style="width:79.12087912087912%; style="width:85.81560283687944%;
float:left;"> 72 </div><div class="not-covered" float:left;"> 121 </div><div class="not-covered"
style="width:20.87912087912088%; style="width:14.184397163120567%;
float:left;"> 19 </div></td> float:left;"> 20 </div></td>
<td class="with-number">79.12 %</td> <td class="with-number">85.82 %</td>
<td class="with-bar"><div class="covered" <td class="with-bar"><div class="covered"
style="width:76.0%; style="width:82.05128205128206%;
float:left;"> 19 </div><div class="partial" float:left;"> 32 </div><div class="partial"
style="width:4.0%; style="width:5.128205128205129%;
float:left;"> 1 </div><div class="not-covered" float:left;"> 2 </div><div class="not-covered"
style="width:20.0%; style="width:12.820512820512821%;
float:left;"> 5 </div></td> float:left;"> 5 </div></td>
<td class="with-number">80.00 %</td> <td class="with-number">87.18 %</td>
<td class="with-number">84</td><td class="with-number">7</td><td class="with-number">25</td> <td class="with-number">91</td><td class="with-number">6</td><td class="with-number">39</td>
</tr> </tr>
<tr> <tr>
<td><a href="mw_parser/utils.clj.html">mw-parser.utils</a></td><td class="with-bar"><div class="covered" <td><a href="mw_parser/utils.clj.html">mw-parser.utils</a></td><td class="with-bar"><div class="covered"
@ -140,9 +140,9 @@
</tr> </tr>
<tr><td>Totals:</td> <tr><td>Totals:</td>
<td class="with-bar"></td> <td class="with-bar"></td>
<td class="with-number">89.47 %</td> <td class="with-number">88.29 %</td>
<td class="with-bar"></td> <td class="with-bar"></td>
<td class="with-number">92.25 %</td> <td class="with-number">90.99 %</td>
</tr> </tr>
</table> </table>
</body> </body>

View file

@ -26,7 +26,7 @@
007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.generate&nbsp;:refer&nbsp;[generate]] 007&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.generate&nbsp;:refer&nbsp;[generate]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.simplify&nbsp;:refer&nbsp;[simplify-rule]] 008&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.simplify&nbsp;:refer&nbsp;[simplify]]
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.utils&nbsp;:refer&nbsp;[rule?]] 009&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[mw-parser.utils&nbsp;:refer&nbsp;[rule?]]
@ -443,7 +443,7 @@
146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[rule&nbsp;(trim&nbsp;rule-text) 146&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[rule&nbsp;(trim&nbsp;rule-text)
</span><br/> </span><br/>
<span class="covered" title="5 out of 5 forms covered"> <span class="covered" title="5 out of 5 forms covered">
147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree&nbsp;(simplify-rule&nbsp;(parse-rule&nbsp;rule)) 147&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree&nbsp;(simplify&nbsp;(parse-rule&nbsp;rule))
</span><br/> </span><br/>
<span class="covered" title="9 out of 9 forms covered"> <span class="covered" title="9 out of 9 forms covered">
148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;afn&nbsp;(if&nbsp;(rule?&nbsp;tree)&nbsp;(eval&nbsp;(generate&nbsp;tree)) 148&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;afn&nbsp;(if&nbsp;(rule?&nbsp;tree)&nbsp;(eval&nbsp;(generate&nbsp;tree))

File diff suppressed because it is too large Load diff

View file

@ -85,176 +85,197 @@
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
027&nbsp;&nbsp; 027&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="3 out of 3 forms covered"> <span class="covered" title="2 out of 2 forms covered">
028&nbsp;&nbsp;(declare&nbsp;simplify-flow&nbsp;simplify-rule) 028&nbsp;&nbsp;(declare&nbsp;simplify)
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
029&nbsp;&nbsp; 029&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
030&nbsp;&nbsp;;;&nbsp;(defn&nbsp;simplify-qualifier
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
031&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&quot;Given&nbsp;that&nbsp;this&nbsp;`tree`&nbsp;fragment&nbsp;represents&nbsp;a&nbsp;qualifier,&nbsp;what
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
032&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;qualifier&nbsp;is&nbsp;that?&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
033&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;[tree]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
034&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;(cond
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
035&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(empty?&nbsp;tree)&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
036&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(and&nbsp;(coll?&nbsp;tree)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
037&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(#{:EQUIVALENCE&nbsp;:COMPARATIVE}&nbsp;(first&nbsp;tree)))&nbsp;tree
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
038&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;(first&nbsp;tree))&nbsp;(or&nbsp;(simplify-qualifier&nbsp;(first&nbsp;tree))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
039&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-qualifier&nbsp;(rest&nbsp;tree)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
040&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;tree)&nbsp;(simplify-qualifier&nbsp;(rest&nbsp;tree))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
041&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;tree))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
042&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="1 out of 1 forms covered">
043&nbsp;&nbsp;(defn&nbsp;simplify-second-of-two 030&nbsp;&nbsp;(defn&nbsp;simplify-second-of-two
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;&quot;There&nbsp;are&nbsp;a&nbsp;number&nbsp;of&nbsp;possible&nbsp;simplifications&nbsp;such&nbsp;that&nbsp;if&nbsp;the&nbsp;`tree`&nbsp;has 031&nbsp;&nbsp;&nbsp;&nbsp;&quot;There&nbsp;are&nbsp;a&nbsp;number&nbsp;of&nbsp;possible&nbsp;simplifications&nbsp;such&nbsp;that&nbsp;if&nbsp;the&nbsp;`tree`&nbsp;has
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
045&nbsp;&nbsp;&nbsp;&nbsp;only&nbsp;two&nbsp;elements,&nbsp;the&nbsp;second&nbsp;is&nbsp;semantically&nbsp;sufficient.&quot; 032&nbsp;&nbsp;&nbsp;&nbsp;only&nbsp;two&nbsp;elements,&nbsp;the&nbsp;second&nbsp;is&nbsp;semantically&nbsp;sufficient.&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;[tree] 033&nbsp;&nbsp;&nbsp;&nbsp;[tree]
</span><br/> </span><br/>
<span class="partial" title="10 out of 11 forms covered"> <span class="partial" title="10 out of 11 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;(count&nbsp;tree)&nbsp;2)&nbsp;(simplify-rule&nbsp;(nth&nbsp;tree&nbsp;1))&nbsp;tree)) 034&nbsp;&nbsp;&nbsp;&nbsp;(if&nbsp;(=&nbsp;(count&nbsp;tree)&nbsp;2)&nbsp;(simplify&nbsp;(nth&nbsp;tree&nbsp;1))&nbsp;tree))
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="blank" title="0 out of 0 forms covered">
048&nbsp;&nbsp; 035&nbsp;&nbsp;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
049&nbsp;&nbsp;;;&nbsp;(defn&nbsp;simplify-quantifier
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
050&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;&quot;If&nbsp;this&nbsp;quantifier&nbsp;is&nbsp;a&nbsp;number,&nbsp;&#x27;simplifiy&#x27;&nbsp;it&nbsp;into&nbsp;a&nbsp;comparative&nbsp;whose&nbsp;operator&nbsp;is&nbsp;&#x27;=&#x27;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
051&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;and&nbsp;whose&nbsp;quantity&nbsp;is&nbsp;that&nbsp;number.&nbsp;This&nbsp;is&nbsp;actually&nbsp;more&nbsp;complicated&nbsp;but&nbsp;makes&nbsp;generation&nbsp;easier.&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
052&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;[tree]
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
053&nbsp;&nbsp;;;&nbsp;&nbsp;&nbsp;(if&nbsp;(number?&nbsp;(second&nbsp;tree))&nbsp;[:COMPARATIVE&nbsp;&#x27;=&nbsp;(second&nbsp;tree)]&nbsp;(simplify-rule&nbsp;(second&nbsp;tree))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
054&nbsp;&nbsp;
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="1 out of 1 forms covered">
055&nbsp;&nbsp;(defn&nbsp;simplify-rule 036&nbsp;&nbsp;(defn&nbsp;simplify-chained-list
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simplify&#x2F;canonicalise&nbsp;this&nbsp;`tree`.&nbsp;Opportunistically&nbsp;replace&nbsp;complex&nbsp;fragments&nbsp;with 037&nbsp;&nbsp;&nbsp;&nbsp;&quot;Some&nbsp;parse&nbsp;trees&nbsp;take&nbsp;the&nbsp;form&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;semantically&nbsp;identical&nbsp;simpler&nbsp;fragments&quot; 038&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;`[:X&nbsp;[:Y&nbsp;1]&nbsp;:NOISE&nbsp;:NOISE&nbsp;[:X&nbsp;[:Y&nbsp;2]&nbsp;:NOISE&nbsp;:NOISE&nbsp;[:X&nbsp;[:Y&nbsp;3]]]]`
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
058&nbsp;&nbsp;&nbsp;&nbsp;[tree] 039&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;where&nbsp;what&#x27;s&nbsp;wanted&nbsp;is&nbsp;`[:X&nbsp;[:Y&nbsp;1]&nbsp;[:Y&nbsp;2]&nbsp;[:Y&nbsp;2]]`&nbsp;--&nbsp;:DISJUNCT-VALUE&nbsp;is&nbsp;a&nbsp;case
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;tree)
</span><br/>
<span class="covered" title="9 out of 9 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:ACTION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:ACTIONS&nbsp;(cons&nbsp;(first&nbsp;tree)&nbsp;(simplify-rule&nbsp;(rest&nbsp;tree)))
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CHANCE-IN&nbsp;nil 040&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in&nbsp;point.&nbsp;This&nbsp;takes&nbsp;such&nbsp;a&nbsp;parse&nbsp;`tree`,&nbsp;where&nbsp;`branch-tag`&nbsp;is&nbsp;the&nbsp;tag&nbsp;of
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:COMPARATIVE&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CONDITION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CONDITIONS&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:EXPRESSION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:PROPERTY&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:PROPERTY-CONDITION-OR-EXPRESSION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:SPACE&nbsp;nil 041&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;enclosing&nbsp;form&nbsp;and&nbsp;`leaf-tag`&nbsp;is&nbsp;the&nbsp;tag&nbsp;of&nbsp;the&nbsp;form&nbsp;to&nbsp;be&nbsp;collected,&nbsp;and&nbsp;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:THEN&nbsp;nil 042&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;returns&nbsp;the&nbsp;desired&nbsp;form.&quot;
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:AND&nbsp;nil 043&nbsp;&nbsp;&nbsp;&nbsp;[tree&nbsp;branch-tag&nbsp;leaf-tag]
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
044&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/> </span><br/>
<span class="covered" title="3 out of 3 forms covered"> <span class="covered" title="3 out of 3 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:VALUE&nbsp;(simplify-second-of-two&nbsp;tree) 045&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(first&nbsp;tree)
</span><br/>
<span class="covered" title="2 out of 2 forms covered">
046&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(reverse
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
047&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(loop&nbsp;[chain&nbsp;(rest&nbsp;tree)&nbsp;v&nbsp;&#x27;()]
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
048&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(let&nbsp;[car&nbsp;(first&nbsp;chain)]
</span><br/> </span><br/>
<span class="covered" title="7 out of 7 forms covered"> <span class="covered" title="7 out of 7 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;nil?&nbsp;(map&nbsp;simplify-rule&nbsp;tree))) 049&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond&nbsp;(empty?&nbsp;chain)&nbsp;v
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="7 out of 7 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree)) 050&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;car)&nbsp;(let&nbsp;[caar&nbsp;(first&nbsp;car)]
</span><br/> </span><br/>
<span class="blank" title="0 out of 0 forms covered"> <span class="covered" title="3 out of 3 forms covered">
077&nbsp;&nbsp; 051&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cond
</span><br/> </span><br/>
<span class="covered" title="1 out of 1 forms covered"> <span class="covered" title="4 out of 4 forms covered">
078&nbsp;&nbsp;(defn&nbsp;simplify-determiner-condition 052&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;branch-tag&nbsp;caar)&nbsp;(recur&nbsp;car&nbsp;v)
</span><br/>
<span class="covered" title="4 out of 4 forms covered">
053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(=&nbsp;leaf-tag&nbsp;caar)&nbsp;(recur
</span><br/> </span><br/>
<span class="not-tracked" title="0 out of 0 forms covered"> <span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;[tree] 054&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;chain)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
055&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;(simplify&nbsp;car)&nbsp;v))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
056&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(recur&nbsp;(rest&nbsp;chain)&nbsp;v)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
057&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:else&nbsp;(recur&nbsp;(rest&nbsp;chain)&nbsp;v)))))))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
058&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
059&nbsp;&nbsp;(defn&nbsp;simplify
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
060&nbsp;&nbsp;&nbsp;&nbsp;&quot;Simplify&#x2F;canonicalise&nbsp;this&nbsp;`tree`.&nbsp;Opportunistically&nbsp;replace&nbsp;complex&nbsp;fragments&nbsp;with
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
061&nbsp;&nbsp;&nbsp;&nbsp;semantically&nbsp;identical&nbsp;simpler&nbsp;fragments&quot;
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
062&nbsp;&nbsp;&nbsp;&nbsp;[tree]
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
063&nbsp;&nbsp;&nbsp;&nbsp;(if
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
064&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(coll?&nbsp;tree)
</span><br/>
<span class="partial" title="10 out of 11 forms covered">
065&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(case&nbsp;(first&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
066&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:ACTION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="10 out of 10 forms covered">
067&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:ACTIONS&nbsp;(cons&nbsp;(first&nbsp;tree)&nbsp;(simplify&nbsp;(rest&nbsp;tree)))
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
068&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:AND&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
069&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CHANCE-IN&nbsp;nil
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
070&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:COMPARATIVE&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
071&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CONDITION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
072&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:CONDITIONS&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="5 out of 5 forms covered">
073&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:DISJUNCT-EXPRESSION&nbsp;(simplify-chained-list&nbsp;tree&nbsp;:DISJUNCT-VALUE&nbsp;:VALUE)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
074&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:EXPRESSION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
075&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:IN&nbsp;nil
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
076&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:PROPERTY&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
077&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:PROPERTY-CONDITION-OR-EXPRESSION&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
078&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:OR&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
079&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:SPACE&nbsp;nil
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:THEN&nbsp;nil
</span><br/>
<span class="covered" title="3 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:VALUE&nbsp;(simplify-second-of-two&nbsp;tree)
</span><br/>
<span class="covered" title="7 out of 7 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(remove&nbsp;nil?&nbsp;(map&nbsp;simplify&nbsp;tree)))
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tree))
</span><br/>
<span class="blank" title="0 out of 0 forms covered">
084&nbsp;&nbsp;
</span><br/>
<span class="covered" title="1 out of 1 forms covered">
085&nbsp;&nbsp;(defn&nbsp;simplify-determiner-condition
</span><br/>
<span class="not-tracked" title="0 out of 0 forms covered">
086&nbsp;&nbsp;&nbsp;&nbsp;[tree]
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-covered" title="0 out of 3 forms covered">
080&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector 087&nbsp;&nbsp;&nbsp;&nbsp;(apply&nbsp;vector
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 3 forms covered"> <span class="not-covered" title="0 out of 3 forms covered">
081&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;:DETERMINER-CONDITION 088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons&nbsp;:DETERMINER-CONDITION
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 2 forms covered"> <span class="not-covered" title="0 out of 2 forms covered">
082&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons 089&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(cons
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <span class="not-covered" title="0 out of 5 forms covered">
083&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-second-of-two&nbsp;(second&nbsp;tree)) 090&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(simplify-second-of-two&nbsp;(second&nbsp;tree))
</span><br/> </span><br/>
<span class="not-covered" title="0 out of 5 forms covered"> <span class="not-covered" title="0 out of 5 forms covered">
084&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;(rest&nbsp;tree)))))) 091&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(rest&nbsp;(rest&nbsp;tree))))))
</span><br/> </span><br/>
</body> </body>
</html> </html>

View file

@ -7,5 +7,5 @@
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.errors.html#var-bad-parse-error">bad-parse-error</a> </li><li> <a href="mw-parser.errors.html#var-reserved-properties-error">reserved-properties-error</a> </li><li> <a href="mw-parser.errors.html#var-throw-parse-exception">throw-parse-exception</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.flow.html">mw-parser.flow</a></h3><div class="doc"><div class="markdown"><p>A very simple parser which parses flow rules.</p> </div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.errors.html#var-bad-parse-error">bad-parse-error</a> </li><li> <a href="mw-parser.errors.html#var-reserved-properties-error">reserved-properties-error</a> </li><li> <a href="mw-parser.errors.html#var-throw-parse-exception">throw-parse-exception</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.flow.html">mw-parser.flow</a></h3><div class="doc"><div class="markdown"><p>A very simple parser which parses flow rules.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.flow.html#var-flow-grammar">flow-grammar</a> </li><li> <a href="mw-parser.flow.html#var-parse-flow">parse-flow</a> </li><li> <a href="mw-parser.flow.html#var-simplify-flow">simplify-flow</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.generate.html">mw-parser.generate</a></h3><div class="doc"><div class="markdown"><p>Generate Clojure source from simplified parse trees.</p> </div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.flow.html#var-flow-grammar">flow-grammar</a> </li><li> <a href="mw-parser.flow.html#var-parse-flow">parse-flow</a> </li><li> <a href="mw-parser.flow.html#var-simplify-flow">simplify-flow</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.generate.html">mw-parser.generate</a></h3><div class="doc"><div class="markdown"><p>Generate Clojure source from simplified parse trees.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.generate.html#var-generate">generate</a> </li><li> <a href="mw-parser.generate.html#var-generate-action">generate-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-condition">generate-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-conditions">generate-conditions</a> </li><li> <a href="mw-parser.generate.html#var-generate-conjunct-condition">generate-conjunct-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-condition">generate-disjunct-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-property-condition">generate-disjunct-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-value">generate-disjunct-value</a> </li><li> <a href="mw-parser.generate.html#var-generate-flow">generate-flow</a> </li><li> <a href="mw-parser.generate.html#var-generate-multiple-actions">generate-multiple-actions</a> </li><li> <a href="mw-parser.generate.html#var-generate-neighbours-condition">generate-neighbours-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-numeric-expression">generate-numeric-expression</a> </li><li> <a href="mw-parser.generate.html#var-generate-probable-action">generate-probable-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-property-condition">generate-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-qualifier">generate-qualifier</a> </li><li> <a href="mw-parser.generate.html#var-generate-ranged-property-condition">generate-ranged-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-rule">generate-rule</a> </li><li> <a href="mw-parser.generate.html#var-generate-simple-action">generate-simple-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-within-condition">generate-within-condition</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.simplify.html">mw-parser.simplify</a></h3><div class="doc"><div class="markdown"><p>Simplify a parse tree.</p> </div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.generate.html#var-generate">generate</a> </li><li> <a href="mw-parser.generate.html#var-generate-action">generate-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-condition">generate-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-conditions">generate-conditions</a> </li><li> <a href="mw-parser.generate.html#var-generate-conjunct-condition">generate-conjunct-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-condition">generate-disjunct-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-property-condition">generate-disjunct-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-disjunct-value">generate-disjunct-value</a> </li><li> <a href="mw-parser.generate.html#var-generate-flow">generate-flow</a> </li><li> <a href="mw-parser.generate.html#var-generate-multiple-actions">generate-multiple-actions</a> </li><li> <a href="mw-parser.generate.html#var-generate-neighbours-condition">generate-neighbours-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-numeric-expression">generate-numeric-expression</a> </li><li> <a href="mw-parser.generate.html#var-generate-probable-action">generate-probable-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-property-condition">generate-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-qualifier">generate-qualifier</a> </li><li> <a href="mw-parser.generate.html#var-generate-ranged-property-condition">generate-ranged-property-condition</a> </li><li> <a href="mw-parser.generate.html#var-generate-rule">generate-rule</a> </li><li> <a href="mw-parser.generate.html#var-generate-simple-action">generate-simple-action</a> </li><li> <a href="mw-parser.generate.html#var-generate-within-condition">generate-within-condition</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.simplify.html">mw-parser.simplify</a></h3><div class="doc"><div class="markdown"><p>Simplify a parse tree.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.simplify.html#var-simplify-determiner-condition">simplify-determiner-condition</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-flow">simplify-flow</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-rule">simplify-rule</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-second-of-two">simplify-second-of-two</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.utils.html">mw-parser.utils</a></h3><div class="doc"><div class="markdown"><p>Utilities used in more than one namespace within the parser.</p> </div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.simplify.html#var-simplify">simplify</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-chained-list">simplify-chained-list</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-determiner-condition">simplify-determiner-condition</a> </li><li> <a href="mw-parser.simplify.html#var-simplify-second-of-two">simplify-second-of-two</a> </li></ul></div></div><div class="namespace"><h3><a href="mw-parser.utils.html">mw-parser.utils</a></h3><div class="doc"><div class="markdown"><p>Utilities used in more than one namespace within the parser.</p>
</div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.utils.html#var-assert-type">assert-type</a> </li><li> <a href="mw-parser.utils.html#var-rule.3F">rule?</a> </li><li> <a href="mw-parser.utils.html#var-search-tree">search-tree</a> </li><li> <a href="mw-parser.utils.html#var-suitable-fragment.3F">suitable-fragment?</a> </li><li> <a href="mw-parser.utils.html#var-TODO">TODO</a> </li></ul></div></div></div></body></html> </div></div><div class="index"><p>Public variables and functions:</p><ul><li> <a href="mw-parser.utils.html#var-assert-type">assert-type</a> </li><li> <a href="mw-parser.utils.html#var-rule.3F">rule?</a> </li><li> <a href="mw-parser.utils.html#var-search-tree">search-tree</a> </li><li> <a href="mw-parser.utils.html#var-suitable-fragment.3F">suitable-fragment?</a> </li><li> <a href="mw-parser.utils.html#var-TODO">TODO</a> </li></ul></div></div></div></body></html>

File diff suppressed because one or more lines are too long

View file

@ -1,8 +1,8 @@
<!DOCTYPE html PUBLIC "" <!DOCTYPE html PUBLIC ""
""> "">
<html><head><meta charset="UTF-8" /><title>mw-parser.simplify documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-parser</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-parser</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-parser</span></div></div></li><li class="depth-2 branch"><a href="mw-parser.bulk.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bulk</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.declarative.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>declarative</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.errors.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>errors</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-2 branch current"><a href="mw-parser.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2"><a href="mw-parser.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-determiner-condition"><div class="inner"><span>simplify-determiner-condition</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-flow"><div class="inner"><span>simplify-flow</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-rule"><div class="inner"><span>simplify-rule</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-second-of-two"><div class="inner"><span>simplify-second-of-two</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-parser.simplify</h1><div class="doc"><div class="markdown"><p>Simplify a parse tree.</p> <html><head><meta charset="UTF-8" /><title>mw-parser.simplify documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-parser</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-parser</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-parser</span></div></div></li><li class="depth-2 branch"><a href="mw-parser.bulk.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bulk</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.declarative.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>declarative</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.errors.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>errors</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-2 branch current"><a href="mw-parser.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2"><a href="mw-parser.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify"><div class="inner"><span>simplify</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-chained-list"><div class="inner"><span>simplify-chained-list</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-determiner-condition"><div class="inner"><span>simplify-determiner-condition</span></div></a></li><li class="depth-1"><a href="mw-parser.simplify.html#var-simplify-second-of-two"><div class="inner"><span>simplify-second-of-two</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-parser.simplify</h1><div class="doc"><div class="markdown"><p>Simplify a parse tree.</p>
</div></div><div class="public anchor" id="var-simplify-determiner-condition"><h3>simplify-determiner-condition</h3><div class="usage"><code>(simplify-determiner-condition tree)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p> </div></div><div class="public anchor" id="var-simplify"><h3>simplify</h3><div class="usage"><code>(simplify tree)</code></div><div class="doc"><div class="markdown"><p>Simplify/canonicalise this <code>tree</code>. Opportunistically replace complex fragments with semantically identical simpler fragments</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L78">view source</a></div></div><div class="public anchor" id="var-simplify-flow"><h3>simplify-flow</h3><div class="usage"></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L59">view source</a></div></div><div class="public anchor" id="var-simplify-chained-list"><h3>simplify-chained-list</h3><div class="usage"><code>(simplify-chained-list tree branch-tag leaf-tag)</code></div><div class="doc"><div class="markdown"><p>Some parse trees take the form <code>[:X [:Y 1] :NOISE :NOISE [:X [:Y 2] :NOISE :NOISE [:X [:Y 3]]]]</code> where whats wanted is <code>[:X [:Y 1] [:Y 2] [:Y 2]]</code> :DISJUNCT-VALUE is a case in point. This takes such a parse <code>tree</code>, where <code>branch-tag</code> is the tag of the enclosing form and <code>leaf-tag</code> is the tag of the form to be collected, and returns the desired form.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L28">view source</a></div></div><div class="public anchor" id="var-simplify-rule"><h3>simplify-rule</h3><div class="usage"><code>(simplify-rule tree)</code></div><div class="doc"><div class="markdown"><p>Simplify/canonicalise this <code>tree</code>. Opportunistically replace complex fragments with semantically identical simpler fragments</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L36">view source</a></div></div><div class="public anchor" id="var-simplify-determiner-condition"><h3>simplify-determiner-condition</h3><div class="usage"><code>(simplify-determiner-condition tree)</code></div><div class="doc"><div class="markdown"><p><strong>TODO</strong>: write docs</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L55">view source</a></div></div><div class="public anchor" id="var-simplify-second-of-two"><h3>simplify-second-of-two</h3><div class="usage"><code>(simplify-second-of-two tree)</code></div><div class="doc"><div class="markdown"><p>There are a number of possible simplifications such that if the <code>tree</code> has only two elements, the second is semantically sufficient.</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L85">view source</a></div></div><div class="public anchor" id="var-simplify-second-of-two"><h3>simplify-second-of-two</h3><div class="usage"><code>(simplify-second-of-two tree)</code></div><div class="doc"><div class="markdown"><p>There are a number of possible simplifications such that if the <code>tree</code> has only two elements, the second is semantically sufficient.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L43">view source</a></div></div></div></body></html> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/simplify.clj#L30">view source</a></div></div></div></body></html>

View file

@ -3,7 +3,7 @@
<html><head><meta charset="UTF-8" /><title>mw-parser.utils documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-parser</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-parser</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-parser</span></div></div></li><li class="depth-2 branch"><a href="mw-parser.bulk.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bulk</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.declarative.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>declarative</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.errors.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>errors</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2 current"><a href="mw-parser.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-parser.utils.html#var-assert-type"><div class="inner"><span>assert-type</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-rule.3F"><div class="inner"><span>rule?</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-search-tree"><div class="inner"><span>search-tree</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-suitable-fragment.3F"><div class="inner"><span>suitable-fragment?</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-TODO"><div class="inner"><span>TODO</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-parser.utils</h1><div class="doc"><div class="markdown"><p>Utilities used in more than one namespace within the parser.</p> <html><head><meta charset="UTF-8" /><title>mw-parser.utils documentation</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Mw-parser</span> <span class="project-version">0.2.0-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to mw-parser</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>mw-parser</span></div></div></li><li class="depth-2 branch"><a href="mw-parser.bulk.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>bulk</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.core.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>core</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.declarative.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>declarative</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.errors.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>errors</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.flow.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>flow</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.generate.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generate</span></div></a></li><li class="depth-2 branch"><a href="mw-parser.simplify.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>simplify</span></div></a></li><li class="depth-2 current"><a href="mw-parser.utils.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>utils</span></div></a></li></ul></div><div class="sidebar secondary"><h3><a href="#top"><span class="inner">Public Vars</span></a></h3><ul><li class="depth-1"><a href="mw-parser.utils.html#var-assert-type"><div class="inner"><span>assert-type</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-rule.3F"><div class="inner"><span>rule?</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-search-tree"><div class="inner"><span>search-tree</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-suitable-fragment.3F"><div class="inner"><span>suitable-fragment?</span></div></a></li><li class="depth-1"><a href="mw-parser.utils.html#var-TODO"><div class="inner"><span>TODO</span></div></a></li></ul></div><div class="namespace-docs" id="content"><h1 class="anchor" id="top">mw-parser.utils</h1><div class="doc"><div class="markdown"><p>Utilities used in more than one namespace within the parser.</p>
</div></div><div class="public anchor" id="var-assert-type"><h3>assert-type</h3><div class="usage"><code>(assert-type tree-fragment type)</code></div><div class="doc"><div class="markdown"><p>If <code>tree-fragment</code> is not a tree fragment of the expected <code>type</code>, throw an exception.</p> </div></div><div class="public anchor" id="var-assert-type"><h3>assert-type</h3><div class="usage"><code>(assert-type tree-fragment type)</code></div><div class="doc"><div class="markdown"><p>If <code>tree-fragment</code> is not a tree fragment of the expected <code>type</code>, throw an exception.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L48">view source</a></div></div><div class="public anchor" id="var-rule.3F"><h3>rule?</h3><div class="usage"><code>(rule? maybe-rule)</code></div><div class="doc"><div class="markdown"><p>Return true if the argument appears to be a parsed rule tree, else false.</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L48">view source</a></div></div><div class="public anchor" id="var-rule.3F"><h3>rule?</h3><div class="usage"><code>(rule? maybe-rule)</code></div><div class="doc"><div class="markdown"><p>Return true if the argument appears to be a parsed rule tree, else false.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L29">view source</a></div></div><div class="public anchor" id="var-search-tree"><h3>search-tree</h3><div class="usage"><code>(search-tree tree tag)</code></div><div class="doc"><div class="markdown"><p>Return the first element of this tree which has this tag in a depth-first, left-to-right search</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L36">view source</a></div></div><div class="public anchor" id="var-search-tree"><h3>search-tree</h3><div class="usage"><code>(search-tree tree tag)</code></div><div class="doc"><div class="markdown"><p>Return the first element of this tree which has this tag in a depth-first, left-to-right search</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L55">view source</a></div></div><div class="public anchor" id="var-suitable-fragment.3F"><h3>suitable-fragment?</h3><div class="usage"><code>(suitable-fragment? tree-fragment type)</code></div><div class="doc"><div class="markdown"><p>Return <code>true</code> if <code>tree-fragment</code> appears to be a tree fragment of the expected <code>type</code>.</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L55">view source</a></div></div><div class="public anchor" id="var-suitable-fragment.3F"><h3>suitable-fragment?</h3><div class="usage"><code>(suitable-fragment? tree-fragment type)</code></div><div class="doc"><div class="markdown"><p>Return <code>true</code> if <code>tree-fragment</code> appears to be a tree fragment of the expected <code>type</code>.</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L41">view source</a></div></div><div class="public anchor" id="var-TODO"><h3>TODO</h3><div class="usage"><code>(TODO message)</code></div><div class="doc"><div class="markdown"><p>Marker to indicate Im not yet finished!</p> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L29">view source</a></div></div><div class="public anchor" id="var-TODO"><h3>TODO</h3><div class="usage"><code>(TODO message)</code></div><div class="doc"><div class="markdown"><p>Marker to indicate Im not yet finished!</p>
</div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L35">view source</a></div></div></div></body></html> </div></div><div class="src-link"><a href="https://github.com/simon-brooke/mw-parser/blob/master/src/mw_parser/utils.clj#L41">view source</a></div></div></div></body></html>

4020
docs/uberdoc.html Normal file

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,7 @@
(ns ^{:doc "A very simple parser which parses production rules." (ns ^{:doc "A very simple parser which parses production rules.
**NOTE**: This parser is obsolete and is superceded by the
declarative parser, q.v."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.core mw-parser.core
(:use mw-engine.utils (:use mw-engine.utils

View file

@ -5,7 +5,7 @@
[clojure.string :refer [join trim]] [clojure.string :refer [join trim]]
[mw-parser.errors :refer [throw-parse-exception]] [mw-parser.errors :refer [throw-parse-exception]]
[mw-parser.generate :refer [generate]] [mw-parser.generate :refer [generate]]
[mw-parser.simplify :refer [simplify-rule]] [mw-parser.simplify :refer [simplify]]
[mw-parser.utils :refer [rule?]] [mw-parser.utils :refer [rule?]]
[trptr.java-wrapper.locale :refer [get-default]]) [trptr.java-wrapper.locale :refer [get-default]])
(:import [java.util Locale])) (:import [java.util Locale]))
@ -144,7 +144,7 @@
([rule-text return-tuple?] ([rule-text return-tuple?]
(assert (string? rule-text)) (assert (string? rule-text))
(let [rule (trim rule-text) (let [rule (trim rule-text)
tree (simplify-rule (parse-rule rule)) tree (simplify (parse-rule rule))
afn (if (rule? tree) (eval (generate tree)) afn (if (rule? tree) (eval (generate tree))
;; else ;; else
(throw-parse-exception tree))] (throw-parse-exception tree))]

View file

@ -1,7 +1,9 @@
(ns ^{:doc "Generate Clojure source from simplified parse trees." (ns ^{:doc "Generate Clojure source from simplified parse trees."
:author "Simon Brooke"} :author "Simon Brooke"}
mw-parser.generate mw-parser.generate
(:require [mw-parser.utils :refer [assert-type TODO]] (:require [clojure.pprint :refer [pprint]]
[clojure.tools.trace :refer [deftrace]]
[mw-parser.utils :refer [assert-type TODO]]
[mw-parser.errors :as pe])) [mw-parser.errors :as pe]))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -23,17 +25,18 @@
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare generate generate-action) (declare generate generate-action)
(defn generate-rule (defn generate-rule
"From this `tree`, assumed to be a syntactically correct rule specification, "From this `tree`, assumed to be a syntactically correct rule specification,
generate and return the appropriate rule as a function of two arguments." generate and return the appropriate rule as a function of two arguments."
[tree] [tree]
(assert-type tree :RULE) (assert-type tree :RULE)
(list 'fn ['cell 'world] (list 'if (generate (nth tree 2)) (generate (nth tree 3))))) (vary-meta
(list 'fn ['cell 'world] (list 'when (generate (nth tree 2)) (generate (nth tree 3))))
merge
{:rule-type
:production}))
(defn generate-conditions (defn generate-conditions
"From this `tree`, assumed to be a syntactically correct conditions clause, "From this `tree`, assumed to be a syntactically correct conditions clause,
@ -42,7 +45,6 @@
(assert-type tree :CONDITIONS) (assert-type tree :CONDITIONS)
(generate (second tree))) (generate (second tree)))
(defn generate-condition (defn generate-condition
"From this `tree`, assumed to be a syntactically correct condition clause, "From this `tree`, assumed to be a syntactically correct condition clause,
generate and return the appropriate clojure fragment." generate and return the appropriate clojure fragment."
@ -50,7 +52,6 @@
(assert-type tree :CONDITION) (assert-type tree :CONDITION)
(generate (second tree))) (generate (second tree)))
(defn generate-conjunct-condition (defn generate-conjunct-condition
"From this `tree`, assumed to be a syntactically conjunct correct condition clause, "From this `tree`, assumed to be a syntactically conjunct correct condition clause,
generate and return the appropriate clojure fragment." generate and return the appropriate clojure fragment."
@ -58,7 +59,6 @@
(assert-type tree :CONJUNCT-CONDITION) (assert-type tree :CONJUNCT-CONDITION)
(cons 'and (map generate (rest tree)))) (cons 'and (map generate (rest tree))))
(defn generate-disjunct-condition (defn generate-disjunct-condition
"From this `tree`, assumed to be a syntactically correct disjunct condition clause, "From this `tree`, assumed to be a syntactically correct disjunct condition clause,
generate and return the appropriate clojure fragment." generate and return the appropriate clojure fragment."
@ -66,7 +66,6 @@
(assert-type tree :DISJUNCT-CONDITION) (assert-type tree :DISJUNCT-CONDITION)
(cons 'or (map generate (rest tree)))) (cons 'or (map generate (rest tree))))
(defn generate-ranged-property-condition (defn generate-ranged-property-condition
"From this `tree`, assumed to be a syntactically property condition clause for "From this `tree`, assumed to be a syntactically property condition clause for
this `property` where the `expression` is a numeric range, generate and return this `property` where the `expression` is a numeric range, generate and return
@ -81,7 +80,6 @@
'upper (list 'max l1 l2)] 'upper (list 'max l1 l2)]
(list 'and (list '>= pv 'lower) (list '<= pv 'upper))))) (list 'and (list '>= pv 'lower) (list '<= pv 'upper)))))
(defn generate-disjunct-property-condition (defn generate-disjunct-property-condition
"From this `tree`, assumed to be a syntactically property condition clause "From this `tree`, assumed to be a syntactically property condition clause
where the expression is a a disjunction, generate and return where the expression is a a disjunction, generate and return
@ -93,11 +91,9 @@
expression (generate (nth tree 3))] expression (generate (nth tree 3))]
(generate-disjunct-property-condition tree property qualifier expression))) (generate-disjunct-property-condition tree property qualifier expression)))
([_tree property qualifier expression] ([_tree property qualifier expression]
(let [e (list 'some (list 'fn ['i] '(= i value)) (list 'quote expression))] (let [e (list expression (list property 'cell))]
(list 'let ['value (list property 'cell)]
(if (= qualifier '=) e (if (= qualifier '=) e
(list 'not e)))))) (list 'not e)))))
(defn generate-property-condition (defn generate-property-condition
"From this `tree`, assumed to be a syntactically property condition clause, "From this `tree`, assumed to be a syntactically property condition clause,
@ -241,7 +237,6 @@
([comp1 quantity property-condition] ([comp1 quantity property-condition]
(generate-neighbours-condition comp1 quantity property-condition 1))) (generate-neighbours-condition comp1 quantity property-condition 1)))
(defn generate-within-condition (defn generate-within-condition
"Generate code for a condition which refers to neighbours within a specified distance. "Generate code for a condition which refers to neighbours within a specified distance.
NOTE THAT there's clearly masses of commonality between this and NOTE THAT there's clearly masses of commonality between this and
@ -265,9 +260,32 @@
:LESS (let [value (generate (nth quantifier 3))] :LESS (let [value (generate (nth quantifier 3))]
(generate-neighbours-condition '< value pc distance)))))) (generate-neighbours-condition '< value pc distance))))))
(defn- generate-disjunct-expression
[tree]
(assert-type tree :DISJUNCT-EXPRESSION)
(try
(set (map generate (rest tree)))
(catch Exception x
(throw
(ex-info
"Failed to compile :DISJUNCT-EXPRESSION"
{:tree tree}
x)))))
;;; Flow rules. A flow rule DOES NOT return a modified world; instead, it
;;; returns a PLAN to modify the world, in the form of a sequence of `flows`.
;;; It is only when the plan is executed that the world is modified.
;;;
;;; so we're looking at something like
;;; (fn [cell world])
;;; (if (= (:state cell) (or (:house cell) :house))
(defn generate-flow (defn generate-flow
[tree] [tree]
(assert-type tree :WITHIN-CONDITION)) (assert-type tree :FLOW-RULE))
;;; Top level; only function anything outside this file (except tests) should
;;; really call.
(defn generate (defn generate
"Generate code for this (fragment of a) parse tree" "Generate code for this (fragment of a) parse tree"
@ -282,7 +300,7 @@
:CONDITIONS (generate-conditions tree) :CONDITIONS (generate-conditions tree)
:CONJUNCT-CONDITION (generate-conjunct-condition tree) :CONJUNCT-CONDITION (generate-conjunct-condition tree)
:DISJUNCT-CONDITION (generate-disjunct-condition tree) :DISJUNCT-CONDITION (generate-disjunct-condition tree)
:DISJUNCT-EXPRESSION (generate (nth tree 2)) :DISJUNCT-EXPRESSION (generate-disjunct-expression tree)
:DISJUNCT-VALUE (generate-disjunct-value tree) :DISJUNCT-VALUE (generate-disjunct-value tree)
:EQUIVALENCE '= :EQUIVALENCE '=
:EXPRESSION (generate (second tree)) :EXPRESSION (generate (second tree))
@ -308,11 +326,3 @@
:WITHIN-CONDITION (generate-within-condition tree) :WITHIN-CONDITION (generate-within-condition tree)
(map generate tree)) (map generate tree))
tree)) tree))
;;; Flow rules. A flow rule DOES NOT return a modified world; instead, it
;;; returns a PLAN to modify the world, in the form of a sequence of `flows`.
;;; It is only when the plan is executed that the world is modified.
;;;
;;; so we're looking at something like
;;; (fn [cell world])
;;; (if (= (:state cell) (or (:house cell) :house))

View file

@ -25,34 +25,38 @@
;;;; ;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(declare simplify-flow simplify-rule) (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)
;; (#{:EQUIVALENCE :COMPARATIVE} (first tree))) tree
;; (coll? (first tree)) (or (simplify-qualifier (first tree))
;; (simplify-qualifier (rest tree)))
;; (coll? tree) (simplify-qualifier (rest tree))
;; :else tree))
(defn simplify-second-of-two (defn simplify-second-of-two
"There are a number of possible simplifications such that if the `tree` has "There are a number of possible simplifications such that if the `tree` has
only two elements, the second is semantically sufficient." only two elements, the second is semantically sufficient."
[tree] [tree]
(if (= (count tree) 2) (simplify-rule (nth tree 1)) tree)) (if (= (count tree) 2) (simplify (nth tree 1)) tree))
;; (defn simplify-quantifier (defn simplify-chained-list
;; "If this quantifier is a number, 'simplifiy' it into a comparative whose operator is '=' "Some parse trees take the form
;; and whose quantity is that number. This is actually more complicated but makes generation easier." `[:X [:Y 1] :NOISE :NOISE [:X [:Y 2] :NOISE :NOISE [:X [:Y 3]]]]`
;; [tree] where what's wanted is `[:X [:Y 1] [:Y 2] [:Y 2]]` -- :DISJUNCT-VALUE is a case
;; (if (number? (second tree)) [:COMPARATIVE '= (second tree)] (simplify-rule (second tree)))) in point. This takes such a parse `tree`, where `branch-tag` is the tag of
the enclosing form and `leaf-tag` is the tag of the form to be collected, and
returns the desired form."
[tree branch-tag leaf-tag]
(cons
(first tree)
(reverse
(loop [chain (rest tree) v '()]
(let [car (first chain)]
(cond (empty? chain) v
(coll? car) (let [caar (first car)]
(cond
(= branch-tag caar) (recur car v)
(= leaf-tag caar) (recur
(rest chain)
(cons (simplify car) v))
:else (recur (rest chain) v)))
:else (recur (rest chain) v)))))))
(defn simplify-rule (defn simplify
"Simplify/canonicalise this `tree`. Opportunistically replace complex fragments with "Simplify/canonicalise this `tree`. Opportunistically replace complex fragments with
semantically identical simpler fragments" semantically identical simpler fragments"
[tree] [tree]
@ -60,19 +64,22 @@
(coll? tree) (coll? tree)
(case (first tree) (case (first tree)
:ACTION (simplify-second-of-two tree) :ACTION (simplify-second-of-two tree)
:ACTIONS (cons (first tree) (simplify-rule (rest tree))) :ACTIONS (cons (first tree) (simplify (rest tree)))
:AND nil
:CHANCE-IN nil :CHANCE-IN nil
:COMPARATIVE (simplify-second-of-two tree) :COMPARATIVE (simplify-second-of-two tree)
:CONDITION (simplify-second-of-two tree) :CONDITION (simplify-second-of-two tree)
:CONDITIONS (simplify-second-of-two tree) :CONDITIONS (simplify-second-of-two tree)
:DISJUNCT-EXPRESSION (simplify-chained-list tree :DISJUNCT-VALUE :VALUE)
:EXPRESSION (simplify-second-of-two tree) :EXPRESSION (simplify-second-of-two tree)
:IN nil
:PROPERTY (simplify-second-of-two tree) :PROPERTY (simplify-second-of-two tree)
:PROPERTY-CONDITION-OR-EXPRESSION (simplify-second-of-two tree) :PROPERTY-CONDITION-OR-EXPRESSION (simplify-second-of-two tree)
:OR nil
:SPACE nil :SPACE nil
:THEN nil :THEN nil
:AND nil
:VALUE (simplify-second-of-two tree) :VALUE (simplify-second-of-two tree)
(remove nil? (map simplify-rule tree))) (remove nil? (map simplify tree)))
tree)) tree))
(defn simplify-determiner-condition (defn simplify-determiner-condition

View file

@ -1,9 +1,10 @@
(ns mw-parser.core-test (ns mw-parser.core-test
(:use clojure.pprint (:require [clojure.test :refer [deftest is testing]]
mw-engine.core [mw-engine.core :refer [transform-world]]
mw-engine.world) [mw-engine.world :refer [make-world]]
(:require [clojure.test :refer :all] [mw-parser.core :refer [compile-rule parse-property-value
[mw-parser.core :refer :all])) parse-rule parse-simple-value
parse-value]]))
(deftest primitives-tests (deftest primitives-tests
(testing "Simple functions supporting the parser" (testing "Simple functions supporting the parser"
@ -357,7 +358,6 @@
(is (nil? (apply afn (list {:x 0 :y 1} world))) (is (nil? (apply afn (list {:x 0 :y 1} world)))
"Left of world is all high, so rule should not fire."))) "Left of world is all high, so rule should not fire.")))
;; 'single action' already tested in 'condition' tests above ;; 'single action' already tested in 'condition' tests above
;; action and actions ;; action and actions
(testing "Conjunction of actions" (testing "Conjunction of actions"

View file

@ -1,57 +1,87 @@
(ns mw-parser.generate-test (ns mw-parser.generate-test
(:use clojure.pprint (:require [clojure.test :refer [deftest is testing]]
mw-engine.core [mw-parser.generate :refer [generate]]))
mw-engine.world
mw-engine.utils
mw-parser.utils)
(:require [clojure.test :refer :all]
[mw-parser.generate :refer :all]))
;; TODO: these tests are badly written and many (all?!?) of them were not
;; actually firing. rewrite ALL to the pattern:
;;
;; (let [actual ...
;; expected ...]
;; (is (= actual expected)))
(deftest expressions-tests (deftest expressions-tests
(testing "Generating primitive expressions." (testing "Generating primitive expressions."
(is (generate '(:NUMERIC-EXPRESSION (:NUMBER "50"))) 50) (is (= (generate '(:NUMERIC-EXPRESSION (:NUMBER "50"))) 50))
(is (generate '(:NUMERIC-EXPRESSION (:SYMBOL "sealevel"))) (is (= (generate '(:NUMERIC-EXPRESSION (:SYMBOL "sealevel")))
'(:sealevel cell)) '(:sealevel cell)))))
))
(deftest lhs-generators-tests (deftest lhs-generators-tests
(testing "Generating left-hand-side fragments of rule functions from appropriate fragments of parse trees" (testing "Generating left-hand-side fragments of rule functions from appropriate fragments of parse trees"
(is (generate (let [expected '(= (:state cell) (or (:forest cell) :forest))
'(:PROPERTY-CONDITION (:SYMBOL "state") [:EQUIVALENCE [:IS "is"]] (:SYMBOL "forest"))) actual (generate
'(= (:state cell) :forest)) '(:PROPERTY-CONDITION
(is (generate (:SYMBOL "state")
[:EQUIVALENCE [:IS "is"]]
(:SYMBOL "forest")))]
(is (= actual expected)))
(is (= (generate
'(:PROPERTY-CONDITION (:SYMBOL "fertility") [:EQUIVALENCE [:IS "is"]] (:NUMBER "10"))) '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:EQUIVALENCE [:IS "is"]] (:NUMBER "10")))
'(= (:fertility cell) 10)) '(= (:fertility cell) 10)))
(is (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:LESS "less"]] (:NUMBER "10"))) (is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:LESS "less"]] (:NUMBER "10")))
'(< (:fertility cell) 10)) '(< (:fertility cell) 10)))
(is (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:MORE "more"]] (:NUMBER "10"))) (is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "fertility") [:COMPARATIVE [:MORE "more"]] (:NUMBER "10")))
'(> (:fertility cell) 10)) '(> (:fertility cell) 10)))
(is (generate '(:CONJUNCT-CONDITION (:PROPERTY-CONDITION (:SYMBOL "state") [:EQUIVALENCE [:IS "is"]] (:SYMBOL "forest")) (:AND "and") (:PROPERTY-CONDITION (:SYMBOL "fertility") [:EQUIVALENCE [:IS "is"]] (:NUMBER "10")))) (is (= (generate '(:CONJUNCT-CONDITION
'(and (= (:state cell) :forest) (= (:fertility cell) 10))) (:PROPERTY-CONDITION
(is (generate '(:DISJUNCT-CONDITION (:PROPERTY-CONDITION (:SYMBOL "state") [:EQUIVALENCE [:IS "is"]] (:SYMBOL "forest")) (:OR "or") (:PROPERTY-CONDITION (:SYMBOL "fertility") [:EQUIVALENCE [:IS "is"]] (:NUMBER "10")))) (:SYMBOL "state")
'(or (= (:state cell) :forest) (= (:fertility cell) 10))) (:QUALIFIER (:EQUIVALENCE (:IS "is")))
(is (generate '(:PROPERTY-CONDITION (:SYMBOL "state") [:EQUIVALENCE [:IS "is"]] (:DISJUNCT-EXPRESSION (:IN "in") (:DISJUNCT-VALUE (:SYMBOL "grassland") (:OR "or") (:DISJUNCT-VALUE (:SYMBOL "pasture") (:OR "or") (:DISJUNCT-VALUE (:SYMBOL "heath"))))))) (:SYMBOL "forest"))
'(let [value (:state cell)] (some (fn [i] (= i value)) (quote (:grassland :pasture :heath))))) (:PROPERTY-CONDITION
(is (generate '(:PROPERTY-CONDITION (:SYMBOL "altitude") [:EQUIVALENCE [:IS "is"]] (:RANGE-EXPRESSION (:BETWEEN "between") (:NUMERIC-EXPRESSION (:NUMBER "50")) (:AND "and") (:NUMERIC-EXPRESSION (:NUMBER "100"))))) (:SYMBOL "fertility")
'(let [lower (min 50 100) upper (max 50 100)] (and (>= (:altitude cell) lower) (<= (:altitude cell) upper)))) (:QUALIFIER (:EQUIVALENCE (:IS "is")))
)) (:NUMBER "10"))))
'(and (= (:state cell) (or (:forest cell) :forest)) (= (:fertility cell) 10))))
(is (= (generate '(:DISJUNCT-CONDITION (:PROPERTY-CONDITION (:SYMBOL "state") (:EQUIVALENCE (:IS "is")) (:SYMBOL "forest")) (:PROPERTY-CONDITION (:SYMBOL "fertility") (:EQUIVALENCE (:IS "is")) (:NUMBER "10"))))
'(or (= (:state cell) (or (:forest cell) :forest)) (= (:fertility cell) 10))))
(is (= (generate '(:PROPERTY-CONDITION
(:SYMBOL "state")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:DISJUNCT-EXPRESSION
(:SYMBOL "heath")
(:SYMBOL "scrub")
(:SYMBOL "forest"))))
'(#{:scrub :forest :heath} (:state cell))))
(is (= (generate '(:PROPERTY-CONDITION (:SYMBOL "altitude") [:EQUIVALENCE [:IS "is"]] (:RANGE-EXPRESSION (:BETWEEN "between") (:NUMERIC-EXPRESSION (:NUMBER "50")) (:AND "and") (:NUMERIC-EXPRESSION (:NUMBER "100")))))
'(let [lower (min 50 100) upper (max 50 100)] (and (>= (:altitude cell) lower) (<= (:altitude cell) upper)))))))
(deftest rhs-generators-tests (deftest rhs-generators-tests
(testing "Generating right-hand-side fragments of rule functions from appropriate fragments of parse trees" (testing "Generating right-hand-side fragments of rule functions from appropriate fragments of parse trees"
(is (generate (is (= (generate
'(:SIMPLE-ACTION (:SYMBOL "state") (:BECOMES "should be") (:SYMBOL "climax"))) '(:SIMPLE-ACTION (:SYMBOL "state") (:BECOMES "should be") (:SYMBOL "climax")))
'(merge cell {:state :climax})) '(merge cell {:state :climax})))
(is (generate (is (= (generate
'(:SIMPLE-ACTION (:SYMBOL "fertility") (:BECOMES "should be") (:NUMBER "10"))) '(:SIMPLE-ACTION (:SYMBOL "fertility") (:BECOMES "should be") (:NUMBER "10")))
'(merge cell {:fertility 10})) '(merge cell {:fertility 10})))))
))
(deftest full-generation-tests (deftest full-generation-tests
(testing "Full rule generation from pre-parsed tree" (testing "Full rule generation from pre-parsed tree"
(is (generate '(:RULE (:IF "if") (:PROPERTY-CONDITION (:SYMBOL "state") [:EQUIVALENCE [:IS "is"]] (:SYMBOL "forest")) (:SIMPLE-ACTION (:SYMBOL "state") (:BECOMES "should be") (:SYMBOL "climax")))) (let [rule '(:RULE
'(fn [cell world] (if (= (:state cell) :forest) (merge cell {:state :climax})))) (:IF "if")
)) (:PROPERTY-CONDITION
(:SYMBOL "state")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:SYMBOL "forest"))
(:ACTIONS
(:SIMPLE-ACTION
(:SYMBOL "state")
(:BECOMES "should be")
(:SYMBOL "climax"))))
expected '(fn [cell world]
(when
(= (:state cell) (or (:forest cell) :forest))
(merge cell {:state :climax})))
actual (generate rule)
expected-meta {:rule-type :production}
actual-meta (meta actual)]
(is (= actual expected))
(is (= actual-meta expected-meta)))))

View file

@ -0,0 +1,98 @@
(ns mw-parser.simplify-test
(:require [clojure.test :refer [deftest is testing]]
[mw-parser.declarative :refer [parse-rule]]
[mw-parser.simplify :refer [simplify]]
[mw-parser.utils :refer [search-tree]]))
((deftest disjunct-condition-test
(testing "Generation of disjunct conditions has been producing wrong
output -- in a way which didn't actually alter the
correctness of the rule -- since the beginning, and because
of inadequate and badly written tests, I didn't know it."
(let [expected '(:DISJUNCT-CONDITION
(:PROPERTY-CONDITION
(:SYMBOL "state")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:SYMBOL "forest"))
(:PROPERTY-CONDITION
(:SYMBOL "fertility")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:NUMBER "10")))
actual (simplify [:DISJUNCT-CONDITION
[:CONDITION
[:PROPERTY-CONDITION
[:PROPERTY [:SYMBOL "state"]]
[:SPACE " "]
[:QUALIFIER [:EQUIVALENCE [:IS "is"]]]
[:SPACE " "]
[:EXPRESSION [:VALUE [:SYMBOL "forest"]]]]]
[:SPACE " "]
[:OR "or"]
[:SPACE " "]
[:CONDITIONS
[:CONDITION
[:PROPERTY-CONDITION
[:PROPERTY [:SYMBOL "fertility"]]
[:SPACE " "]
[:QUALIFIER [:EQUIVALENCE [:IS "is"]]]
[:SPACE " "]
[:EXPRESSION [:VALUE [:NUMBER "10"]]]]]]])]
(is (= actual expected))))))
(deftest conjunct-condition-test
(testing "Conjunct conditions were failing in more or less the same way"
(let [expected '(:CONJUNCT-CONDITION
(:PROPERTY-CONDITION
(:SYMBOL "state")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:SYMBOL "forest"))
(:PROPERTY-CONDITION
(:SYMBOL "fertility")
(:QUALIFIER (:EQUIVALENCE (:IS "is")))
(:NUMBER "10")))
actual (simplify [:CONJUNCT-CONDITION
[:CONDITION
[:PROPERTY-CONDITION
[:PROPERTY [:SYMBOL "state"]]
[:SPACE " "]
[:QUALIFIER [:EQUIVALENCE [:IS "is"]]]
[:SPACE " "]
[:EXPRESSION [:VALUE [:SYMBOL "forest"]]]]]
[:SPACE " "]
[:AND "and"]
[:SPACE " "]
[:CONDITIONS
[:CONDITION
[:PROPERTY-CONDITION
[:PROPERTY [:SYMBOL "fertility"]]
[:SPACE " "]
[:QUALIFIER [:EQUIVALENCE [:IS "is"]]]
[:SPACE " "]
[:EXPRESSION [:VALUE [:NUMBER "10"]]]]]]])]
(is (= actual expected)))))
((deftest unchained-disjuncts-test
(testing "Disjunct values should not be chained"
(let [wrong '(:DISJUNCT-EXPRESSION
(:IN "in")
(:DISJUNCT-VALUE
(:SYMBOL "heath")
(:DISJUNCT-VALUE
(:SYMBOL "scrub")
(:DISJUNCT-VALUE (:SYMBOL "forest")))))
parse-tree (search-tree
(parse-rule
"if state is not in heath or scrub or forest then state should be climax")
:DISJUNCT-EXPRESSION)
actual (simplify parse-tree)]
(is (not (= wrong actual))))
(let [expected '(:DISJUNCT-EXPRESSION
(:SYMBOL "heath")
(:SYMBOL "scrub")
(:SYMBOL "forest"))
parse-tree (search-tree
(parse-rule
"if state is not in heath or scrub or forest then state should be climax")
:DISJUNCT-EXPRESSION)
actual (simplify parse-tree)]
(is (= expected actual))))))