我可以在没有附加归纳类型的情况下证明引理吗
Can I prove a lemma without an additional inductive type
我有以下类型:
Inductive instr : Set :=
| Select : nat -> instr
| Backspace : instr.
Definition prog := list instr.
和 'execute' 程序的函数:
Fixpoint execProg (p:prog) (head: list nat) (input: list nat)
: option (list nat) :=
match p with
| nil => match input with
| nil => Some head
| _::_ => None
end
| m::rest =>
match m with
| Select n =>
match input with
| nil => None
| x::r => if (beq_nat n x ) then
match (execProg rest (head++[x]) r) with
| None => None
| Some l => Some l
end
else None
end
| Backspace =>
match input with
| nil => None
| x::r => match (execProg rest (removelast head) r) with
| None => None
| Some l => Some l
end
end
end
end.
我可以尝试各种输入:
Eval compute in
execProg (Backspace::Select 1::Select 4::Backspace::nil)
nil (1::1::4::5::nil).
现在我想证明以下引理:
Lemma app_denoteSB :
forall (a b:nat) (p:prog) (input output:list nat) ,
execProg p [] input = Some output ->
execProg (p++[Select a; Backspace]) [] (input ++ [a;b])
= Some output.
但我不知道该怎么做。
通常,instr 堆栈的大小应与数据(输入列表)的大小相同,我可以更改结构并创建一个对列表 (instr,nat),并且 运行 上的归纳这个新列表。
但出于好奇,我想知道是否有办法在没有新结构的情况下证明引理。
可能吗?
谢谢!!
问题是您的陈述不够笼统,无法通过归纳法进行,因为归纳步骤需要处理 head
而非 []
的值。修复很简单:
Require Import Arith.
Require Import List.
Import ListNotations.
Inductive instr : Set :=
| Select : nat -> instr
| Backspace : instr.
Definition prog := list instr.
Fixpoint execProg (p:prog) (head input: list nat) : option (list nat) :=
match p, input with
| [], [] => Some head
| [], _ :: _ => None
| Select n :: rest, [] => None
| Select n :: rest, x :: r =>
if beq_nat n x then execProg rest (head++[x]) r
else None
| Backspace :: rest, [] => None
| Backspace :: rest, x :: r => execProg rest (removelast head) r
end.
Lemma app_denoteSB :
forall (a b:nat) (p:prog) (head: list nat) (input output:list nat) ,
execProg p head input = Some output ->
execProg (p++[Select a; Backspace]) head (input ++ [a;b]) = Some output.
Proof.
intros a b p.
induction p as [|[n|] p IH].
- intros head [|??]; simpl; try easy.
intros output H; injection H as <-.
now rewrite Nat.eqb_refl, removelast_last.
- intros head [|x input] output; simpl; try easy.
destruct (Nat.eqb_spec n x) as [<-|ne]; try easy.
apply IH.
- intros head [|x input] output; simpl; try easy.
apply IH.
Qed.
我有以下类型:
Inductive instr : Set :=
| Select : nat -> instr
| Backspace : instr.
Definition prog := list instr.
和 'execute' 程序的函数:
Fixpoint execProg (p:prog) (head: list nat) (input: list nat)
: option (list nat) :=
match p with
| nil => match input with
| nil => Some head
| _::_ => None
end
| m::rest =>
match m with
| Select n =>
match input with
| nil => None
| x::r => if (beq_nat n x ) then
match (execProg rest (head++[x]) r) with
| None => None
| Some l => Some l
end
else None
end
| Backspace =>
match input with
| nil => None
| x::r => match (execProg rest (removelast head) r) with
| None => None
| Some l => Some l
end
end
end
end.
我可以尝试各种输入:
Eval compute in
execProg (Backspace::Select 1::Select 4::Backspace::nil)
nil (1::1::4::5::nil).
现在我想证明以下引理:
Lemma app_denoteSB :
forall (a b:nat) (p:prog) (input output:list nat) ,
execProg p [] input = Some output ->
execProg (p++[Select a; Backspace]) [] (input ++ [a;b])
= Some output.
但我不知道该怎么做。 通常,instr 堆栈的大小应与数据(输入列表)的大小相同,我可以更改结构并创建一个对列表 (instr,nat),并且 运行 上的归纳这个新列表。
但出于好奇,我想知道是否有办法在没有新结构的情况下证明引理。
可能吗?
谢谢!!
问题是您的陈述不够笼统,无法通过归纳法进行,因为归纳步骤需要处理 head
而非 []
的值。修复很简单:
Require Import Arith.
Require Import List.
Import ListNotations.
Inductive instr : Set :=
| Select : nat -> instr
| Backspace : instr.
Definition prog := list instr.
Fixpoint execProg (p:prog) (head input: list nat) : option (list nat) :=
match p, input with
| [], [] => Some head
| [], _ :: _ => None
| Select n :: rest, [] => None
| Select n :: rest, x :: r =>
if beq_nat n x then execProg rest (head++[x]) r
else None
| Backspace :: rest, [] => None
| Backspace :: rest, x :: r => execProg rest (removelast head) r
end.
Lemma app_denoteSB :
forall (a b:nat) (p:prog) (head: list nat) (input output:list nat) ,
execProg p head input = Some output ->
execProg (p++[Select a; Backspace]) head (input ++ [a;b]) = Some output.
Proof.
intros a b p.
induction p as [|[n|] p IH].
- intros head [|??]; simpl; try easy.
intros output H; injection H as <-.
now rewrite Nat.eqb_refl, removelast_last.
- intros head [|x input] output; simpl; try easy.
destruct (Nat.eqb_spec n x) as [<-|ne]; try easy.
apply IH.
- intros head [|x input] output; simpl; try easy.
apply IH.
Qed.