001  (ns ^{:doc "Simplify a parse tree."
                
                002        :author "Simon Brooke"}
                
                003   mw-parser.simplify)
                
                004  
                
                005  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                
                006  ;;;;
                
                007  ;;;; mw-parser: a rule parser for MicroWorld.
                
                008  ;;;;
                
                009  ;;;; This program is free software; you can redistribute it and/or
                
                010  ;;;; modify it under the terms of the GNU General Public License
                
                011  ;;;; as published by the Free Software Foundation; either version 2
                
                012  ;;;; of the License, or (at your option) any later version.
                
                013  ;;;;
                
                014  ;;;; This program is distributed in the hope that it will be useful,
                
                015  ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
                
                016  ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                
                017  ;;;; GNU General Public License for more details.
                
                018  ;;;;
                
                019  ;;;; You should have received a copy of the GNU General Public License
                
                020  ;;;; along with this program; if not, write to the Free Software
                
                021  ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
                
                022  ;;;; USA.
                
                023  ;;;;
                
                024  ;;;; Copyright (C) 2014 Simon Brooke
                
                025  ;;;;
                
                026  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                
                027  
                
                028  (declare simplify-flow simplify-rule)
                
                029  
                
                030  ;; (defn simplify-qualifier
                
                031  ;;   "Given that this `tree` fragment represents a qualifier, what
                
                032  ;;   qualifier is that?"
                
                033  ;;   [tree]
                
                034  ;;   (cond
                
                035  ;;     (empty? tree) nil
                
                036  ;;     (and (coll? tree)
                
                037  ;;          (#{:EQUIVALENCE :COMPARATIVE} (first tree))) tree
                
                038  ;;     (coll? (first tree)) (or (simplify-qualifier (first tree))
                
                039  ;;                              (simplify-qualifier (rest tree)))
                
                040  ;;     (coll? tree) (simplify-qualifier (rest tree))
                
                041  ;;     :else tree))
                
                042  
                
                043  (defn simplify-second-of-two
                
                044    "There are a number of possible simplifications such that if the `tree` has
                
                045    only two elements, the second is semantically sufficient."
                
                046    [tree]
                
                047    (if (= (count tree) 2) (simplify-rule (nth tree 1)) tree))
                
                048  
                
                049  ;; (defn simplify-quantifier
                
                050  ;;   "If this quantifier is a number, 'simplifiy' it into a comparative whose operator is '='
                
                051  ;;   and whose quantity is that number. This is actually more complicated but makes generation easier."
                
                052  ;;   [tree]
                
                053  ;;   (if (number? (second tree)) [:COMPARATIVE '= (second tree)] (simplify-rule (second tree))))
                
                054  
                
                055  (defn simplify-rule
                
                056    "Simplify/canonicalise this `tree`. Opportunistically replace complex fragments with
                
                057    semantically identical simpler fragments"
                
                058    [tree]
                
                059    (if
                
                060     (coll? tree)
                
                061      (case (first tree)
                
                062        :ACTION (simplify-second-of-two tree)
                
                063        :ACTIONS (cons (first tree) (simplify-rule (rest tree)))
                
                064        :CHANCE-IN nil
                
                065        :COMPARATIVE (simplify-second-of-two tree)
                
                066        :CONDITION (simplify-second-of-two tree)
                
                067        :CONDITIONS (simplify-second-of-two tree)
                
                068        :EXPRESSION (simplify-second-of-two tree)
                
                069        :PROPERTY (simplify-second-of-two tree)
                
                070        :PROPERTY-CONDITION-OR-EXPRESSION (simplify-second-of-two tree)
                
                071        :SPACE nil
                
                072        :THEN nil
                
                073        :AND nil
                
                074        :VALUE (simplify-second-of-two tree)
                
                075        (remove nil? (map simplify-rule tree)))
                
                076      tree))
                
                077  
                
                078  (defn simplify-determiner-condition
                
                079    [tree]
                
                080    (apply vector
                
                081           (cons :DETERMINER-CONDITION
                
                082                 (cons
                
                083                  (simplify-second-of-two (second tree))
                
                084                  (rest (rest tree))))))