Curry Howard tương ứng với Dự đoán logic?


7

Vì vậy, tôi đang cố gắng để có được vòng đầu Curry-Howard. (Tôi đã thử nó nhiều lần, nó chỉ không gelling / có vẻ quá trừu tượng). Để giải quyết vấn đề cụ thể, tôi đang làm việc thông qua một vài hướng dẫn của Haskell được liên kết từ wikipedia, đặc biệt là Tim Newsham . Cũng có một cuộc thảo luận hữu ích khi Newsham đăng bài hướng dẫn.

(Nhưng tôi sẽ bỏ qua các datahàm bao của Newsham và Piponi , và nói về các loại cơ bản.) Chúng ta có sơ đồ tiên đề của Hilbert (được biểu thị dưới dạng các tổ hợp S , K ); chúng ta có các mệnh đề như các loại; hàm ý như hàm mũi tên; và Modus Ponens là ứng dụng chức năng:

axK :: p -> q -> p
axK  = const
axS :: (p -> q -> r) -> (p -> q) -> p -> r
axS     f                g          x  = f x (g x)

modPons = ($);   infixl 0 `modPons`          -- infix Left, cp ($) is Right

Sau đó tôi có thể rút ra luật định danh:

ident     = axS `modPons` axK `modPons` axK  -- (S K K)
-- ident :: p -> p                           -- inferred

Có những kiểu này như kiểu chữ trần chỉ tương ứng với các mệnh đề có vẻ khá không tưởng tượng. Tôi có thể sử dụng nhiều hơn hệ thống loại để thực sự xây dựng các đề xuất không? Tôi đang nghĩ:

data      IsNat n  = IsNat !n                -- [Note **]

data      Z        = Z
axNatZ ::            IsNat Z
axNatZ             = IsNat Z

data      S n      = S !n
axNatS :: IsNat n -> IsNat (S n)
axNatS   (IsNat n) = IsNat (S n) 

twoIsNat = axNatS `modPons` (axNatS `modPons` axNatZ)
-- ===> IsNat (S (S Z))

[Lưu ý **] Tôi đang sử dụng các nhà xây dựng nghiêm ngặt, theo chủ đề thảo luận, để tránh giới thiệu _ | _ .

Ở đâu:

  • IsNat là một vị ngữ: đưa ra một đề xuất từ ​​một thuật ngữ.
  • n là một biến
  • S là một hàm, tạo một thuật ngữ từ một biến.
  • Z là một hằng số (hàm niladic).

Vì vậy, tôi dường như đã nhúng Logic dự đoán (thứ nhất)

Tôi đánh giá cao các loại của tôi không vệ sinh; Tôi có thể dễ dàng trộn lẫn một đề xuất typevar với một typevar-as-term. Có lẽ tôi nên sử dụng Kindhệ thống để phân tách chúng. OTOH tiên đề của tôi sẽ phải là sai lầm ngoạn mục để đi đến bất kỳ kết luận.

Tôi chưa bày tỏ:

  • định lượng phổ quát: nó ẩn cho các bình miễn phí;
  • định lượng hiện sinh: các hằng số có hiệu lực có thể đóng vai trò là các tồn tại bị bỏ qua;
  • sự bình đẳng của các điều khoản: Tôi đã sử dụng các kiểu chữ lặp đi lặp lại trong ý nghĩa;
  • quan hệ: điều này dường như làm việc, hoặc nó là sai lầm? ...
    data          PlusNat n m l  = PlusNat !n !m !l

    axPlusNatZ :: IsNat m       -> PlusNat Z m m
    axPlusNatZ   (IsNat m)       = PlusNat Z m m

    axPlusNatS :: PlusNat n m l -> PlusNat (S n) m (S l)
    axPlusNatS   (PlusNat n m l) = PlusNat (S n) m (S l)

    plus123 = axPlusNatS `modPons`
              (axPlusNatZ `modPons`
               (axNatS `modPons` (axNatS `modPons` axNatZ)) ) 
    -- ===> PlusNat (S Z) (S (S Z)) (S (S (S Z)))

Viết các tiên đề thật dễ dàng, lịch sự theo Định lý của Wadler miễn phí! . Viết các bằng chứng là công việc khó khăn. (Tôi sẽ bỏ modPonsvà chỉ sử dụng ứng dụng chức năng.)

Đây có thực sự đạt được một logic. Hay là nó là thứ điên rồ? Tôi có nên dừng lại trước khi tôi làm hại thêm bộ não của mình không?

Bạn cần phải có các loại phụ thuộc để thể hiện FOPL trong Curry-Howard. Nhưng tôi dường như không làm điều đó (?)


1
Vấn đề với cách tiếp cận của bạn IsNatlà không đưa ra một đề xuất từ ​​một thuật ngữ, nó tạo ra một đề xuất từ ​​một đề xuất .
Derek Elkins rời SE

