AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77738685
Accepted
Andreas Florath
Andreas Florath
Asked: 2023-12-31 17:07:56 +0800 CST2023-12-31 17:07:56 +0800 CST 2023-12-31 17:07:56 +0800 CST

Coq 中的高效记录构建:直接证明包含可能吗?

  • 772

我想在 Coq 中定义一个小记录,其中还包括某些条件。此外,我想要一个定义来以简单的方式创建记录。这是我的方法:

Require Import Arith.

(* Define the qn record with conditions for q and n *)
Record qn := {
    q : nat;
    q_ge_2 : leb 2 q = true; (* Ensuring q is greater or equal than 2 *)
    n : nat;
    n_ge_1 : leb 1 n = true  (* Ensuring n is greater or equal than 1 *)
  }.

(* A support function to create instances of qn more conveniently *)
Definition make_qn (q n: nat) (Hq : leb 2 q = true) (Hn : leb 1 n = true) : qn :=
  {| q := q; q_ge_2 := Hq; n := n; n_ge_1 := Hn |}.

(* Examples of qn *)
Example qn_example1 : qn := make_qn 2 1 (eq_refl true) (eq_refl true).
Example qn_example2 : qn := make_qn 3 5 (eq_refl true) (eq_refl true).
Example qn_example3 : qn := make_qn 4 2 (eq_refl true) (eq_refl true).

我已经尝试了一些不同的方法 - 也定义了 qn 记录,例如使用 Prop 而不是 bool。

有没有办法简化make_qn定义直接包含证明?例如使用它就像

Example qn_simple1 : qn := make_qn 2 1
coq
  • 2 2 个回答
  • 62 Views

2 个回答

  • Voted
  1. Best Answer
    Julio Di Egidio
    2023-12-31T23:23:48+08:002023-12-31T23:23:48+08:00

    考虑以下定义qn(为了方便起见,我重命名了一些内容):

    (* Define [qn] with conditions for [q] and [n]. *)
    Record qn := mkQn
    {
      qn_q : nat ;
      qn_n : nat ;
      qn_q_ge_2 : qn_q >= 2 ;
      qn_n_ge_1 : qn_n >= 1 ;
    }.
    

    前提是 Coq 中的所有函数都必须是总计的,我们实际上可以证明根据您的问题不存在“快捷构造qn函数”,即不存在(总计)函数,给定任意 q和n,返回qn这样的它的qn_q=q和qn_n= n:

    (* The type of "short-cutting [qn] constructors". *)
    Definition MkQnSc := forall q n : nat,
      { i : qn | i.(qn_q) = q /\ i.(qn_n) = n }.
    
    (* [MkQnSc] is empty! *)
    Lemma no_MkQnSc : MkQnSc -> False.
    Proof.
      unfold MkQnSc.
      intros F.
      destruct (F 0 0) as [[q n Hq Hn] [Eq _]].
      simpl in Eq.
      rewrite Eq in Hq.
      inversion Hq.
    Qed.
    

    顺便说一句,“快捷构造qn函数”的一种可能方法(根据您的问题)是作为option qn返回类型,尽管这当然只是移动球门柱,因为那时需要对返回的option/进行模式匹配证明我们有一个Somevs None。

    也就是说,减轻每次在构造函数中必须提供证明项的不便的一种方法(@Villetaneuse 在对他的答案的评论中也提到过)是使用带有战术的符号,它确实可以用于构造项,虽然不能用于模式匹配(我不知道其他显着差异,至少在这种情况下):

    From Coq Require Import Lia.
    
    Notation mkQnSc q n :=
      (mkQn q n ltac:(lia) ltac:(lia))
      (only parsing).
    
    Example ex_qn_2_1 : qn := mkQnSc 2 1.  (* OK *)
    
    Fail Definition is_qn_2_1 (i : qn) : Prop :=
      match i with
      | mkQnSc 2 1 => True
      | _          => False
      end.  (* ERROR: Quotations not supported in patterns *)
    
    Definition is_qn_2_1 (i : qn) : Prop :=
      match i with
      | mkQn 2 1 _ _ => True
      | _            => False
      end.  (* OK *)
    
    • 1
  2. Villetaneuse
    2023-12-31T19:57:10+08:002023-12-31T19:57:10+08:00

    这是我尝试简化您的代码。

    1. 我使用Prop而不是bool因为更lia喜欢Prop,但bool也可以与其他工具一起使用来证明不等式(甚至简单的计算)。
    2. make_qn我没有在记录外部定义,而是为记录构造函数指定一个名称。
    3. 我用来ltac:(tactic)在示例中构造证明项。

    它可能并不完美(例如,该记录的平等性必须使用某种形式的无关性证明)。

    我不认为有一个神奇的解决方案可以在不给出证明条件的情况下构建元素。

    Require Import Arith.
    
    (* Define the qn record with conditions for q and n *)
    (* I have changed bool with Prop. *)
    Record qn := MakeQn {
        q : nat;
        q_ge_2 : q >= 2; (* Ensuring q is greater or equal than 2 *)
        n : nat;
        n_ge_1 : n >= 1  (* Ensuring n is greater or equal than 1 *)
      }.
    
    Require Import Lia.
    (* Examples of qn *)
    Example qn_example1 : qn := MakeQn 2 ltac:(lia) 1 ltac:(lia).
    Example qn_example2 : qn := MakeQn 3 ltac:(lia) 5 ltac:(lia).
    Example qn_example3 : qn := MakeQn 4 ltac:(lia) 2 ltac:(lia).
    
    • 0

