Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 多列表归纳法证明_Scala_Functional Programming_Induction_Proof Of Correctness_Equational Reasoning - Fatal编程技术网

Scala 多列表归纳法证明

Scala 多列表归纳法证明,scala,functional-programming,induction,proof-of-correctness,equational-reasoning,Scala,Functional Programming,Induction,Proof Of Correctness,Equational Reasoning,我正在关注有关Coursera的Scala讲座中的函数编程,在视频5.7的结尾,Martin Odersky要求通过归纳证明以下等式的正确性: (xs ++ ys) map f = (xs map f) ++ (ys map f) 当涉及多个列表时,如何处理归纳法证明 我已经检查了xs为零和ys为零的基本情况。 我已经用归纳法证明了,当x被x::x替换时,方程成立,但是我们是否也需要用y::y替换y来检查方程 在这种情况下(不会破坏练习太多…无论如何都没有评分),您如何处理:(xs++(y::

我正在关注有关Coursera的Scala讲座中的函数编程,在视频5.7的结尾,Martin Odersky要求通过归纳证明以下等式的正确性:

(xs ++ ys) map f = (xs map f) ++ (ys map f)
当涉及多个列表时,如何处理归纳法证明

我已经检查了xs为零和ys为零的基本情况。 我已经用归纳法证明了,当x被x::x替换时,方程成立,但是我们是否也需要用y::y替换y来检查方程

在这种情况下(不会破坏练习太多…无论如何都没有评分),您如何处理:
(xs++(y::ys))map f

这是我在一个类似的例子中使用的方法,以证明

(xs ++ ys).reverse = ys.reverse ++ xs.reverse
证明(省略基本情况和easy x::xs情况):


这是对的吗?

正如@Phil的评论所说,首先是很好地理解方法
++
在列表上的作用更好的方法是

如何证明列表程序的性质? 答案是结构归纳法! 通过结构归纳证明列表属性P(xs)的证明规则:

p(无)(基本情况) 对于所有x,xs:P(xs)=>P(x::xs)(诱导步骤)

对于所有xs:p(xs)(结果)

诱导步骤中的p(xs)称为诱导假说

因为唯一重要的是xs,ys是长度为l的fix-property列表,在为xs证明之后,您可以为ys证明,或者看到它是可交换的

让我们应用归纳法和函数的定义

p(xs):(xs++ys)map f=(xs-map f)++(ys-map f)

基本情况下,我们用nil取代xs

(nil ++ ys) map f [definition of ++ ] 
ys map f  on the other hand 
(xs map f) ++ (ys map p) [apply map over NIL] 
(NIL) ++ (ys map p) [definition pf ++] 
ys map p
诱导步骤

((x::xs) ++ ys) map f [definition ++]
(x:: (xs ++ ys)) map f [definition map]
f(x) :: ((xs ++ ys) map f) [induction hypothesis]
f(x) :: ((xs map f) ++ (ys map f)) [definition ++]
(f(x) :: (xs map f)) ++ (ys map f) [definition map]
(x::xs) map f ++ ys map f
q、 急诊室

例如,scala工作表中的另一个案例

import scala.util.Random

// P : length ( append(as,bs) )) = length ( as ) + length (bs)

def length[T](as: List[T]): Int = as match {
    case Nil => 0
    case _::xs => 1 + length(xs)
}

def append[T](as: List[T], bs: List[T]): List[T] = as match {
  case Nil => bs
  case x :: xs => x :: append(xs, bs)
}

// base case  we substitute Nil for as in P

val a:List[Int] = Nil
val n = 10
val b:List[Int] = Seq.fill(n)(Random.nextInt).toList

length((append(a,b)))

length(a)

length(b)
导入scala.util.Random

length: length[T](val as: List[T]) => Int




append: append[T](val as: List[T],val bs: List[T]) => List[T]






a: List[Int] = List()
n: Int = 10
b: List[Int] = List(1168053950, 922397949, -1884264936, 869558369, -165728826, -1052466354, -1696038881, 246666877, 1673332480, -975585734)

res0: Int = 10

res1: Int = 0

res2: Int = 10

您可以找到更多示例

该属性涉及多个列表,但
++
仅在其左参数上递归。这是一个暗示,你们可以通过归纳法证明这个左论点。一般来说,当证明一个关于某个递归函数的命题时,首先要尝试的是归纳出函数递归的同一个参数

我将为您做一个示例:

索赔
(xs++ys)地图f
=
(xs地图f)++(ys地图f)

证明:通过
xs
上的归纳法

  • 基本情况:
    xs
    =
    Nil

    • lhs=
      (Nil++ys)映射f
      =
      ys映射f

      (根据
      ++
      的定义)

    • rhs=
      (无图f)++(ys图f)
      =
      Nil++ys图f
      =
      ys图f

      (通过
      映射
      ,然后通过
      ++
      的定义)

    • 因此lhs=rhs
  • 感应情况:
    xs
    =
    z::zs

    • 假设
      (zs++ys)映射f
      =
      (zs映射f)++(ys映射f)
    • 目标
      ((z::zs)++ys)映射f
      =
      ((z::zs)映射f)++ys映射f
    • lhs=
      (z:(zs++ys))映射f
      =
      f(z:((zs++ys)映射f)
      (1)

      (根据
      地图
      的定义)

    • rhs=
      ((z::zs)映射f)++(ys映射f)
      =
      (f(z):(zs映射f))++(ys映射f)

      (根据
      地图
      的定义)

    • 反过来,rhs=
      f(z):((zs地图f)++(ys地图f))
      (2)

      (根据
      ++
      的定义)

    • 假设(1)(2),我们已经证明了目标

因此,我们已经证明了该声明是正确的,无需对
xs
ys
f

进行规范。请看
++
map
的定义。有两个列表,但它们分解哪一个当然,但是这个定义并不能证明……我们可以说“它已经被证明是正确的,通过归纳两个表达式列表中的一个,因此整个表达式是正确的”……我倾向于认为我们不能。谢谢你的回答。我的问题可能不是很清楚,你的答案与我证明的部分相符。我的问题是如何从“一个列表上的归纳”变成“整个表达式被证明是正确的”。@Gael你只需要在一个列表上归纳,然后不透明地引用另一个列表。
length: length[T](val as: List[T]) => Int




append: append[T](val as: List[T],val bs: List[T]) => List[T]






a: List[Int] = List()
n: Int = 10
b: List[Int] = List(1168053950, 922397949, -1884264936, 869558369, -165728826, -1052466354, -1696038881, 246666877, 1673332480, -975585734)

res0: Int = 10

res1: Int = 0

res2: Int = 10