我可以证明没有其他电感类型的引理

发布于 2025-02-03 16:19:20 字数 1531 浏览 1 评论 0原文

我有以下类型:

Inductive instr : Set :=
 | Select    : nat -> instr
 | Backspace : instr.

Definition prog := list instr.

以及“执行”程序的功能:

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.

但是我看不到该怎么做。 通常,乐器堆栈的大小应与数据的大小相同(输入列表),我可以更改结构并创建对(仪器,NAT)的列表,并在此新列表上运行归纳。

但是出于好奇,我想知道是否有一种方法可以证明没有新结构的引理。

是否可以 ?

谢谢 !!

I have the following types :

Inductive instr : Set :=
 | Select    : nat -> instr
 | Backspace : instr.

Definition prog := list instr.

and a function to 'execute' the program :

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.

I can try it on various inputs :

Eval compute in
  execProg (Backspace::Select 1::Select 4::Backspace::nil)
    nil (1::1::4::5::nil).

Now I'd like to prove the following lemma:

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.

But I don't see how to do that.
As normally, the size of the instr stack should be the same as the size of the data (input list), I can change the structures and create a list of pairs (instr,nat), and run the induction on this new list.

But out of curiosity, I was wondering if there was a way to prove the lemma without the new structure.

Is it possible ?

Thanks !!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

游魂 2025-02-10 16:19:20

问题是您的语句不够笼统,无法通过归纳进行,因为归纳步骤需要处理head [] 以外的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.

The issue is that your statement is not general enough to go through by induction, because the inductive step needs to handle values of head other than []. The fix is easy:

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文