Fix negation.
authorEugen Sawin <sawine@me73.com>
Tue, 17 May 2011 18:00:34 +0200
changeset 14719b6a84938f
parent 13 7e15db592010
child 15 fa6d6a2cefe4
Fix negation.
sml.py
     1.1 --- a/sml.py	Tue May 17 16:11:11 2011 +0200
     1.2 +++ b/sml.py	Tue May 17 18:00:34 2011 +0200
     1.3 @@ -15,7 +15,7 @@
     1.4      formula1 = Imp([Eq([p, q]), r])
     1.5      formula2 = Not([Or([p, q])])
     1.6      formula3 = Not([Not([p])])
     1.7 -    use = formula1
     1.8 +    formula =  formula1
     1.9  
    1.10      args = parse_arguments()
    1.11      if (args.formula):
    1.12 @@ -28,25 +28,54 @@
    1.13          tree = SyntaxTree(out, tree_nodes) 
    1.14          formula = tree.root
    1.15     
    1.16 -    print formula
    1.17 -    print "reduced"
    1.18 -    print reduce(formula)
    1.19 -    print reduce(formula)
    1.20 +    print "formula: \t\t", formula
    1.21 +    print "expanded -> and <->: \t", expand_imp_eq(formula)
    1.22 +    print "reduced ~: \t\t", reduce_not(expand_imp_eq(formula))
    1.23  
    1.24 -def reduce(formula):  
    1.25 +def expand_imp_eq(formula):  
    1.26      map = {IMP: lambda (a, b): Or([Not([a]), b]),
    1.27 -           EQ: lambda (a, b): And([Or([Not([a]), b]), Or([a, Not([b])])]),
    1.28 -           NOT: lambda (a,): not isinstance(a, Not) 
    1.29 -           and not isinstance(a.values[0], Not) 
    1.30 -           and a.__class__([Not([v]) for v in a.values]) or a.values[0],
    1.31 -           AND: lambda (a, b): And([a, b]), 
    1.32 -           OR: lambda (a, b): Or([a, b])}
    1.33 +           EQ: lambda (a, b): And([Or([Not([a]), b]), Or([a, Not([b])])])}
    1.34 +
    1.35      def values():       
    1.36 -        return [reduce(v) for v in formula.values] 
    1.37 +        return [expand_imp_eq(v) for v in formula.values] 
    1.38  
    1.39      if not isinstance(formula, Operator) or formula.id not in map:       
    1.40          return formula
    1.41 -    return map[formula.id](values())    
    1.42 +    return map[formula.id](values())   
    1.43 +
    1.44 +def reduce_not(formula):  
    1.45 +    negmap = {AND: lambda (a, b): Or([negate(a), negate(b)]),
    1.46 +              OR: lambda (a, b): And([negate(a), negate(b)]),
    1.47 +              VARIABLE: lambda (a,): Not([a]),
    1.48 +              NOT: lambda (a,): a}
    1.49 +
    1.50 +    def values():
    1.51 +        return [reduce_not(v) for v in formula.values]
    1.52 +
    1.53 +    def negate(f):
    1.54 +         return negmap[f.id](f.values)
    1.55 +
    1.56 +    if not isinstance(formula, Operator):
    1.57 +        return formula   
    1.58 +    if formula.id == NOT:
    1.59 +        return negate(formula.values[0])
    1.60 +    return formula.__class__(values())
    1.61 +
    1.62 +
    1.63 +
    1.64 +
    1.65 +    map = {NOT: lambda (a,): not isinstance(a, Not) 
    1.66 +           and not isinstance(a.values[0], Not) 
    1.67 +           and a.__class__([Not([reduce2(v)]) for v in a.values]) or a.values[0]}
    1.68 +
    1.69 +    def values(): 
    1.70 +        return [reduce2(v) for v in formula.values] 
    1.71 +
    1.72 +    if not isinstance(formula, Operator) or not isinstance(formula.values[0], Operator):
    1.73 +        return formula 
    1.74 +    elif formula.id not in map: 
    1.75 +        return formula.__class__(values())
    1.76 +    return map[formula.id](values())   
    1.77   
    1.78  NOT = "~"
    1.79  AND = "&"
    1.80 @@ -55,7 +84,7 @@
    1.81  EQ = "<->"
    1.82  BOX = "[]"
    1.83  DIAMOND = "<>"
    1.84 -VARIABLE = "p"
    1.85 +VARIABLE = "VAR"
    1.86  LB = "("
    1.87  RB = ")"
    1.88