I’m creating logic simplification program in sml. But I have a problem for this input:
- Or(Or(Var"x", Var"y"), Var"z");
val it = Or (Or (Var #,Var #),Var "z") : formula
- Simplify it;
And it’s in an infinite loop.
Here is my code:
fun Simplify (Or(True, _)) = True
| Simplify (Or(_, True)) = True
| Simplify (Or(False, False)) = False
| Simplify (Or(x, False)) = (Simplify x)
| Simplify (Or(False, x)) = (Simplify x)
| Simplify (Or (Var (x), Var (y))) = Or (Var (x), Var (y))
| Simplify (Or (x, y)) = (Simplify (Or (Simplify x, Simplify y)))
| Simplify (And(_, False)) = False
| Simplify (And(False, _)) = False
| Simplify (And(True, True)) = True
| Simplify (And(True, x)) = (Simplify x)
| Simplify (And(x, True)) = (Simplify x)
| Simplify (And(Var (x), Var(y))) = And (Var (x), Var (y))
| Simplify (And (x, y)) = (Simplify (And (Simplify x, Simplify y)))
| Simplify (Not(Not(x))) = (Simplify x)
| Simplify (Not(True)) = False
| Simplify (Not(False)) = True
| Simplify (Not(Var (x))) = (Not (Var x))
| Simplify (Not(x)) = (Simplify (Not (Simplify x)))
| Simplify True = True
| Simplify False = False
| Simplify (Var(x)) = Var(x);
There are three cases which are really suspicious:
Basically, if x and y couldn’t be simplified further,
Simplify xandSimplify ywill returnxandy. So you will invoke Simplify with the same input as before (Or(x, y),And(x, y)orNot x). You can test that your function doesn’t terminate with some examples such as:And(And(Var "x", Var "y"), Var "z")andNot(And(Var "x", Var "y").The idea of simplification is that you have
TrueorFalsein an inner clause, you want to propagate it to outer levels. Note that you will not try to simplify if x and y are irreducible.UPDATE:
Your function could be fixed as follows:
UPDATE 2:
I think you tried to use top-down approach which is not really appropriate. I rewrite the function using bottom-up approach to make it shorter and more readable: