Завершение доказательства с помощью Qed.
делает доказательство непрозрачным. Иногда это то, что вам нужно, но если вам когда-нибудь понадобится вычислительный контент доказательства, вы должны закончить его Defined.
.
Это должно работать, поскольку теперь D
можно развернуть.
Inductive Id (A : Type) (x : A) : A -> Type :=
| refl : Id A x x.
(* trivial with induction *)
Theorem symId {A} {x y} : Id A x y -> Id A y x.
Proof.
intros.
induction H.
apply refl.
Qed.
Check Id_ind.
(* Id_ind *)
(* : forall (A : Type) (x : A) (P : forall a : A, Id A x a -> Prop), *)
(* P x (refl A x) -> forall (y : A) (i : Id A x y), P y i *)
Theorem D {A} (x y : A) : Id A x y -> Prop.
Proof.
intros.
apply (Id A y x).
Defined.
Theorem d {A} (x : A) : D x x (refl A x).
Proof.
apply refl.
Qed.
Что касается других ваших вопросов. Вы можете явно использовать индукцию двумя способами. Одним из них является использование Id_rect
, Id_rec
или Id_ind
(они автоматически объявляются при определении Id
). Например,
Definition Id_sym {A: Type} {x y: A}: Id A x y -> Id A y x :=
Id_ind A x (fun y' _ => Id A y' x) (refl A x) y.
(использование некоторых неявных аргументов может облегчить чтение).
В конечном итоге это преобразуется в оператор сопоставления, так что вы также можете использовать его.
Definition Id_sym' {A: Type} {x y: A} (p: Id A x y): Id A y x :=
match p with
| refl _ _ => refl _ _
end.
Чтобы объявить локальную переменную в определении, вы можете использовать форму let var := term in term
. Например, Id_sym
выше можно переписать как
Definition Id_sym'' {A: Type} {x y: A}: Id A x y -> Id A y x :=
let P := (fun y' _ => Id A y' x) in
Id_ind A x P (refl A x) y.