Изабель нужно много времени, чтобы доказать правильность (на мой взгляд) довольно простых функций преобразования типов данных. В качестве примера я создал типы данных для представления математических и логических выражений и функцию, которая упрощает такое выражение.
datatype 'a math_expr =
Num int |
Add "'a math_expr" "'a math_expr" |
Mul "'a math_expr" "'a math_expr" |
Sub "'a math_expr" "'a math_expr" |
Div "'a math_expr" "'a math_expr"
datatype 'a expr =
True |
False |
And "'a expr" "'a expr" |
Or "'a expr" "'a expr" |
Eq "'a math_expr" "'a math_expr" |
Ne "'a math_expr" "'a math_expr" |
Lt "'a math_expr" "'a math_expr" |
Le "'a math_expr" "'a math_expr" |
Gt "'a math_expr" "'a math_expr" |
Ge "'a math_expr" "'a math_expr" |
If "'a expr" "'a expr" "'a expr"
function (sequential) simplify :: "'a expr ⇒ 'a expr" where
"simplify (And a True) = a" |
"simplify (And True b) = b" |
"simplify (Or a True) = True" |
"simplify (Or True b) = True" |
"simplify e = e"
by pat_completeness auto
termination by lexicographic_order
В моем блокноте Изабель требуется довольно много времени, чтобы проверить функцию (подпись и текст выделены) и еще больше времени, чтобы подтвердить ее полноту (выделено by pat_completeness auto
). Необходимое время вычислений сильно зависит от сложности типа данных expr
и количества правил сопоставления с образцом в simplify
. Чем больше конструкторов в типе данных и чем больше правил сопоставления с образцом, тем больше времени это занимает.
В чем причина такого поведения? Есть ли способ упростить доказуемость такой функции?