Изменение вектора в Coq

#coq

#coq

Вопрос:

Я пытаюсь изменить вектор в Coq. Моя реализация заключается в следующем:

 Fixpoint vappend {T : Type} {n m} (v1 : vect T n) (v2 : vect T m)  : vect T (plus n m) :=  match v1 in vect _ n return vect T (plus n m) with  | vnil =gt; v2  | x ::: v1' =gt; x ::: (vappend v1' v2)  end.  Theorem plus_n_S : forall n m, plus n (S m) = S (plus n m). Proof.  intros. induction n; auto.  - simpl. rewrite lt;- IHn. auto. Qed.  Theorem plus_n_O : forall n, plus n O = n. Proof.  induction n.  - reflexivity.  - simpl. rewrite IHn. reflexivity. Qed.  Definition vreverse {T : Type} {n} (v : vect T n) : vect T n.  induction v.  - apply [[]].  - rewrite lt;- plus_n_O. simpl. rewrite lt;- plus_n_S.  apply (vappend IHv (t ::: [[]])).  Show Proof. Defined.  

Проблема в том, что когда я пытаюсь вычислить функцию, она выдает что-то вроде:

 match plus_n_O (S (S O)) in (_ = y) return (vect nat y) with ...  

и не смог продвинуться дальше. В чем здесь проблема? Как я могу это исправить?

Комментарии:

1. Какое именно выражение вы пытаетесь вычислить?

2. На самом деле любое выражение, которое не является пустым, например O ::: O ::: [[]]

Ответ №1:

Проблема в том, что ваши функции используют непрозрачные доказательства, plus_n_S и plus_n_O . Чтобы вычислить vreverse , вам нужно вычислить эти доказательства, и если они непрозрачны, вычисление будет заблокировано.

Вы можете устранить эту проблему, прозрачно определив функции. Лично я предпочитаю при этом не использовать режим доказательства, так как легче видеть, что происходит. (Здесь я использовал определение векторов в стандартной библиотеке.)

 Require Import Coq.Vectors.Vector. Import VectorNotations.  Fixpoint vappend {T : Type} {n m} (v1 : t T n) (v2 : t T m)  : t T (plus n m) :=  match v1 in t _ n return t T (plus n m) with  | [] =gt; v2  | x :: v1' =gt; x :: vappend v1' v2  end.  Fixpoint plus_n_S n m : n   S m = S (n   m) :=  match n with  | 0 =gt; eq_refl  | S n =gt; f_equal S (plus_n_S n m)  end.  Fixpoint plus_n_O n : n   0 = n :=  match n with  | 0 =gt; eq_refl  | S n =gt; f_equal S (plus_n_O n)  end.  Fixpoint vreverse {T : Type} {n} (v : t T n) : t T n :=  match v in t _ n return t T n with  | [] =gt; []  | x :: v =gt;  eq_rect _ (t T)  (eq_rect _ (t T) (vappend (vreverse v) [x]) _ (plus_n_S _ 0))  _ (f_equal S ( plus_n_O _))  end.  Compute vreverse (1 :: 2 :: 3 :: []).