Cảm ơn @DerekElkins, tôi đoán bạn có nghĩa là đối số IsNatchỉ là một loại, do đó phải là một đề xuất. OK, bằng nhau IsNat nchỉ là một loại vì vậy phải là một đề xuất. Tôi phải 'vì danh dự của mình' không được ntrốn vào vùng đất đề xuất / xuất hiện như một cuộc tranh luận với một liên kết logic (đó là lý do tại sao tôi nói về vệ sinh kiểu). Bạn có vui hơn không nếu tôi sử dụng mã hóa Church cho Nats? Tôi nghĩ rằng tôi chỉ mở rộng-calc với các nhà xây dựng ở cấp độ loại, giống như Haskell ở cấp độ hạn (?)
AntC

PS có lẽ n một đề xuất : nó nói 'Tôi đang ở'. Đó là không nhiều hơn bất kỳ typevar đang nói theo CH. IsNat nđang nói / chứng kiến: hơn nữa, cư dân ncủa một loại 'đặc biệt', hay còn gọi là 'sắp xếp' theo logic. Sau đó, tôi sẽ vượt ra ngoài-calc (?)
AntC

1
Tôi không nghĩ rằng việc tìm hiểu về Đồng phân Curry-Howard bằng cách chơi xung quanh với các ngôn ngữ lập trình phức tạp là cách tiếp cận đúng đắn. Nó sẽ không dẫn đến bất kỳ sự hiểu biết thực sự về nguyên tắc.
Tuyến Miles

1
Nếu bạn không hiểu các văn bản, thì bạn nên tìm hiểu những gì bạn cần để hiểu các văn bản. Haskell không phải là một trong những điều đó.
Miles Rout

Câu trả lời:


3

Để giải thích lý do tại sao tôi không thoải mái với datagiấy gói của Newsham và (đặc biệt là) Piponi ... (Đây sẽ là câu hỏi nhiều hơn câu trả lời, nhưng có lẽ nó sẽ hướng đến việc giải thích những gì sai với tôi IsNatmặc dù nó có vẻ rất giống với Newsham. )

Piponi trang 17 trên có:

data Proposition = Proposition :-> Proposition
                  | Symbol String
                  | False deriving Eq

data Proof = MP Proof Proof
     | Axiom String Proposition deriving Eq

Tôi thấy không có loại ở đây. Đánh vần một hàm tạo dữ liệu :->không làm cho nó hoạt động theo mũi tên; và đánh vần một hàm tạo dữ liệu MP(cho Modus Ponens) không làm cho nó hoạt động được. Có một toán tử 'nhà xây dựng thông minh' (@@)cho MP, nhưng điều đó không áp dụng chức năng nào: nó chỉ đơn thuần thực hiện khớp mẫu trên hàm :->tạo.

Newsham có (Tôi sẽ bắt đầu với phần Hàm ý / Modus Ponens):

data Prop p = Prop p

data p :=> q = Imp (Prop p -> Prop q)

impInj :: (Prop p -> Prop q) -> Prop (p :=> q)
impInj p2q = Prop (Imp p2q)

impElim :: Prop p -> Prop (p :=> q) -> Prop q
impElim p (Prop (Imp p2q)) = p2q p

Điều này trông giống như nó: chúng ta có các loại, mũi tên chức năng, ứng dụng chức năng trong impElim. Nhà xây dựng kiểu Impvới các quy tắc tiêm và loại bỏ của nó phản ánh các cấu trúc cây chứng minh trong các Bài giảng về sự đồng hình của Curry-Howard . Nhưng tôi lo lắng: tại sao Impcần một nhà xây dựng kiểu và nhà xây dựng dữ liệu? Một lần nữa, đánh vần như :=>không làm cho một mũi tên chức năng. Tại sao tất cả các nhà Propxây dựng gói và tháo dỡ này ? Tại sao không đơn giản Prop (p -> q)?

Vì vậy, khi tôi nhìn vào phần 'Kết hợp' (phần thực sự xuất hiện trước):

data p :/\ q = And (Prop p) (Prop q)

andInj :: Prop p -> Prop q -> Prop (p :/\ q)
andInj p q = Prop (And p q)

andElimL :: Prop (p :/\ q) -> Prop p
andElimL (Prop (And p q)) = p

andElimR :: Prop (p :/\ q) -> Prop q
andElimR (Prop (And p q)) = q

Những Elimchức năng này không sử dụng ứng dụng chức năng. Họ chỉ đơn thuần là khớp mẫu trên các nhà xây dựng. Không có cấu trúc liên quan để kết hợp: chúng tôi hoàn toàn tin tưởng rằng 'lập trình viên' chỉ sử dụng andInjquy tắc để xây dựng một loại (p :/\ q).

Vì vậy, khi Newsham đạt được tính giao hoán:

commuteAnd :: Prop (p :/\ q) -> Prop (q :/\ p)
commuteAnd pq = andInj (andElimR pq) (andElimL pq)

Và yêu cầu bồi thường

Lưu ý rằng bằng chứng Haskell của chúng tôi không chứa bất kỳ tham chiếu nào đến cấu trúc bên trong của kiểu dữ liệu (: / \). Khi đã xác định và chứng minh các quy tắc của chúng tôi "andInj", "andElimR" và "andElimL", chúng ta không bao giờ phải nhìn trộm việc thực hiện kiểu dữ liệu (: / \) nữa.

