I'm trying to examine how the type checker works on the following function, but can't understand
how the type checker works in the second (the nested) match
clause:
Definition plus_O_2 :=
(fix F (m : mynat) : m == plus m O :=
match m as m0 with
| O as m2 => myeq_refl O : m2 == plus m2 O
| S x as m2 => ((match F x in (m0 == m1) return (S m0 == S m1) with
| myeq_refl x0 => myeq_refl (S x0)
end) : m2 == plus m2 O)
end) : forall n : mynat, n == plus n O.
This is a function that provides proof that forall n : mynat, n == plus n O
, where mynat
, ==
, plus
are self-defined natural numbers, equality, and addition:
Inductive mynat :=
| O
| S (x:mynat).
Fixpoint plus (a b:mynat) :=
match a with
| O => b
| S n => S (plus n b)
end.
Inductive myeq {X:Type} : X -> X -> Prop :=
| myeq_refl : forall x, myeq x x.
Notation "x == y" := (myeq x y)
(at level 70, no associativity)
: type_scope.
(The definition for myeq
and the corresponding Notation
statement was referenced from Software Foundations Vol.1, https://softwarefoundations.cis.upenn.edu/lf-current/ProofObjects.html).
What I'm trying to understand is how Coq manages to type check this function. Here's what I understand of now:
F
first receivesm
. It is expected to return a value of typem == plus m O
(The proposition we want to show).m
passes through pattern matching.- If
m
isO
(meant to represent zero), it returnsmyeq_refl O
.myeq_refl O
has typeO == O
. Meanwhile, fromF
's definition, it is expected to have typeO == plus O O
. (My guess is that,) Coq compares these types while type checking, and notices thatplus O O
is equivalent toO
by its definition, so it passes the type check.
- If
m
is of formS x
, a second pattern matching starts running.F x
will have the formx == plus x O
. This structure is captured in thein
clause, and thereturn
clause specifies that the returning type will beS x == S (plus x O)
.- (I don't understand what happens here)
- If
- Since both patterns end up with the type
m == plus m O
, the function has the typeforall n : mynat, n == plus n O
.
Now, my questions are, what exactly happens with the type checker in where I wrote "I don't understand what happens here?" Particularly,
- In my understanding, as the
in
clause specifies,F x
is expected to have the typem0 == m1
. Meanwhile, the matching clausemyeq_refl x0
seems to have the typex0 == x0
, where both sides are equal. Why does Coq's type checker match these two seemingly different types? - After the match (after
=>
), thematch
clause outputsmyeq_refl (S x0)
, which should have typeS x0 == S x0
. Meanwhile, thereturn
clause stipulates that the returning type should beS m0 == S m1
, which in my understanding should be equivalent toS x == S (plus x O)
. These types, at first glance, seem different. How does Coq find out that these types are in fact equivalent?- Particularly, the second type seems to have a more complicated structure than the original proposition we want to show,
n == plus n O
, which should mean that Coq should not immediately be able to find that this is in fact equivalent ton == n
.
- Particularly, the second type seems to have a more complicated structure than the original proposition we want to show,