Coq 局部归纳定义与定理

Coq 局部归纳定义与定理,coq,Coq,我在一些证明中使用了两个归纳的定义作为反例。不过,我想将这些定义封装在部分中。可以使用Let隐藏常规定义,但是对于归纳定义也可以这样做吗?那么定理s呢 让我给出我试图实现的实际目标,因为我可能一开始就完全走错了方向。我想把罗伯特·戈德布拉特(Robert Goldblatt)的优秀著作《时间与计算的逻辑》(Logics of Time and Computation)中的所有证明和练习形式化为Coq 首先,我们采用古典逻辑,因为这也是这本书所做的 Require Import Classical

我在一些证明中使用了两个
归纳的
定义作为反例。不过,我想将这些定义封装在
部分中。可以使用
Let
隐藏常规
定义
,但是对于
归纳定义也可以这样做吗?那么
定理
s呢

让我给出我试图实现的实际目标,因为我可能一开始就完全走错了方向。我想把罗伯特·戈德布拉特(Robert Goldblatt)的优秀著作《时间与计算的逻辑》(Logics of Time and Computation)中的所有证明和练习形式化为Coq

首先,我们采用古典逻辑,因为这也是这本书所做的

Require Import Classical_Prop.
Require Import Classical_Pred_Type.
接下来,我们定义标识符的方法与在软件基础中定义标识符的方法相同

Inductive id : Type := Id : nat -> id.
语法的定义

Inductive modal : Type :=
| Bottom : modal
| V : id -> modal
| Imp : modal -> modal -> modal
| Box : modal -> modal
.

Definition Not (f : modal) : modal := Imp f Bottom.
使用Kripke框架定义语义

(* Inspired by: www.cs.vu.nl/~tcs/mt/dewind.ps.gz
 *)
Record frame : Type :=
{ Worlds : Type
; WorldsExist : exists w : Worlds, True
; Rel : Worlds -> Worlds -> Prop
}.

Record kripke : Type :=
{ Frame : frame
; Label : (Worlds Frame) -> id -> Prop
}.

Fixpoint satisfies (M : kripke) (x : (Worlds (Frame M))) (f : modal) : Prop
:= match f with
| Bottom => False
| V v => (Label M x v)
| Imp f1 f2 => (satisfies M x f1) -> (satisfies M x f2)
| Box f => forall y : (Worlds (Frame M)), (Rel (Frame M) x y) -> (satisfies M y f)
end.
第一个引理将模态
Not
与Coq的引理联系起来

Lemma satisfies_Not
: forall M x f
, satisfies M x (Not f) = ~ satisfies M x f
.
Proof. auto.
Qed.
接下来,我们提升语义以完成模型

Definition M_satisfies (M : kripke) (f : modal) : Prop
:=  forall w : Worlds (Frame M), satisfies M w f.
我们展示了
连接词的含义

Lemma M_satisfies_Not : forall M f
,   M_satisfies M (Not f) -> ~ M_satisfies M f
.
Proof. 
  unfold M_satisfies.
  intros M f Hn Hcontra.
  destruct (WorldsExist (Frame M)).
  specialize (Hn x); clear H.
  rewrite satisfies_Not in Hn.
  specialize (Hcontra x). auto.
Qed.
事情来了。上面引理的反面不成立,我想通过一个反例来说明这一点,展示一个它不成立的模型

Inductive Wcounter : Set := | x1:Wcounter | x2:Wcounter | x3:Wcounter.

Lemma Wcounter_not_empty : exists w : Wcounter, True.
Proof. exists x1. constructor. Qed.

Inductive Rcounter (x : Wcounter) (y : Wcounter) : Prop :=
| E1 : x = x1 -> y = x2 -> Rcounter x y
| E2 : x = x2 -> y = x3 -> Rcounter x y
.

Definition Lcounter : Wcounter -> id -> Prop
:= fun x i => match x with
| x1 => match i with | Id 0 => True | _ => False end
| x2 => match i with | Id 1 => True | _ => False end
| x3 => match i with | Id 0 => True | _ => False end
end.

Definition Fcounter : frame := Build_frame Wcounter Wcounter_not_empty Rcounter.

Definition Kcounter : kripke := Build_kripke Fcounter Lcounter.
接下来是一个
Ltac
,它使我不再需要输入verbose
assert
s

Ltac counter_example H Hc := match type of H with
| ?P -> ~ ?Q => assert(Hc: Q)
| ?P -> (?Q -> False) => assert(Hc: Q)
| ?P -> ?Q => assert(Hc: ~Q)
end.
最后,我用这个反例来证明下面的
引理

Lemma M_not_satisfies_Not : ~ forall M f
,   (~ M_satisfies M f) -> M_satisfies M (Not f)
.
Proof.
  apply ex_not_not_all. exists Kcounter.
  apply ex_not_not_all. exists (V (Id 0)).
  unfold M_satisfies. simpl.
  intro Hcontra. unfold not in Hcontra.
  counter_example Hcontra Hn2.
    apply ex_not_not_all. exists x1. simpl. auto.
  apply Hn2. apply Hcontra. apply ex_not_not_all; exists x2. simpl. auto.
Qed.

我最好使用
记住
策略来定义证据中的反例,但我不认为它可以用于
归纳的
定义。所有与反例相关的定义都是作为我理论的一部分导出的,我不想这样做。它仅用于证明
M\u not\u满足\u not
。实际上,我甚至不想导出这个
引理
,因为它不是很有用。我只是想说
M\u Not
不可能是等价的。

部分
没有隐藏定义,而是使用
模块
。例如,将计数器示例放在模块中

Module CounterExample.
    Import Definitions.
    Inductive Wcounter : Set := x1 | x2 | x3. 
    ...
    Lemma M_not_satisfies_Not : ...
End CounterExample.
在这个阶段,只有
反例
在顶层定义

如果您也不想这样做,那么您可以将定义放在一个
.v
文件中,将反例放在导入定义的另一个文件中。实际上,它的工作方式是将
.v
文件转换为单独的模块