Я сталкиваюсь с тем, что, по моему мнению, может быть ошибкой в Coq 8.4pl5. Учитывая это состояние доказательства:

1 subgoal

st : state
a : sinstr
a0 : list sinstr
b : list sinstr
IHa : forall stack : list nat,
      s_execute st stack (a0 ++ b) = s_execute st (s_execute st stack a0) b
stack : list nat

======================== ( 1 / 1 )
s_execute st stack ((a :: a0) ++ b) =
s_execute st (s_execute st stack (a :: a0)) b

Coq разрешает мне apply IHa. Когда я это делаю, цель достигается и теорема доказывается.

Это неправильная унификация (я думаю, что это так), и если да, то сообщалось ли об этой проблеме?

Если нет, как я могу сообщить об этом? Я знаю, что Coq используется в программном обеспечении с высоким уровнем гарантии, и я считаю, что, хотя это не последняя версия, это не особенно старая версия. Таким образом, даже если это будет исправлено в более поздних версиях, было бы хорошо убедиться, что люди знают, что эта проблема действительно существует в этой версии Coq.

Для справки, я сузил код до этого (я не пытался сузить его еще больше, потому что не совсем понимаю, что может вызывать это). Рассматриваемый apply находится в предпоследней строке (со всеми звездочками в комментарии):

(** aexp **)
Require Import Coq.Arith.Peano_dec.

Inductive id : Type :=
| Id : nat -> id.

Theorem eq_id_dec : forall a b : id,
  {a = b} + {a <> b}.
Proof.
  intros.
  case_eq a.
  case_eq b.
  intros.
  destruct (eq_nat_dec n0 n).
    left. auto.
    right. unfold not. intros. inversion H1. contradiction.
Qed.


Definition state : Type := id -> nat.

Definition empty_state : state :=
  fun _ => 0.

Definition update (st : state) (i : id) (v : nat) : state :=
  fun j => if eq_id_dec j i
            then v
            else st j.

Inductive aexp : Type :=
  | AId : id -> aexp
  | ANum : nat -> aexp
  | APlus : aexp -> aexp -> aexp
  | AMinus : aexp -> aexp -> aexp
  | AMult : aexp -> aexp -> aexp.

Fixpoint aeval (a : aexp) (st : state) : nat :=
  match a with
  | AId i => st i
  | ANum n => n
  | APlus x y => aeval x st + aeval y st
  | AMinus x y => aeval x st - aeval y st
  | AMult x y => aeval x st * aeval y st
  end.

(** Stack compiler **)

Require Import List.
Import ListNotations.


Inductive sinstr : Type :=
| SPush : nat -> sinstr
| SLoad : id -> sinstr
| SPlus : sinstr
| SMinus : sinstr
| SMult : sinstr.

Fixpoint s_execute (st : state) (stack : list nat) (prog : list sinstr)
    : list nat :=
  match prog with
  | nil => stack
  | cons x xs =>
      let stack' := match x with
      | SPush a => cons a stack
      | SLoad v => cons (st v) stack
      | SPlus   => match stack with
                   | cons a (cons b rest) => cons (b + a) rest
                   | _ => [27]
                   end
      | SMinus  => match stack with
                   | cons a (cons b rest) => cons (b - a) rest
                   | _ => [27]
                   end
      | SMult   => match stack with
                   | cons a (cons b rest) => cons (b * a) rest
                   | _ => [27]
                   end
      end
      in
      s_execute st stack' xs
  end.


Fixpoint s_compile (e : aexp) : list sinstr :=
  match e with
  | AId i => [ SLoad i ]
  | ANum n => [ SPush n ]
  | APlus a b => (s_compile a) ++ (s_compile b) ++ [ SPlus ]
  | AMinus a b => (s_compile a) ++ (s_compile b) ++ [ SMinus ]
  | AMult a b => (s_compile a) ++ (s_compile b) ++ [ SMult ]
  end.

Lemma s_execute_app : forall st stack a b,
  s_execute st stack (a ++ b) = s_execute st (s_execute st stack a) b.
Proof.
  intros.
  generalize dependent stack.
  induction a ; try reflexivity.
    intros.
    apply IHa. (***********************)
Qed.
0
David 24 Фев 2016 в 22:57

2 ответа

Лучший ответ

Если вы сделаете simpl после введения, вы увидите, что гипотеза и цель могут объединиться:

 s_execute st
     match a with
     | SPush a1 => a1 :: stack
     | SLoad v => st v :: stack
     | SPlus =>
         match stack with
         | [] => [27]
         | [a1] => [27]
         | a1 :: b0 :: rest => b0 + a1 :: rest
         end
     | SMinus =>
         match stack with
         | [] => [27]
         | [a1] => [27]
         | a1 :: b0 :: rest => b0 - a1 :: rest
         end
     | SMult =>
         match stack with
         | [] => [27]
         | [a1] => [27]
         | a1 :: b0 :: rest => b0 * a1 :: rest
         end
     end (a0 ++ b) =
   s_execute st
     (s_execute st
        match a with
        | SPush a1 => a1 :: stack
        | SLoad v => st v :: stack
        | SPlus =>
            match stack with
            | [] => [27]
            | [a1] => [27]
            | a1 :: b0 :: rest => b0 + a1 :: rest
            end
        | SMinus =>
            match stack with
            | [] => [27]
            | [a1] => [27]
            | a1 :: b0 :: rest => b0 - a1 :: rest
            end
        | SMult =>
            match stack with
            | [] => [27]
            | [a1] => [27]
            | a1 :: b0 :: rest => b0 * a1 :: rest
            end
        end a0) b
4
Arthur Azevedo De Amorim 24 Фев 2016 в 20:22

Хотя вы, возможно, не захотите сообщать об этой конкретной проблеме, благодаря анализу Артура, если вы хотите связаться с разработчиками Coq, они находятся в списках рассылки Coq-club и Coq-dev. Увидеть

https://coq.inria.fr/community

Для архивов и дополнительной информации. Существует также система отслеживания ошибок Coq-bugs, которую вы можете использовать.

1
larsr 25 Фев 2016 в 06:12