结构感应的OCaml证明

时间:2016-02-04 17:25:13

标签: ocaml proof induction

给出以下功能:

let rec foo l1 l2 = 
    match (l1,l2) with
        ([],ys) -> ys
      | (x::xs,ys) -> foo xs (x::ys))

证明以下属性:

  • foo (foo xs ys) zs = foo ys (xs@zs)

到目前为止,我已经完成了基础案例和归纳案例,但不知道如何开始证明:

基本案例:

  • foo (foo [] ys) zs = foo ys ([]@zs)
  • foo ys zs = foo ys zs

归纳案例:

  • foo (foo (x::xs) ys) zs = foo ys ((x::xs)@zs)

1 个答案:

答案 0 :(得分:1)

您要询问的证据类型如下。我包括基本案例。感应案例留给你。确保使用归纳案例中某处提到的假设来完成它。我使用=表示“平等”,使用=>进行评估。我不知道您的上下文中可用的关系,允许您对评估和相等性的假设,或者是否允许您使用有关@的引理或者有可用的抽象定义。所以,你可能不得不修改它。

通过归纳xs的结构证明。

案例:xs = []

foo (foo xs ys) zs
  =  foo (foo [] ys) zs          (* structure of xs *)
  => foo (match ([], ys) with ([], ys) -> ys | (* ... *)
                                 (* def. of foo, substitution *)
  => foo (ys) zs                 (* eval. of match *)
  =  foo ys zs                   (* drop parentheses *)
  =  foo ys ([] @ zs)            (* abstract def. of @ *)
  =  foo ys (xs @ zs)            (* structure of xs *)

案例:xs = x::xs'

此处,假设所有yszsfoo (foo xs' ys) zs = foo ys (xs' @ zs)(这就是所谓的归纳假设。)

foo (foo xs ys) zs
  =  foo (foo (x::xs') ys) zs    (* structure of xs *)
  =  foo (match (x::xs', ys) with (* ... *) | (x::xs', ys) -> (* ... *)
                                 (* def. of foo, substitution *)
  => foo (foo xs' (x::ys)) zs    (* eval. of match *)

    (* for you *)

  =  foo ys ((x::xs') @ zs)      (* by some argument from you *)
  =  foo ys (xs @ zs)            (* structure of xs *)

正如您所看到的,证明首先选择一个值来进行结构归纳(您已经在问题中选择了xs)。然后,证据根据可能构造的xs的所有可能方式分成案例。由于xs可能是一个列表(这就是为什么类型信息很重要),因此它只有两种:它可能是[],也可能是x::xs'一些值x和列表xs'。这分别导致基本情况和归纳情况。在这两种情况下,我们必须证明相同的原始属性,但我们知道有关xs看起来的额外信息(即xs的“结构”)。

对于每种情况,您都使用该结构来确定您想要的语句(在原始问题中大致正确)。然后,您尝试简单地从语句左侧的表达式转到右侧的表达式,使用评估规则,标识和您可用的任何词条。在归纳的情况下,你可以使用关于xs'的另一个事实(“归纳假设”)。这种“直接”方法在研究层面的所有(也许是大多数)案例中都不起作用,但它适用于这项工作。

案例中证明的实际陈述是

  1. 如果xs = []foo (foo xs ys) zs = foo ys (xs @ zs);和
  2. 如果xs = x::xs'foo (foo xs' ys) zs = foo ys (xs' @ zs),则foo (foo xs ys) zs = foo ys (xs @ zs)
  3. yszs是隐式普遍量化的。