Когда у вас есть такое равенство, обычно самый быстрый путь к go - это использование inversion
tacti c, которое будет более или менее использовать инъекцию конструкторов.
Lemma foo :
forall (a b : nat),
Some a = Some b ->
a = b.
Proof.
intros a b e. inversion e. reflexivity.
Qed.
Однако случай Some
достаточно особенный, поэтому вы можете написать его по-другому (особенно если вы хотите прочитать сгенерированное доказательство). Вы можете написать некоторую get функцию для option
, используя значение по умолчанию:
Definition get_opt_default {A : Type} (x : A) (o : option A) :=
match o with
| Some a => a
| None => x
end.
Так что get_opt_default x (Some a) = a
. Теперь, используя f_equal (get_opt_default a)
на равенстве Some a = Some b
, вы получите
get_opt_default a (Some a) = get_opt_default a (Some b)
, который упрощается до
a = b
Lemma Some_inj :
forall A (a b : A),
Some a = Some b ->
a = b.
Proof.
intros a b e.
apply (f_equal (get_opt_default a)) in e.
cbn in e.
exact e.
Qed.
Это то, что можно сделать в целом. По сути, вы пишете экстрактор для вашего значения как функцию и применяете его к обеим сторонам равенства. Вычислением он даст ожидаемый результат.