Есть три случая, которые действительно подозрительны:
| Simplify (Or (x, y)) = (Simplify (Or (Simplify x, Simplify y)))
| Simplify (And (x, y)) = (Simplify (And (Simplify x, Simplify y)))
| Simplify (Not(x)) = (Simplify (Not (Simplify x)))
В принципе, если x и y не могут быть упрощены в дальнейшем, Simplify x
и Simplify y
вернут x
и y
,Таким образом, вы будете вызывать Simplify с тем же вводом, что и раньше (Or(x, y)
, And(x, y)
или Not x
).Вы можете проверить, что ваша функция не заканчивается некоторыми примерами, такими как: And(And(Var "x", Var "y"), Var "z")
и Not(And(Var "x", Var "y")
.
Идея упрощения заключается в том, что у вас есть True
или False
во внутреннем предложении,Вы хотите распространить это на внешние уровни.Обратите внимание, что вы не будете пытаться упростить, если x и y неприводимы.
ОБНОВЛЕНИЕ:
Ваша функция может быть исправлена следующим образом:
fun Simplify (Or(True, _)) = True
| ... (* Keep other cases as before *)
| Simplify (Or (x, y)) = (case Simplify x of
True => True
| False => Simplify y
| x' => (case Simplify y of
True => True
| False => x'
| y' => Or(x', y')))
| Simplify (And (x, y)) = (case Simplify x of
False => False
| True => Simplify y
| x' => (case Simplify y of
False => False
| True => x'
| y' => And(x', y')))
| Simplify (Not x) = case Simplify x of
True => False
| False => True
| x' => Not x'
ОБНОВЛЕНИЕ 2:
Я думаю, что вы пытались использовать нисходящий подход, который не совсем подходит.Я переписываю функцию, используя восходящий подход, чтобы сделать ее короче и более удобочитаемой:
fun Simplify True = True
| Simplify False = False
| Simplify (Var x) = Var x
| Simplify (Not x) = (case Simplify x of
True => False
| False => True
| x' => Not x')
| Simplify (And(x, y)) = (case Simplify x of
False => False
| True => Simplify y
| x' => (case Simplify y of
False => False
| True => x'
| y' => And(x', y')))
| Simplify (Or(x, y)) = (case Simplify x of
True => True
| False => Simplify y
| x' => (case Simplify y of
True => True
| False => x'
| y' => Or(x', y')))