【问题标题】:Multiple assignments in a Coq let clauseCoq let 子句中的多个赋值
【发布时间】:2017-03-08 10:22:04
【问题描述】:

我是 Coq 的新手,只是想弄清楚基本语法。如何向let 添加多个子句?这是我正在尝试编写的函数:

Definition split {A:Set} (lst:list A) :=
  let
    fst := take (length lst / 2) lst
    snd := drop (length lst / 2) lst
  in (fst, snd) end.

这是错误:

语法错误:在 [constr:operconstr level 200] 之后应为“in”(在 [constr:binder_constr] 中)。

我想它在fst 的定义之后需要一个in

【问题讨论】:

    标签: syntax-error coq let


    【解决方案1】:

    确实,您需要在第一个标识符之后使用in。根据参考手册(§1.2.12):

    let ident := term1 in term2 表示term1term2 中的变量ident 的本地绑定。

    您需要多个(嵌套的)let ... in 表达式:

    Definition split {A:Set} (lst:list A) :=
      let fst := take (length lst / 2) lst in
      let snd := drop (length lst / 2) lst in
        (fst, snd).
    

    顺便说一句,您可以使用标准库 (List module) 中的 firstnskipn 函数来代替 takedrop

    Require Import Coq.Lists.List.
    Import ListNotations.
    Compute firstn 3 [1;2;3;4;5].    (* Result: [1;2;3] *)
    Compute skipn 3 [1;2;3;4;5].     (* Result: [4;5]   *)
    

    这(以及一些重构)导致split 的以下定义(我将其重命名以避免split 标准函数的阴影):

    Definition split_in_half {A:Set} (lst:list A) :=
      let l2 := Nat.div2 (length lst) in
        (firstn l2 lst, skipn l2 lst).
    
    Compute split_in_half [1;2;3;4;5].    (* Result: ([1; 2], [3; 4; 5])  *)
    

    顺便说一句,如果您担心输入列表的多次传递,它仍然有很大的改进空间。如果您打算进行提取,例如,您可能是进入 OCaml。

    【讨论】:

    • 很棒的答案,谢谢!我只是在定义自己的语言来掌握语言:)
    • 谢谢 :) 我还可以建议查看引理firstn_skipnfirstn_length(在List 模块中),它们总结并保证(!)相应函数的主要属性。
    猜你喜欢
    • 1970-01-01
    • 2011-10-31
    • 2018-10-18
    • 1970-01-01
    • 2015-11-16
    • 2018-05-29
    • 2019-03-25
    • 2019-06-27
    • 1970-01-01
    相关资源
    最近更新 更多