允许看起来应该统一的申请

时间:2016-02-24 19:57:38

标签: coq unification

我遇到了我认为可能是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.

2 个答案:

答案 0 :(得分:4)

如果您在介绍后 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 ,您会看到假设和目标可以统一:

#!/usr/bin/env python

# save top 10 google image search results to current directory
# https://developers.google.com/custom-search/json-api/v1/using_rest

import requests
import os
import sys
import re
import shutil

url = 'https://www.googleapis.com/customsearch/v1?key={}&cx={}&searchType=image&q={}'
apiKey = os.environ['GOOGLE_IMAGE_APIKEY']
cx = os.environ['GOOGLE_CSE_ID']
q = sys.argv[1]

i = 1
for result in requests.get(url.format(apiKey, cx, q)).json()['items']:
  link = result['link']
  image = requests.get(link, stream=True)
  if image.status_code == 200:
    m = re.search(r'[^\.]+$', link)
    filename = './{}-{}.{}'.format(q, i, m.group())
    with open(filename, 'wb') as f:
      image.raw.decode_content = True
      shutil.copyfileobj(image.raw, f)
    i += 1

答案 1 :(得分:1)

虽然您可能不想报告此特定问题,但感谢Arthur的分析,如果您想联系Coq开发人员,他们会在Coq-club和Coq-dev邮件列表上闲逛。见

https://coq.inria.fr/community

有关档案和更多信息。 还有一个可以使用的错误跟踪系统Coq-bugs。