1

Is it possible in Isabelle to access the individual elements of a data type? Let's say I have the following data type:

datatype foo = mat int int int int 

and (e.g. in a lemma)

fixes A :: foo

Is it possible to access the single elements of A? Or alternatively, fix the single elements (fix a b c d :: int) and then define A as mat a b c d?

Benedikt
  • 67
  • 4

2 Answers2

1

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".

Manuel Eberl
  • 7,858
  • 15
  • 24
1

Alternatively it is possible to define custom extractor functions when specifying a data type. In your case, for example

datatype foo = Mat (mat_a : int) (mat_b : int) (mat_c : int) (mat_d : int)

would work.

Then you can access the first element of a foo value x by mat_a x, the second by mat_b x, and so on.

Example:

 value "mat_a (Mat 1 2 3 4)"

"1" :: "int"

chris
  • 4,988
  • 20
  • 36