Опция sequential
заставляет команду function
специализировать перекрывающиеся уравнения так, чтобы они больше не перекрывались. Однако это только препроцессор для фактической внутренней конструкции, которая фактически поддерживает перекрывающиеся шаблоны (при условии, что можно доказать, что правые части обозначают одно и то же значение HOL для перекрывающихся экземпляров, то есть они согласованы). Это доказательство согласованности выражается в виде отдельных целей (которые auto
решаются практически всегда, если используется опция sequential
, поскольку достаточно доказать, что они не могут перекрываться). Тем не менее, в числе неоднозначных уравнений есть квадратично много целей. Поэтому, если вы добавите больше конструкторов, перекрывающиеся уравнения будут разбиты на большее количество случаев, и эти случаи приведут к квадратичному числу целей.
Существует два обходных пути, когда функция не является рекурсивной:
Для нерекурсивных функций я рекомендую использовать definition
с выражением case
справа. Затем вы можете использовать simps_of_case
из HOL-Library.Simps_Case_Conv
для получения простых правил. Тем не менее, вы не получите хорошего правила разграничения падежа.
definition simplify :: "'a expr ⇒ 'a expr" where
"simplify e = (case e of And a True => a | And True b => b | ... | _ => e)"
simps_of_case simplify_simps [simp]: simplify_def
Если вы хотите получить хорошие теоремы о различении регистра, вы можете разделить определение функции на несколько вспомогательных функций:
fun simplify_add :: "'a expr => 'a expr => 'a expr" where
"simplify_add a True = a"
| "simplify_add True b = b"
| "simplify_add a b = Add a b"
fun simplify_or (* similarly *)
fun simplify :: "'a expr => 'a expr" where
"simplify (And a b) = simplify_and a b"
| "simplify (Or a b) = simplify_or a b"
| "simplify e = e"
Для рекурсивных функций вы можете избежать взрыва, переместив некоторые различия в регистре справа. Например:
fun simplify :: "'a expr ⇒ 'a expr" where
"simplify (And a b) = (case b of True => a | _ => case a of True => b | _ => And a b)"
| ...
Опять же, это значительно уменьшает количество уравнений после того, как они не перекрываются, но вы больше не получаете одни и те же правила разграничения (и правила индукции).