Skip to content

Commit

Permalink
KD: New equational reasoning examples
Browse files Browse the repository at this point in the history
WIP
  • Loading branch information
LeventErkok committed Dec 5, 2024
1 parent 2086552 commit eb5f1b6
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
-----------------------------------------------------------------------------

Check failure on line 1 in Documentation/SBV/Examples/KnuckleDragger/EquationalReasoning.hs

View workflow job for this annotation

GitHub Actions / hlint

Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.EquationalReasoning\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Various equalities that arise in functional-programming. A good source\n-- is the classic book \"Introduction to Functional Programming using Haskell,\"\n-- second edition. (Section 4.6 and others.)\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE DeriveAnyClass #-}\n{-# LANGUAGE DeriveDataTypeable #-}\n{-# LANGUAGE StandaloneDeriving #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE TypeAbstractions #-}\n\n{-# OPTIONS_GHC -Wall -Werror #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.EquationalReasoning where\n\nimport Prelude hiding (map, foldl, foldr, (<>))\n\nimport Data.SBV\nimport Data.SBV.List\nimport Data.SBV.Tools.KnuckleDragger\n\n-- | Data declaration for an uninterpreted type, usually indicating source.\ndata A\nmkUninterpretedSort ''A\n\n-- | Data declaration for an uninterpreted type, usually indicating target.\ndata B\nmkUninterpretedSort ''B\n\n-- | Data declaration for an uninterpreted type, usually indicating an intermediate value.\ndata C\nmkUninterpretedSort ''C\n\n-- * Fold-map fusion\n\n-- | Fold-map fusion: @foldr f a . map g = foldr (f . g) a@\n--\n-- We have:\n--\n-- >>> foldMapFusion\n-- Lemma: foldMapFusion Q.E.D.\n-- [Proven] foldMapFusion\nfoldMapFusion :: IO Proof\nfoldMapFusion = runKD $ do\n let a :: SA\n a = uninterpret \"a\"\n\n g :: SC -> SB\n g = uninterpret \"g\"\n\n f :: SB -> SA -> SA\n f = uninterpret \"f\"\n\n p xs = foldr f a (map g xs) .== foldr (f . g) a xs\n\n lemma \"foldMapFusion\" (\\(Forall @\"xs\" xs) -> p xs) [induct p]\n\n\n{---------------------\n --- Can't converge\n\n-- | Fusion for foldr:\n--\n-- @\n-- Given f a = b and f (g x y) = h x (f y), for all x and y\n-- We have: f . foldr g a = foldr h b\n-- @\n--\n-- We have:\n--\n-- >>> foldrFusion\nfoldrFusion :: IO Proof\nfoldrFusion = runKD $ do\n let a :: SA\n a = uninterpret \"a\"\n\n b :: SB\n b = uninterpret \"b\"\n\n f :: SA -> SB\n f = uninterpret \"f\"\n\n g :: SC -> SA -> SA\n g = uninterpret \"g\"\n\n h :: SC -> SB -> SB\n h = uninterpret \"h\"\n\n p xs = f (foldr g a xs) .== foldr h b xs\n\n -- f a == b\n h1 <- axiom \"f a == b\" $ f a .== b\n\n -- forall x, y: f (g x) = h x (f y)\n h2 <- axiom \"f (g x) = h x (f y)\" $ \\(Forall @\"x\" x) (Forall @\"y\" y) -> f (g x y) .== h x (f y)\n\n chainLemmaWith z3{transcript = Just \"bad.smt2\"} \"foldrFusion\"\n (\\(Forall @\"xs\" xs) -> p xs)\n (\\x xs -> [ f (foldr g a (x .: xs))\n , f (g x (foldr g a xs))\n , h x (f (foldr g a xs))\n , h x (foldr h b xs)\n , foldr h b (x .: xs)\n ])\n [h1, h2, induct p]\n-}\n\n{----------------\n-- TODO: Can't converge on this either..\n-- | First duality theorem. Given:\n--\n-- @\n-- x @ (y @ z) = (x @ y) @ z (associativity of @)\n-- and e @ x = x (left unit)\n-- and x @ e = x (right unit)\n-- @\n--\n-- Prove:\n--\n-- @\n-- foldr (@) e xs = foldl (@) e xs\n-- @\n--\n-- We have:\n--\n-- >>> firstDuality\nfirstDuality :: IO Proof\nfirstDuality = runKD $ do\n let (@) :: SA -> SA -> SA\n (@) = uninterpret \"|@|\"\n\n e :: SA\n e = uninterpret \"e\"\n\n axm1 <- axiom \"@ is associative\" (\\(Forall @\"x\" x) (Forall @\"y\" y) (Forall @\"z\" z) -> x @ (y @ z) .== (x @ y) @ z)\n axm2 <- axiom \"e is left unit\" (\\(Forall @\"x\" x) -> e @ x .== x)\n axm3 <- axiom \"e is right unit\" (\\(Forall @\"x\" x) -> x @ e .== x)\n\n let p xs = foldr (@) e xs .== foldl (@) e xs\n\n -- Helper: foldl (@) (y @ z) xs = y @ foldl (@) z xs\n h <- do\n let hp y z xs = foldl (@) (y @ z) xs .== y @ foldl (@) z xs\n\n chainLemma \"foldl over @\"\n (\\(Forall @\"y\" y) (Forall @\"z\" z) (Forall @\"xs\" xs) -> hp y z xs)\n (\\y z x xs -> [ foldl (@) (y @ z) (x .: xs)\n , foldl (@) ((y @ z) @ x) xs\n , foldl (@)
-- |
-- Module : Documentation.SBV.Examples.KnuckleDragger.FoldrLaws
-- Module : Documentation.SBV.Examples.KnuckleDragger.EquationalReasoning
-- Copyright : (c) Levent Erkok
-- License : BSD3
-- Maintainer: [email protected]
-- Stability : experimental
--
-- Various fold related laws, inspired by Section 4.6 of Richard Bird's
-- classic book "Introduction to Functional Programming using Haskell,"
-- second edition.
-- Various equalities that arise in functional-programming. A good source
-- is the classic book "Introduction to Functional Programming using Haskell,"
-- second edition. (Section 4.6 and others.)
-----------------------------------------------------------------------------

{-# LANGUAGE CPP #-}
Expand All @@ -21,22 +21,101 @@

{-# OPTIONS_GHC -Wall -Werror #-}

module Documentation.SBV.Examples.KnuckleDragger.FoldLaws where
module Documentation.SBV.Examples.KnuckleDragger.EquationalReasoning where

import Prelude hiding (foldl, foldr, (<>))
import Prelude hiding (map, foldl, foldr, (<>))

import Data.SBV
import Data.SBV.List
import Data.SBV.Tools.KnuckleDragger

-- | Data declaration for an uninterpreted source type.
-- | Data declaration for an uninterpreted type, usually indicating source.
data A
mkUninterpretedSort ''A

-- | Data declaration for an uninterpreted target type.
-- | Data declaration for an uninterpreted type, usually indicating target.
data B
mkUninterpretedSort ''B

-- | Data declaration for an uninterpreted type, usually indicating an intermediate value.
data C
mkUninterpretedSort ''C

-- * Fold-map fusion

-- | Fold-map fusion: @foldr f a . map g = foldr (f . g) a@
--
-- We have:
--
-- >>> foldMapFusion
-- Lemma: foldMapFusion Q.E.D.
-- [Proven] foldMapFusion
foldMapFusion :: IO Proof
foldMapFusion = runKD $ do
let a :: SA
a = uninterpret "a"

g :: SC -> SB
g = uninterpret "g"

f :: SB -> SA -> SA
f = uninterpret "f"

p xs = foldr f a (map g xs) .== foldr (f . g) a xs

lemma "foldMapFusion" (\(Forall @"xs" xs) -> p xs) [induct p]


{---------------------
--- Can't converge
-- | Fusion for foldr:
--
-- @
-- Given f a = b and f (g x y) = h x (f y), for all x and y
-- We have: f . foldr g a = foldr h b
-- @
--
-- We have:
--
-- >>> foldrFusion
foldrFusion :: IO Proof
foldrFusion = runKD $ do
let a :: SA
a = uninterpret "a"
b :: SB
b = uninterpret "b"
f :: SA -> SB
f = uninterpret "f"
g :: SC -> SA -> SA
g = uninterpret "g"
h :: SC -> SB -> SB
h = uninterpret "h"
p xs = f (foldr g a xs) .== foldr h b xs
-- f a == b
h1 <- axiom "f a == b" $ f a .== b
-- forall x, y: f (g x) = h x (f y)
h2 <- axiom "f (g x) = h x (f y)" $ \(Forall @"x" x) (Forall @"y" y) -> f (g x y) .== h x (f y)
chainLemmaWith z3{transcript = Just "bad.smt2"} "foldrFusion"
(\(Forall @"xs" xs) -> p xs)
(\x xs -> [ f (foldr g a (x .: xs))
, f (g x (foldr g a xs))
, h x (f (foldr g a xs))
, h x (foldr h b xs)
, foldr h b (x .: xs)
])
[h1, h2, induct p]
-}

{----------------
-- TODO: Can't converge on this either..
-- | First duality theorem. Given:
--
Expand Down Expand Up @@ -85,6 +164,7 @@ firstDuality = runKD $ do
[axm1, axm2, induct hp]
lemma "firstDuality" (\(Forall @"xs" xs) -> p xs) [axm1, axm2, axm3, h, induct p]
-}

----------------------------------------------------------------------------------------
{- TODO: Can't converge on this one. The strengthened induction axiom requires a very careful
Expand Down
2 changes: 1 addition & 1 deletion sbv.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Library
, Documentation.SBV.Examples.KnuckleDragger.AppendRev
, Documentation.SBV.Examples.KnuckleDragger.Basics
, Documentation.SBV.Examples.KnuckleDragger.CaseSplit
, Documentation.SBV.Examples.KnuckleDragger.FoldLaws
, Documentation.SBV.Examples.KnuckleDragger.EquationalReasoning
, Documentation.SBV.Examples.KnuckleDragger.Kleene
, Documentation.SBV.Examples.KnuckleDragger.Induction
, Documentation.SBV.Examples.KnuckleDragger.ListLen
Expand Down

0 comments on commit eb5f1b6

Please sign in to comment.