On a logical level, you can use the case
syntax to deconstruct the datatype (i.e. case A of mat a b c d ⇒ …
). You can also define your own projection functions using fun
or primrec
, e.g.
primrec foo1 where "foo1 (mat a b c d) = a"
In a proof, you can access the values using obtain
and the cases
command, e.g.
obtain a b c d where "A = mat a b c d" by (cases A) auto
As for your questions about definitions, you can make local definitions in Isar proofs like this:
define A where "A = mat a b c d"
and you can then unfold that definition using the theorem A_def
.
If you want to use your definition in the premises or goal already (and have it unfolded in the theorem after proving it), you can use defines
:
lemma
defines "A ≡ mat a b c d"
shows …
Again, this gives you a fact A_def
that you can use to unfold the definition.
You can also use let ?A = mat a b c d
or pattern matching with is
to introduce abbreviations. In contrast to the definitions from before, these are only on the syntactic level, i.e. you type ?A
, but after parsing, you have mat a b c d
, and you will also see mat a b c d
in the output. is
works like this:
lemma
shows "P (mat a b c d)" (is "P ?A")
proof -
term ?A
It also works after "assumes".