相关问题

  • 为什么“专门化”在证明中不是无效策略?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    使用 <font color="#xxx"> 突出显示 html 中的代码

    • 2 个回答
  • Marko Smith

    为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类?

    • 1 个回答
  • Marko Smith

    您可以使用花括号初始化列表作为(默认)模板参数吗?

    • 2 个回答
  • Marko Smith

    为什么列表推导式在内部创建一个函数?

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Marko Smith

    java.lang.NoSuchMethodError: 'void org.openqa.selenium.remote.http.ClientConfig.<init>(java.net.URI, java.time.Duration, java.time.Duratio

    • 3 个回答
  • Marko Smith

    为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)?

    • 4 个回答
  • Marko Smith

    为什么库中不调用全局变量的构造函数?

    • 1 个回答
  • Marko Smith

    std::common_reference_with 在元组上的行为不一致。哪个是对的?

    • 1 个回答
  • Marko Smith

    C++17 中 std::byte 只能按位运算?

    • 1 个回答
  • Martin Hope
    fbrereto 为什么在传递 {} 时重载解析更喜欢 std::nullptr_t 而不是类? 2023-12-21 00:31:04 +0800 CST
  • Martin Hope
    比尔盖子 您可以使用花括号初始化列表作为(默认)模板参数吗? 2023-12-17 10:02:06 +0800 CST
  • Martin Hope
    Amir reza Riahi 为什么列表推导式在内部创建一个函数? 2023-11-16 20:53:19 +0800 CST
  • Martin Hope
    Michael A fmt 格式 %H:%M:%S 不带小数 2023-11-11 01:13:05 +0800 CST
  • Martin Hope
    God I Hate Python C++20 的 std::views::filter 未正确过滤视图 2023-08-27 18:40:35 +0800 CST
  • Martin Hope
    LiDa Cute 为什么 'char -> int' 是提升,而 'char -> Short' 是转换(但不是提升)? 2023-08-24 20:46:59 +0800 CST
  • Martin Hope
    jabaa 为什么库中不调用全局变量的构造函数? 2023-08-18 07:15:20 +0800 CST
  • Martin Hope
    Panagiotis Syskakis std::common_reference_with 在元组上的行为不一致。哪个是对的? 2023-08-17 21:24:06 +0800 CST
  • Martin Hope
    Alex Guteniev 为什么编译器在这里错过矢量化? 2023-08-17 18:58:07 +0800 CST
  • Martin Hope
    wimalopaan C++17 中 std::byte 只能按位运算? 2023-08-17 17:13:58 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve