【问题标题】:How to implement mathematics induction on Haskell如何在 Haskell 上实现数学归纳法
【发布时间】:2016-04-07 16:00:05
【问题描述】:
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) 

问题:

证明如果basecase pindstep p,那么forAllNat p

我不明白的是,如果basecase pindstep p,那么forAllNat p当然应该是True

我认为basecase pP(0) 是真的,并且 indstep p 表示 P(Succ n)P(n+1) 是真的 我们需要证明P(n) 是真的。 我对吗? 有关如何执行此操作的任何建议?

【问题讨论】:

    标签: haskell math proof induction


    【解决方案1】:

    正如 Benjamin Hodgson 所指出的,您无法在 Haskell 中完全证明这一点。但是,您可以用稍强的前提条件来证明一个陈述。我也会忽略Bool 的不必要的复杂性。

    {-# 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)
    

    【讨论】:

    • 非常酷。我以前从未见过像这样用于定理证明的单例。当然,Haskell 通常与_|_ 相关的缺点意味着您可以“证明”毫无根据的ps 或ns 的归纳原理,这将被真实证明助手中的终止检查器排除。跨度>
    • @BenjaminHodgson,确实,缺乏终止检查有时很烦人。有时准确地确定哪些参数必须是单例以及哪些可以只是代理是很有趣的。它确实将您的注意力集中在计算发生的位置。
    【解决方案2】:

    您无法在 Haskell 中证明这一点。 (Turns out you can.) 语言的依赖类型不够。它是一种编程语言,而不是证明助手。我认为作业可能希望你用铅笔和纸证明它。

    你可以在 Agda 中做到这一点。

    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)
    

    (您可能会将induction-principle 识别为Natfoldr。)

    TypeInType 登陆 GHC 8 时,你可能会得到一些类似的东西。但它不会很漂亮。

    【讨论】:

    • 我认为TypeInType 没有任何影响。问题不是类型与种类,而是术语与类型。没有办法在 Haskell 中证明 Nat 可以从 'Z'S 构造。事实上,它甚至不是true,因为Nat 类型也被Any 这样的“卡住类型”所占据。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2013-02-04
    相关资源
    最近更新 更多