Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.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
如何在Haskell上实现数学归纳_Haskell_Math_Proof_Induction - Fatal编程技术网

如何在Haskell上实现数学归纳

如何在Haskell上实现数学归纳,haskell,math,proof,induction,Haskell,Math,Proof,Induction,问题: 证明如果basecase p和indstep p,则对于allnat p 我不明白的是,如果basecase p和indstep p,那么对于allnat p当然应该是True 我认为basecase p说p(0)是正确的,并且 indstep p说p(成功)这是p(n+1)是真的 我们需要证明P(n)是真的。 我说得对吗? 关于如何做到这一点,你有什么建议吗?你不能在哈斯凯尔内部证明这一点。()语言的依赖性不够强。它是一种编程语言,不是一种证明助手。我认为作业可能要求你用铅笔和纸证明

问题:

证明如果
basecase p
indstep p
,则
对于allnat p

我不明白的是,如果
basecase p
indstep p
,那么
对于allnat p
当然应该是
True

我认为
basecase p
p(0)
是正确的,并且
indstep p
p(成功)
这是
p(n+1)
是真的 我们需要证明P(n)是真的。 我说得对吗? 关于如何做到这一点,你有什么建议吗?

你不能在哈斯凯尔内部证明这一点。()语言的依赖性不够强。它是一种编程语言,不是一种证明助手。我认为作业可能要求你用铅笔和纸证明

不过你可以在阿格达做

data Nat = Zero | Succ Nat
type Predicate = (Nat -> Bool)

-- forAllNat p = (p n) for every finite defined n :: Nat

implies :: Bool -> Bool -> Bool
implies p q = (not p) || q 

basecase :: Predicate -> Bool
basecase p = p Zero 

jump :: Predicate -> Predicate
jump p n = implies (p n) (p (Succ n)) 

indstep :: Predicate -> Bool
indstep p = forallnat (jump p) 
(您可以将
归纳原则
识别为
Nat
foldr


TypeInType
进入GHC 8时,您可能会得到类似的结果。不过这并不漂亮。

正如本杰明·霍奇森所指出的,你无法在哈斯克尔身上证明这一点。但是,您可以用稍微强一点的前提条件来证明一个语句。我还将忽略
Bool
不必要的复杂性

data Nat : Set where
  zero : Nat
  suc : Nat -> Nat

Pred : Set -> Set1
Pred A = A -> Set

Universal : {A : Set} -> Pred A -> Set
Universal {A} P = (x : A) -> P x

Base : Pred Nat -> Set
Base P = P zero
Step : Pred Nat -> Set
Step P = (n : Nat) -> P n -> P (suc n)

induction-principle : (P : Pred Nat) -> Base P -> Step P -> Universal P
induction-principle P b s zero = b
induction-principle P b s (suc n) = s n (induction-principle P b s n)

我认为
TypeInType
没有任何影响。问题不在于类型与种类,而在于术语与类型。在Haskell中,没有办法证明任何类型的
Nat
都可以由
'Z
's
构建。事实上,这甚至不是真的,因为
Nat
类型中也有像
Any
这样的“卡住类型”。非常酷。我以前从未见过像这样用单例来证明定理。当然,Haskell通常与
|
相关的缺点意味着你可以“证明”无根据的
p
s或
n
s的归纳原理,这将被真正的证明助手中的终止检查器排除。@BenjaminHodgson,的确,缺少终止检查有时是令人讨厌的。有时弄清楚哪些参数必须是单例,哪些只能是代理,这很有趣。它真正把你的注意力集中在计算发生的地方。
{-# LANGUAGE GADTs, KindSignatures, DataKinds, RankNTypes, ScopedTypeVariables #-}

data Nat = Z | S Nat

data Natty :: Nat -> * where
  Zy :: Natty 'Z
  Sy :: Natty n -> Natty ('S n)

type Base (p :: Nat -> *) = p 'Z
type Step (p :: Nat -> *) = forall (n :: Nat) . p n -> p ('S n)

induction :: forall (p :: Nat -> *) (n :: Nat) .
             Base p -> Step p -> Natty n -> p n
induction b _ Zy = b
induction b s (Sy n) = s (induction b s n)