I'm trying to define a conjunction function for 4-valued logic (false, true, null, and error):
datatype 'a maybe = Just "'a" | Nothing | Error
type_synonym bool4 = "bool maybe"
abbreviation JF :: "bool4" where "JF ≡ Just False"
abbreviation JT :: "bool4" where "JT ≡ Just True"
abbreviation BN :: "bool4" where "BN ≡ Nothing"
abbreviation BE :: "bool4" where "BE ≡ Error"
fun and4 :: "bool4 ⇒ bool4 ⇒ bool4" where
"and4 JF b = JF"
| "and4 a JF = JF"
| "and4 BE b = BE"
| "and4 a BE = BE"
| "and4 BN b = BN"
| "and4 a BN = BN"
| "and4 a b = JT"
I expect that the first patterns have a priority over the last patterns.
It seems that the definition is wrong. I'm trying to evaluate the following expressions:
value "and4 JF b"
value "and4 a JF"
The first one returns JF as expected. But the second one can't be simplified.
As result I can't prove commutativity of the conjunction:
lemma and4_commut:
"and4 a b = and4 b a"
It's recomended to use function
instead of fun
in "Defining Recursive Functions in Isabelle/HOL" by Alexander Krauss. But I get 12 false subgoals:
function and4 :: "bool4 ⇒ bool4 ⇒ bool4" where
"and4 JF b = JF"
| "and4 a JF = JF"
| "and4 BE b = BE"
| "and4 a BE = BE"
| "and4 BN b = BN"
| "and4 a BN = BN"
| "and4 a b = JT"
apply pat_completeness
apply auto
I guess it's because the function has conflicting patterns. For example, and4 JF BE
are matched by the 1st and 4th patterns. And the result of conjuction could be either JF or BE.
What is a right way to define such a functions? And how to prove its commutativity? I can use a case of
construction but it complicates the function definition.