Tôi không đồng ý:

  • Chữ ký cho commuteAnd không dựa vào cấu trúc bên trong của hàm tạo :/\kiểu.
  • Mặc dù định nghĩa vẻ chức năng thích chỉ đơn chức năng, trên thực tế các andElims làm "cái nhìn" vào cấu trúc.

Tôi hy vọng chúng ta có thể chứng minh tính giao hoán của kết hợp từ định nghĩa của nó, mà không cần một tiên đề để nói như vậy (?)

Được thôi nếu tôi quá thuần khiết, tôi mong đợi điều gì? Điều này để kết hợp dựa trên mã hóa Giáo hội cho cặp:

type Conj p q r = Prop ((p -> q -> r) -> r)     -- not right, see later

andInj :: Prop p -> Prop q -> Conj p q r
andInj (Prop p) (Prop q) = Prop (\elim -> elim p q)

andElimL :: Conj p q p -> Prop p
andElimL (Prop conj) = Prop (conj axK)    -- axK is `const`

Bây giờ tôi có thể viết commuteAndbằng ứng dụng chức năng 'thích hợp':

--  commuteAnd :: (Conj p q r) -> (Conj q p r)
commuteAnd pq = andInj (andElimR pq) (andElimL pq)

Định nghĩa chức năng đó giống như của Newsham. Nhưng tôi đã nhận xét chữ ký vì loại suy ra của GHC không đủ chung. Nó muốn Prop ((p -> p -> p) -> p) -> ((p -> p -> p) -> p). Đó chỉ là một biến thể ưa thích về luật Danh tính.

Chỉnh sửa: (Sau khi @DerekElkins bình luận đầu tiên ở đây.) Phế liệu tất cả điều này:

Tôi đã kết thúc trong nước sâu (và âm u). Tôi nghĩ rằng loại hình của tôi Conjcần phải đa hình hơn, có khả năng Imprimateative. Tôi đã bị mắc kẹt về việc cố gắng đưa ra một loại thứ hạng cao hơn:

type Conj p q = Prop (forall r.((p -> q -> r) -> r))

Nhưng GHC không chơi. (Và hỗ trợ cho tính đa hình Imprativeative là "không ổn định".) Và một forallthứ được yêu cầu như thế trông giống như định nghĩa cho Sai / không có người ở mà tôi đang mong đợi sử dụng.

Tôi cần một loại cấp bậc cao hơn, nhưng không phải là Imprativeative. Và không phải trên loại cho Conjnhưng chocommuteAnd

commuteAnd :: (forall r. Conj p q r) -> (Conj q p r')
-- (same function for `commuteAnd` as above)

ĐỒNG Ý. Tôi có thể vui vẻ trao đổi đối số quảng cáo infinitum.

[Kết thúc chỉnh sửa]

Vì vậy, câu hỏi của tôi: nếu nó hợp pháp những gì Newsham đang làm với các hàm tạo lồng nhau và khớp mẫu ở mọi nơi, vậy thì điều gì không hợp pháp về IsNatkhớp và mẫu của tôi ?


1
Như Piponi tuyên bố, các loại PropositionProofkhông phải là ví dụ về sự tương ứng của Curry-Howard trong hành động. Chúng chỉ tạo thành một hệ thống chứng minh kiểu LCF đơn giản. Sự tương ứng của Curry-Howard được chứng kiến ​​bởi compilechức năng (mặc dù hầu hết các công việc được thực hiện bởi (^)show) biến những Propositions và Proofs đó thành mã Haskell. Như đối với mã Newsham của, những gói làm cho không có sự khác biệt (:=>)về cơ bản (->). Anh ta chỉ thêm chúng (như anh ta tuyên bố rõ ràng) để anh ta có thể trao đổi trong một triển khai khác, không tầm thường sau này.
Derek Elkins rời SE

Cảm ơn. Neasham, tôi muốn gắn bó với Logic Trực giác, không phải Cổ điển; vì vậy bỏ qua các phần tiếp theo / đơn nguyên. Bạn có nói rằng những khuyết điểm của anh ấy không hoạt động cho Trực giác? Có (:=>)được thực hiện như (->). Nhưng một mô hình / mô phỏng logic, cần xác thực trình thông dịch (?). Tại sao tôi không thể diễn đạt trực tiếp trong Haskell (->)?
AntC

Nhận xét tương tự wrt Piponi: ông giới thiệu (^)để đối phó với Cổ điển. OK, tôi sẽ thử dùng showmã Haskell và xem nó khác nhau như thế nào. (Tôi cũng sẽ cố gắng tìm hiểu cách anh ấy giới thiệu Integer.) Tôi đang cố gắng sử dụng tối thiểu máy móc Haskell, vì sợ tôi sẽ giới thiệu _|_ở đâu đó và làm suy yếu "các chương trình là bằng chứng".
AntC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.