给出以下功能:
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)
答案 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'
:
此处,假设所有ys
,zs
,foo (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'
的另一个事实(“归纳假设”)。这种“直接”方法在研究层面的所有(也许是大多数)案例中都不起作用,但它适用于这项工作。
案例中证明的实际陈述是
xs = []
,foo (foo xs ys) zs = foo ys (xs @ zs)
;和xs = x::xs'
和foo (foo xs' ys) zs = foo ys (xs' @ zs)
,则foo (foo xs ys) zs = foo ys (xs @ zs)
。 ys
和zs
是隐式普遍量化的。