COQ中转换的精确控制

发布于 2025-01-25 14:55:06 字数 1955 浏览 2 评论 0原文

我尝试证明COQ中的以下定理:

Theorem simple :
    forall (n b:nat) (input output: list nat) , short (n::b::input) true (n::output) = None 
             -> short (b::input) false output = None. 

简短如下:

Fixpoint short (input: list nat) (starting : bool) (output: list nat) : option (list nat) :=
match input with
  | nil => match output with
                 | nil => Some nil
                 | y::r => None
           end
  | x::rest => match output with
                | nil => ...
                | y::r => if ( beq_nat x y ) then match (short rest false r) with
                                                   | None => if (starting) then match (short rest starting output) with
                                                                               | Some pp => Some (0 :: pp)
                                                                               | None => None
                                                                           end 
                                                            else None 
                                                   | Some pp => Some (x :: pp)
                                                   end
                        else ...
end.

如果我可以控制开始

short (n::b::input) true (n::output)

并最终以类似内容的转换步骤,则证明很简单:

match (short (b::input) false output) with
            | None => match (short rest starting output) with
                            | Some pp => Some (0 :: pp)
                            | None => None
                      end 
            | Some pp => Some (x :: pp)
end

我已经尝试了:

Proof.
  intros.
  cbv delta in H.
  cbv fix in H.
  cbv beta in H.
  cbv match in H.
  rewrite Nat.eqb_refl in H.
...

但是,如果这样做,则似乎重写了不仅仅是重写并执行转换,我无法再次将其折叠到所需的表格……

任何知道如何进行转换?

谢谢 !!

I try to prove the following theorem in Coq:

Theorem simple :
    forall (n b:nat) (input output: list nat) , short (n::b::input) true (n::output) = None 
             -> short (b::input) false output = None. 

with short as follows :

Fixpoint short (input: list nat) (starting : bool) (output: list nat) : option (list nat) :=
match input with
  | nil => match output with
                 | nil => Some nil
                 | y::r => None
           end
  | x::rest => match output with
                | nil => ...
                | y::r => if ( beq_nat x y ) then match (short rest false r) with
                                                   | None => if (starting) then match (short rest starting output) with
                                                                               | Some pp => Some (0 :: pp)
                                                                               | None => None
                                                                           end 
                                                            else None 
                                                   | Some pp => Some (x :: pp)
                                                   end
                        else ...
end.

The proof would be simple if I could control the conversion steps to start with

short (n::b::input) true (n::output)

and end up with something like:

match (short (b::input) false output) with
            | None => match (short rest starting output) with
                            | Some pp => Some (0 :: pp)
                            | None => None
                      end 
            | Some pp => Some (x :: pp)
end

I've tried this :

Proof.
  intros.
  cbv delta in H.
  cbv fix in H.
  cbv beta in H.
  cbv match in H.
  rewrite Nat.eqb_refl in H.
...

but it seems that rewrite if doing more than a rewrite and performs a conversion I can't fold again to the desired form...

Any idea how this conversion can be done ?

Thank you !!

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

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

发布评论

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

评论(1

小耗子 2025-02-01 14:55:06

cbn策略看起来像是在这里做得不错的工作:

Theorem simple :
    forall (n b:nat) (input output: list nat) , short (n::b::input) true (n::output) = None 
             -> short (b::input) false output = None.
Proof.
  intros.
  cbn in *.
  rewrite Nat.eqb_refl in H.
  match goal with | |- ?t = _ => set (x := t) in * end.
  destruct x.
  all: congruence.
Qed.

通常,我建议您反对cbv,除非您想真正获得布尔值。但是,如果您想做“只是有点不展开” cbnsimpl通常会更好地表现。

The cbn tactic looks like it does a decent job here:

Theorem simple :
    forall (n b:nat) (input output: list nat) , short (n::b::input) true (n::output) = None 
             -> short (b::input) false output = None.
Proof.
  intros.
  cbn in *.
  rewrite Nat.eqb_refl in H.
  match goal with | |- ?t = _ => set (x := t) in * end.
  destruct x.
  all: congruence.
Qed.

In general, I would advise against cbv unless you want to really get eg a boolean. But if you want to do "just a bit of unfolding" cbn or simpl are usually better behaved.

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