Skip to content

KD: Make cvc5 easier to use from KD #535

KD: Make cvc5 easier to use from KD

KD: Make cvc5 easier to use from KD #535

Triggered via push September 21, 2024 00:03
Status Success
Total duration 1m 10s
Artifacts

hlint.yml

on: push
Fit to window
Zoom out
Zoom in

Annotations

10 errors and 15 warnings
hlint: Data/SBV/Tools/KnuckleDragger.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Data.SBV.Tools.KnuckleDragger\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- A lightweight theorem proving like interface, built on top of SBV.\n-- Inspired by and modeled after Philip Zucker's tool with the same\n-- name, see <http://github.com/philzook58/knuckledragger>.\n--\n-- See the directory Documentation.SBV.Examples.KnuckleDragger for various examples.\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE ConstraintKinds #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE DerivingStrategies #-}\n{-# LANGUAGE FlexibleContexts #-}\n{-# LANGUAGE FlexibleInstances #-}\n{-# LANGUAGE FunctionalDependencies #-}\n{-# LANGUAGE GeneralizedNewtypeDeriving #-}\n{-# LANGUAGE MultiParamTypeClasses #-}\n{-# LANGUAGE NamedFieldPuns #-}\n{-# LANGUAGE TypeAbstractions #-}\n\n{-# OPTIONS_GHC -Wall -Werror #-}\n\nmodule Data.SBV.Tools.KnuckleDragger (\n -- * Propositions and their proofs\n Proposition, Proof\n -- * Adding axioms/definitions\n , axiom\n -- * Basic proofs\n , lemma, lemmaWith\n , theorem, theoremWith\n -- * Chain of reasoning\n , chainLemma, chainLemmaWith\n , chainTheorem, chainTheoremWith\n -- * Induction\n , Induction(..)\n -- * Faking proofs\n , sorry\n -- * Running KnuckleDragger proofs\n , KD, runKD, runKDWith, KDConfig(..), defaultKDConfig, z3KD, cvc5KD\n ) where\n\nimport Control.Monad.Trans (liftIO)\n\nimport Data.SBV\nimport Data.SBV.Tools.KDKernel\nimport Data.SBV.Tools.KDUtils\n\nimport Control.Monad (when)\nimport Control.Monad.Reader (ask)\n\n-- | A class for doing equational reasoning style chained proofs. Use 'chainLemma' to prove a given theorem\n-- as a sequence of equalities, each step following from the previous.\nclass ChainLemma steps step | steps -> step where\n\n -- | Prove a property via a series of equality steps, using the default solver.\n -- Let @h@ be a list of already established lemmas. Let @p@ be a property we wanted to prove, named @name@.\n -- Consider a call of the form @chainLemma name P [A, B, C, D] H@. Note that @h@ is\n -- a list of already proven facts, ensured by the type signature. We proceed as follows:\n --\n -- * Prove: @h -> A == B@\n -- * Prove: @h && A == B -> B == C@\n -- * Prove: @h && A == B && B == C -> C == D@\n -- * Prove: @h && A == B && B == C && C == D -> P@\n -- * If all of the above steps succeed, conclude @p@.\n --\n -- So, chain-lemma is essentially modus-ponens, applied in a sequence of stepwise equality reasoning.\n --\n -- If there are no helpers given (i.e., if @h@ is empty), then this call is equivalent to 'lemmaWith'.\n -- If @h@ is a singleton, then we error-out. A single step in @h@ indicates a user-error, since there's\n -- no sequence of steps to reason about.\n chainLemma :: Proposition a => String -> a -> steps -> [Proof] -> KD Proof\n\n -- | Same as chainLemma, except tagged as Theorem\n chainTheorem :: Proposition a => String -> a -> steps -> [Proof] -> KD Proof\n\n -- | Prove a property via a series of equality steps, using the given solver.\n chainLemmaWith :: Proposition a => KDConfig -> String -> a -> steps -> [Proof] -> KD Proof\n\n -- | Same as chainLemmaWith, except tagged as Theorem\n chainTheoremWith :: Proposition a => KDConfig -> String -> a -> steps -> [Proof] -> KD Proof\n\n -- | Internal, shouldn't be needed outside the library\n makeSteps :: steps -> [step]\n makeInter :: steps -> step -> step -> SBool\n\n chainLemma nm p steps by = do cfg <- ask\n chainLemmaWith cfg nm p steps by\n\n chainTheorem nm p steps by = do cfg <- ask\n chainTheoremWith cfg nm p steps by\n\n chainLemmaWith = chainGeneric False\n chainTheoremWith = chainGeneric True\n\n chainGeneric :: Proposition a => Bool -> KDConfig -> String -> a -> steps -> [Proof] -> KD Proof\n chainGeneric taggedTheorem cfg nm result steps base = do\n liftIO $ putStrLn $ \"Chain: \" ++ nm\n let proofSteps =
hlint: Documentation/SBV/Examples/KnuckleDragger/AppendRev.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.AppendRev\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Example use of the KnuckleDragger, on list append and reverses.\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE DeriveAnyClass #-}\n{-# LANGUAGE DeriveDataTypeable #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE StandaloneDeriving #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE TypeAbstractions #-}\n{-# LANGUAGE TypeApplications #-}\n\n{-# OPTIONS_GHC -Wall -Werror #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.AppendRev where\n\nimport Prelude hiding (reverse, (++))\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\nimport Data.SBV.List ((.:), (++), reverse)\nimport qualified Data.SBV.List as SL\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | Use an uninterpreted type for the elements\ndata Elt\nmkUninterpretedSort ''Elt\n\n-- | @xs ++ [] == xs@\n--\n-- We have:\n--\n-- >>> runKD appendNull\n-- Lemma: appendNull Q.E.D.\nappendNull :: KD Proof\nappendNull = lemma \"appendNull\"\n (\\(Forall @\"xs\" (xs :: SList Elt)) -> xs ++ SL.nil .== xs)\n []\n\n-- | @(x : xs) ++ ys == x : (xs ++ ys)@\n--\n-- We have:\n--\n-- >>> runKD consApp\n-- Lemma: consApp Q.E.D.\nconsApp :: KD Proof\nconsApp = lemma \"consApp\"\n (\\(Forall @\"x\" (x :: SElt)) (Forall @\"xs\" xs) (Forall @\"ys\" ys) -> (x .: xs) ++ ys .== x .: (xs ++ ys))\n []\n\n-- | @(xs ++ ys) ++ zs == xs ++ (ys ++ zs)@\n--\n-- We have:\n--\n-- >>> runKD appendAssoc\n-- Lemma: appendAssoc Q.E.D.\nappendAssoc :: KD Proof\nappendAssoc = do\n -- The classic proof by induction on xs\n let p :: SymVal a => SList a -> SList a -> SList a -> SBool\n p xs ys zs = xs ++ (ys ++ zs) .== (xs ++ ys) ++ zs\n\n lemma \"appendAssoc\"\n (\\(Forall @\"xs\" (xs :: SList Elt)) (Forall @\"ys\" ys) (Forall @\"zs\" zs) -> p xs ys zs)\n []\n\n-- | @reverse (xs ++ ys) == reverse ys ++ reverse xs@\n-- We have:\n--\n-- >>> runKD revApp\n-- Lemma: revApp Q.E.D.\nrevApp :: KD Proof\nrevApp = do\n let q :: SymVal a => SList a -> SList a -> SBool\n q xs ys = reverse (xs ++ ys) .== reverse ys ++ reverse xs\n\n lemma \"revApp\" (\\(Forall @\"xs\" (xs :: SList Elt)) (Forall @\"ys\" ys) -> q xs ys)\n [induct2 (q @elt)]\n\n-- | @reverse (reverse xs) == xs@\n--\n-- We have:\n--\n-- >>> runKD reverseReverse\n-- Lemma: revApp Q.E.D.\n-- Lemma: reverseReverse Q.E.D.\nreverseReverse :: KD Proof\nreverseReverse = do\n lRevApp <- revApp\n\n let p :: SymVal a => SList a -> SBool\n p xs = reverse (reverse xs) .== xs\n\n lemma \"reverseReverse\"\n (\\(Forall @\"xs\" (xs :: SList Elt)) -> p xs)\n [induct (p @elt), lRevApp]\n"
hlint: Documentation/SBV/Examples/KnuckleDragger/Induction.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.Induction\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Example use of the KnuckleDragger, for some inductive proofs\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE TypeAbstractions #-}\n\n{-# OPTIONS_GHC -Wall -Werror #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.Induction where\n\nimport Prelude hiding (sum, length)\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | Prove that sum of constants @c@ from @0@ to @n@ is @n*c@.\n--\n-- We have:\n--\n-- >>> runKD sumConstProof\n-- Lemma: sumConst_correct Q.E.D.\nsumConstProof :: KD Proof\nsumConstProof = do\n let sum :: SInteger -> SInteger -> SInteger\n sum = smtFunction \"sum\" $ \\n c -> ite (n .== 0) 0 (c + sum (n-1) c)\n\n spec :: SInteger -> SInteger -> SInteger\n spec n c = n * c\n\n p :: SInteger -> SInteger -> SBool\n p n c = observe \"imp\" (sum n c) .== observe \"spec\" (spec n c)\n\n lemma \"sumConst_correct\" (\\(Forall @\"n\" n) (Forall @\"c\" c) -> n .>= 0 .=> p n c) [induct2 p]\n\n-- | Prove that sum of numbers from @0@ to @n@ is @n*(n-1)/2@.\n--\n-- We have:\n--\n-- >>> runKD sumProof\n-- Lemma: sum_correct Q.E.D.\nsumProof :: KD Proof\nsumProof = do\n let sum :: SInteger -> SInteger\n sum = smtFunction \"sum\" $ \\n -> ite (n .== 0) 0 (n + sum (n - 1))\n\n spec :: SInteger -> SInteger\n spec n = (n * (n+1)) `sDiv` 2\n\n p :: SInteger -> SBool\n p n = observe \"imp\" (sum n) .== observe \"spec\" (spec n)\n\n lemma \"sum_correct\" (\\(Forall @\"n\" n) -> n .>= 0 .=> p n) [induct p]\n\n-- | Prove that sum of square of numbers from @0@ to @n@ is @n*(n+1)*(2n+1)/6@.\n--\n-- We have:\n--\n-- >>> runKD sumSquareProof\n-- Lemma: sumSquare_correct Q.E.D.\nsumSquareProof :: KD Proof\nsumSquareProof = do\n let sumSquare :: SInteger -> SInteger\n sumSquare = smtFunction \"sumSquare\" $ \\n -> ite (n .== 0) 0 (n * n + sumSquare (n - 1))\n\n spec :: SInteger -> SInteger\n spec n = (n * (n+1) * (2*n+1)) `sDiv` 6\n\n p :: SInteger -> SBool\n p n = observe \"imp\" (sumSquare n) .== observe \"spec\" (spec n)\n\n lemma \"sumSquare_correct\" (\\(Forall @\"n\" n) -> n .>= 0 .=> p n) [induct p]\n"
hlint: Documentation/SBV/Examples/KnuckleDragger/Kleene.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.Kleene\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Example use of the KnuckleDragger layer, proving some Kleene algebra theorems.\n--\n-- Based on <http://www.philipzucker.com/bryzzowski_kat/>\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE DeriveAnyClass #-}\n{-# LANGUAGE DeriveDataTypeable #-}\n{-# LANGUAGE FlexibleInstances #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE StandaloneDeriving #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE TypeAbstractions #-}\n{-# LANGUAGE TypeSynonymInstances #-}\n\n{-# OPTIONS_GHC -Wall -Werror -Wno-unused-matches #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.Kleene where\n\nimport Prelude hiding((<=))\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | An uninterpreted sort, corresponding to the type of Kleene algebra strings.\ndata Kleene\nmkUninterpretedSort ''Kleene\n\n-- | Star operator over kleene algebras. We're leaving this uninterpreted.\nstar :: SKleene -> SKleene\nstar = uninterpret \"star\"\n\n-- | The 'Num' instance for Kleene makes it easy to write regular expressions\n-- in the more familiar form.\ninstance Num SKleene where\n (+) = uninterpret \"par\"\n (*) = uninterpret \"seq\"\n\n abs = error \"SKleene: not defined: abs\"\n signum = error \"SKleene: not defined: signum\"\n negate = error \"SKleene: not defined: signum\"\n\n fromInteger 0 = uninterpret \"zero\"\n fromInteger 1 = uninterpret \"one\"\n fromInteger n = error $ \"SKleene: not defined: fromInteger \" ++ show n\n\n-- | The set of strings matched by one regular expression is a subset of the second,\n-- if adding it to the second doesn't change the second set.\n(<=) :: SKleene -> SKleene -> SBool\nx <= y = x + y .== y\n\n-- | A sequence of Kleene algebra proofs. See <http://www.cs.cornell.edu/~kozen/Papers/ka.pdf>\n--\n-- We have:\n--\n-- >>> runKD kleeneProofs\n-- Axiom: par_assoc Axiom.\n-- Axiom: par_comm Axiom.\n-- Axiom: par_idem Axiom.\n-- Axiom: par_zero Axiom.\n-- Axiom: seq_assoc Axiom.\n-- Axiom: seq_zero Axiom.\n-- Axiom: seq_one Axiom.\n-- Axiom: rdistrib Axiom.\n-- Axiom: ldistrib Axiom.\n-- Axiom: unfold Axiom.\n-- Axiom: least_fix Axiom.\n-- Lemma: par_lzero Q.E.D.\n-- Lemma: par_monotone Q.E.D.\n-- Lemma: seq_monotone Q.E.D.\n-- Chain: star_star_1\n-- Lemma: star_star_1.1 Q.E.D.\n-- Lemma: star_star_1.2 Q.E.D.\n-- Lemma: star_star_1.3 Q.E.D.\n-- Lemma: star_star_1.4 Q.E.D.\n-- Lemma: star_star_1 Q.E.D.\n-- Lemma: subset_eq Q.E.D.\n-- Lemma: star_star_2_2 Q.E.D.\n-- Lemma: star_star_2_3 Q.E.D.\n-- Lemma: star_star_2_1 Q.E.D.\n-- Lemma: star_star_2 Q.E.D.\nkleeneProofs :: KD ()\nkleeneProofs = do\n\n -- Kozen axioms\n par_assoc <- axiom \"par_assoc\" $ \\(Forall @\"x\" (x :: SKleene)) (Forall @\"y\" y) (Forall @\"z\" z) -> x + (y + z) .== (x + y) + z\n par_comm <- axiom \"par_comm\" $ \\(Forall @\"x\" (x :: SKleene)) (Forall @\"y\" y) -> x + y .== y + x\n par_idem <- axiom \"par_idem\" $ \\(Forall @\"x\" (x :: SKleene)) -> x + x .== x\n par_zero <- axiom \"par_zero\" $ \\(Forall @\"x\" (x :: SKleene)) -> x + 0 .== x\n\n seq_assoc <- axiom \"seq_assoc\" $ \\(Forall @\"x\" (x :: SKleene)) (Forall @\"y\" y) (Forall @\"z\" z) -> x * (y * z) .== (x * y) * z\n seq_zero <- axiom \"seq_zero\" $ \\(Forall @\"x\" (x :: SKleene)) -> x * 0 .== 0\n seq_one <- axiom \"seq_one\" $ \\(Forall @\"x\" (x :: SKleene)) -> x * 1 .== x\n\n rdistrib <- axiom \"rdistrib\" $ \\(Forall @\"x\" (x :: SKleene)) (Forall @\"y\" y) (Forall @\"z\" z) -> x * (y + z) .== x * y + x * z\n ldistrib <- axiom \"ldistrib\" $ \\(Forall @\"x\" (x :: SKleene)) (Forall @\"y\" y) (Forall @\"z\" z) -> (y + z) * x .== y * x +
hlint: Documentation/SBV/Examples/KnuckleDragger/ListLen.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.ListLen\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Example use of the KnuckleDragger, about lenghts of lists\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE DeriveAnyClass #-}\n{-# LANGUAGE DeriveDataTypeable #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE StandaloneDeriving #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE TypeAbstractions #-}\n{-# LANGUAGE TypeApplications #-}\n\n{-# OPTIONS_GHC -Wall -Werror -Wno-unused-do-bind #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.ListLen where\n\nimport Prelude hiding (sum, length, reverse, (++))\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\nimport qualified Data.SBV.List as SL\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> :set -XScopedTypeVariables\n-- >>> import Control.Exception\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | Use an uninterpreted type for the elements\ndata Elt\nmkUninterpretedSort ''Elt\n\n-- | Prove that the length of a list is one more than the length of its tail.\n--\n-- We have:\n--\n-- >>> runKD listLengthProof\n-- Lemma: length_correct Q.E.D.\nlistLengthProof :: KD Proof\nlistLengthProof = do\n let length :: SList Elt -> SInteger\n length = smtFunction \"length\" $ \\xs -> ite (SL.null xs) 0 (1 + length (SL.tail xs))\n\n spec :: SList Elt -> SInteger\n spec = SL.length\n\n p :: SList Elt -> SBool\n p xs = observe \"imp\" (length xs) .== observe \"spec\" (spec xs)\n\n lemma \"length_correct\" (\\(Forall @\"xs\" xs) -> p xs) [induct p]\n\n-- | It is instructive to see what kind of counter-example we get if a lemma fails to prove.\n-- Below, we do a variant of the 'listLengthProof', but with a bad implementation over integers,\n-- and see the counter-example. Our implementation returns an incorrect answer if the given list is longer\n-- than 5 elements and have 42 in it. We have:\n--\n-- >>> runKD badProof `catch` (\\(_ :: SomeException) -> pure ())\n-- Lemma: bad\n-- *** Failed to prove bad.\n-- Falsifiable. Counter-example:\n-- xs = [8,25,26,27,28,42] :: [Integer]\n-- imp = 42 :: Integer\n-- spec = 6 :: Integer\nbadProof :: KD ()\nbadProof = do\n let length :: SList Integer -> SInteger\n length = smtFunction \"length\" $ \\xs -> ite (SL.null xs) 0 (1 + length (SL.tail xs))\n\n badLength :: SList Integer -> SInteger\n badLength xs = ite (SL.length xs .> 5 .&& 42 `SL.elem` xs) 42 (length xs)\n\n spec :: SList Integer -> SInteger\n spec = SL.length\n\n p :: SList Integer -> SBool\n p xs = observe \"imp\" (badLength xs) .== observe \"spec\" (spec xs)\n\n lemma \"bad\" (\\(Forall @\"xs\" xs) -> p xs) [induct p]\n\n pure ()\n\n-- | @Length (xs ++ ys) == length xs + length ys@\n--\n-- We have:\n--\n-- >>> runKD lenAppend\n-- Lemma: lenAppend Q.E.D.\nlenAppend :: KD Proof\nlenAppend = lemma \"lenAppend\"\n (\\(Forall @\"xs\" (xs :: SList Elt)) (Forall @\"ys\" ys) ->\n SL.length (xs SL.++ ys) .== SL.length xs + SL.length ys)\n []\n\n-- | @Length xs == length ys -> length (xs ++ ys) == 2 * length xs@\n--\n-- We have:\n--\n-- >>> runKD lenAppend2\n-- Lemma: lenAppend2 Q.E.D.\nlenAppend2 :: KD Proof\nlenAppend2 = lemma \"lenAppend2\"\n (\\(Forall @\"xs\" (xs :: SList Elt)) (Forall @\"ys\" ys) ->\n SL.length xs .== SL.length ys\n .=> SL.length (xs SL.++ ys) .== 2 * SL.length xs)\n []\n"
hlint: Documentation/SBV/Examples/KnuckleDragger/RevLen.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.RevLen\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Proof that reversing a list does not change its length.\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 -Wno-unused-do-bind #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.RevLen where\n\nimport Prelude hiding (length, reverse)\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\nimport Data.SBV.List (reverse, length)\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> :set -XScopedTypeVariables\n-- >>> import Control.Exception\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | Use an uninterpreted type for the elements\ndata Elt\nmkUninterpretedSort ''Elt\n\n-- | @Length xs == length (reverse xs)@\n--\n-- We have:\n--\n-- >>> runKD revLen\n-- Lemma: revLen Q.E.D.\nrevLen :: KD Proof\nrevLen = do\n let p :: SList Elt -> SBool\n p xs = length (reverse xs) .== length xs\n\n lemma \"revLen\"\n (\\(Forall @\"xs\" xs) -> p xs)\n [induct p]\n\n-- | An example where we attempt to prove a non-theorem. Notice the counter-example\n-- generated for:\n--\n-- @Length xs = ite (length xs .== 3) 5 (length xs)@\n--\n-- We have:\n--\n-- >>> runKD badRevLen `catch` (\\(_ :: SomeException) -> pure ())\n-- Lemma: badRevLen\n-- *** Failed to prove badRevLen.\n-- Falsifiable. Counter-example:\n-- xs = [Elt!val!1,Elt!val!2,Elt!val!1] :: [Elt]\nbadRevLen :: KD ()\nbadRevLen = do\n let p :: SList Elt -> SBool\n p xs = length (reverse xs) .== ite (length xs .== 3) 5 (length xs)\n\n lemma \"badRevLen\"\n (\\(Forall @\"xs\" xs) -> p xs)\n [induct p]\n\n pure ()\n"
hlint: Documentation/SBV/Examples/KnuckleDragger/Sqrt2IsIrrational.hs#L1
Error: Parse error: Unsupported extension: TypeAbstractions ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.KnuckleDragger.Sqrt2IsIrrational\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Prove that square-root of 2 is irrational.\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DataKinds #-}\n{-# LANGUAGE ScopedTypeVariables #-}\n{-# LANGUAGE TypeAbstractions #-}\n\n{-# OPTIONS_GHC -Wall -Werror -Wno-unused-matches #-}\n\nmodule Documentation.SBV.Examples.KnuckleDragger.Sqrt2IsIrrational where\n\nimport Prelude hiding (even, odd)\n\nimport Data.SBV\nimport Data.SBV.Tools.KnuckleDragger\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> import Data.SBV.Tools.KnuckleDragger(runKD)\n\n\n-- | Prove that square-root of @2@ is irrational. That is, we can never find @A@ and @b@ such that\n-- @sqrt 2 == a / b@ and @A@ and @b@ are co-prime.\n--\n-- In order not to deal with reals and square-roots, we prove the integer-only alternative:\n-- If @A^2 = 2b^2@, then @A@ and @b@ cannot be co-prime. We proceed by establishing the\n-- following helpers first:\n--\n-- (1) An odd number squared is odd: @odd x -> odd x^2@\n-- (2) An even number that is a perfect square must be the square of an even number: @even x^2 -> even x@.\n-- (3) If a number is even, then its square must be a multiple of 4: @even x .=> x*x % 4 == 0@.\n--\n-- Using these helpers, we can argue:\n--\n-- (4) Start with the premise @A^2 = 2b^2@.\n-- (5) Thus, @A^2@ must be even. (Since it equals @2b^2@ by a.)\n-- (6) Thus, @A@ must be even. (Using 2 and b.)\n-- (7) Thus, @A^2@ must be divisible by @4@. (Using 3 and c. That is, 2b^2 == 4*K for someK.)\n-- (8) Thus, @b^2@ must be even. (Using d, b^2 = 2K.)\n-- (9) Thus, @b@ must be even. (Using 2 and e.)\n-- (10) Since @A@ and @b@ are both even, they cannot be co-prime. (Using c and f.)\n--\n-- Note that our proof is mostly about the first 3 facts above, then z3 and KnuckleDragger fills in the rest.\n--\n-- We have:\n--\n-- >>> runKD sqrt2IsIrrational\n-- Lemma: expandOddXInSq Q.E.D.\n-- Lemma: oddSquaredIsOdd Q.E.D.\n-- Lemma: evenIfSquareIsEven Q.E.D.\n-- Lemma: evenSquaredIsMult4 Q.E.D.\n-- Lemma: sqrt2IsIrrational Q.E.D.\nsqrt2IsIrrational :: KD Proof\nsqrt2IsIrrational = do\n let even, odd :: SInteger -> SBool\n even = (2 `sDivides`)\n odd = sNot . even\n\n sq :: SInteger -> SInteger\n sq x = x * x\n\n -- Prove that an odd number squared gives you an odd number.\n -- Interestingly, the solver doesn't need the analogous theorem that even number\n -- squared is even, possibly because the even/odd definition above is enough for\n -- it to deduce that fact automatically.\n oddSquaredIsOdd <- do\n\n -- Help the solver by explicitly proving that if @x@ is odd, then it can be written as @2k+1@.\n -- We do need to do this in a bit of a round about way, proving @sq x@ is the square\n -- of another odd number, as that seems to help z3 do better quantifier instantiation.\n --\n -- Note that, instead of using an existential quantifier for k, we actually tell\n -- the solver what the witness is, which makes the proof go through.\n expandOddXInSq <- lemma \"expandOddXInSq\"\n (\\(Forall @\"x\" x) -> odd x .=> sq x .== sq (2 * (x `sDiv` 2) + 1))\n []\n\n lemma \"oddSquaredIsOdd\"\n (\\(Forall @\"x\" x) -> odd x .=> odd (sq x))\n [expandOddXInSq]\n\n -- Prove that if a perfect square is even, then it be the square of an even number. For z3, the above proof\n -- is enough to establish this.\n evenIfSquareIsEven <- lemma \"evenIfSquareIsEven\" (\\(Forall @\"x\" x) -> even (sq x) .=> even x) [oddSquaredIsOdd]\n\n -- Prove that if @A@ is an even number, then its square is four times the square of another.\n -- Happily, z3 needs no helpers to establish this all on its own.\n evenSquaredIsMult4 <- lemma \"evenSquaredIsMult4\"\n (\\(Forall @\"a\" a) -> even a .=> quantifiedBool (\\(Exists @\"b\" b) -> sq a
hlint: Documentation/SBV/Examples/Misc/FirstOrderLogic.hs#L290
Error: Parse error: Expression syntax in pattern: Forall @"x" ▫︎ Found: " skolemEx4 = sat cs\n where cs :: ConstraintSet\n> cs = do constrain $ taggedSkolemize \"c1\" $ \\(Forall @\"x\" x) (Exists @\"y\" y) -> x .== (y :: SInteger)\n constrain $ taggedSkolemize \"c2\" $ \\(Forall @\"x\" x) (Exists @\"y\" y) -> x .== (y-1 :: SInteger)\n"
hlint: Documentation/SBV/Examples/Puzzles/Orangutans.hs#L1
Error: Parse error: Unsupported extension: OverloadedRecordDot ▫︎ Found: "-----------------------------------------------------------------------------\n-- |\n-- Module : Documentation.SBV.Examples.Puzzles.Orangutans\n-- Copyright : (c) Levent Erkok\n-- License : BSD3\n-- Maintainer: [email protected]\n-- Stability : experimental\n--\n-- Based on <http://github.com/goldfirere/video-resources/blob/main/2022-08-12-java/Haskell.hs>\n-----------------------------------------------------------------------------\n\n{-# LANGUAGE CPP #-}\n{-# LANGUAGE DeriveAnyClass #-}\n{-# LANGUAGE DeriveDataTypeable #-}\n{-# LANGUAGE DeriveGeneric #-}\n{-# LANGUAGE FlexibleContexts #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE StandaloneDeriving #-}\n{-# LANGUAGE OverloadedRecordDot #-}\n\n{-# OPTIONS_GHC -Wall -Werror #-}\n\nmodule Documentation.SBV.Examples.Puzzles.Orangutans where\n\nimport Data.SBV\nimport GHC.Generics (Generic)\n\n\n-- $setup\n-- >>> -- For doctest purposes only:\n-- >>> import Data.SBV\n\n\n-- | Orangutans in the puzzle.\ndata Orangutan = Merah | Ofallo | Quirrel | Shamir deriving (Enum, Bounded)\n\n-- | Handlers for each orangutan.\ndata Handler = Dolly | Eva | Francine | Gracie\n\n-- | Location for each orangutan.\ndata Location = Ambalat | Basahan | Kendisi | Tarakan\n\nmkSymbolicEnumeration ''Orangutan\nmkSymbolicEnumeration ''Handler\nmkSymbolicEnumeration ''Location\n\n-- | An assignment is solution to the puzzle\ndata Assignment = MkAssignment { orangutan :: SOrangutan\n , handler :: SHandler\n , location :: SLocation\n , age :: SInteger\n }\n deriving (Generic, Mergeable)\n\n-- | Create a symbolic assignment, using symbolic fields.\nmkSym :: Orangutan -> Symbolic Assignment\nmkSym o = do let h = show o ++ \".handler\"\n l = show o ++ \".location\"\n a = show o ++ \".age\"\n s <- MkAssignment (literal o) <$> free h <*> free l <*> free a\n constrain $ s.age `sElem` [4, 7, 10, 13]\n pure s\n\n-- | We get:\n--\n-- >>> allSat puzzle\n-- Solution #1:\n-- Merah.handler = Gracie :: Handler\n-- Merah.location = Tarakan :: Location\n-- Merah.age = 10 :: Integer\n-- Ofallo.handler = Eva :: Handler\n-- Ofallo.location = Kendisi :: Location\n-- Ofallo.age = 13 :: Integer\n-- Quirrel.handler = Dolly :: Handler\n-- Quirrel.location = Basahan :: Location\n-- Quirrel.age = 4 :: Integer\n-- Shamir.handler = Francine :: Handler\n-- Shamir.location = Ambalat :: Location\n-- Shamir.age = 7 :: Integer\n-- This is the only solution.\npuzzle :: ConstraintSet\npuzzle = do\n solution@[_merah, ofallo, quirrel, shamir] <- mapM mkSym [minBound .. maxBound]\n\n let find f = foldr1 (\\a1 a2 -> ite (f a1) a1 a2) solution\n\n -- 0. All are different in terms of handlers, locations, and ages\n constrain $ distinct (map (.handler) solution)\n constrain $ distinct (map (.location) solution)\n constrain $ distinct (map (.age) solution)\n\n -- 1. Shamir is 7 years old.\n constrain $ shamir.age .== 7\n\n -- 2. Shamir came from Ambalat.\n constrain $ shamir.location .== sAmbalat\n\n -- 3. Quirrel is younger than the ape that was found in Tarakan.\n let tarakan = find (\\a -> a.location .== sTarakan)\n constrain $ quirrel.age .< tarakan.age\n\n -- 4. Of Ofallo and the ape that was found in Tarakan, one is cared for by Gracie and the other is 13 years old.\n let clue4 a1 a2 = a1.handler .== sGracie .&& a2.age .== 13\n constrain $ clue4 ofallo tarakan .|| clue4 tarakan ofallo\n constrain $ sOfallo ./= tarakan.orangutan\n\n -- 5. The animal that was found in Ambalat is either the 10-year-old or the animal Francine works with.\n let ambalat = find (\\a -> a.location .== sAmbalat)\n constrain $ ambalat.age .== 10 .|| ambalat.handler .== sFrancine\n\n -- 6. Ofallo isn't 10 years old.\n constrain $ ofallo.age ./= 10\n\n -- 7. The ape that was found in Kendisi is older than the ape Dolly works with.\n let kendisi = find (\\a -> a.location .== sKendisi)\n let dolly = find (\\a -> a.handler .== sDolly)\n constrain $ kendisi.age .> dolly.age\n"
hlint: SBVTestSuite/TestSuite/Basics/Quantifiers.hs#L45
Error: Parse error: Expression syntax in pattern: ExistsN @4 ▫︎ Found: " ]\n \n> others = [ goldenCapturedIO \"quantifiedB_0\" $ check $ \\(ExistsN @4 xs) -> sAll (.< (20 :: SWord8)) xs .&& sum (1 : xs) .== (0::SWord8)\n , goldenCapturedIO \"quantifiedB_1\" $ check $ \\(ExistsN @4 xs) -> sum xs .== (0::SWord8)\n , goldenCapturedIO \"quantifiedB_2\" $ check $ \\k (ForallN @4 xs) -> sum xs .== (k::SWord8)\n"
hlint
The following actions uses node12 which is deprecated and will be forced to run on node16: actions/checkout@v2, rwe/actions-hlint-setup@v1, rwe/actions-hlint-run@v2. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/
hlint
The following actions use a deprecated Node.js version and will be forced to run on node20: actions/checkout@v2, rwe/actions-hlint-setup@v1, rwe/actions-hlint-run@v2. For more info: https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/
hlint: Data/SBV/Core/Data.hs#L19
Warning in module Data.SBV.Core.Data: Unused LANGUAGE pragma ▫︎ Found: "{-# LANGUAGE InstanceSigs #-}"
hlint: Data/SBV/Core/Data.hs#L819
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SInteger)" ▫︎ Perhaps: "SInteger"
hlint: Data/SBV/Core/Data.hs#L819
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(KUnbounded)" ▫︎ Perhaps: "KUnbounded"
hlint: Data/SBV/Core/Data.hs#L819
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(KUnbounded)" ▫︎ Perhaps: "KUnbounded"
hlint: Data/SBV/Core/Data.hs#L820
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SWord8)" ▫︎ Perhaps: "SWord8"
hlint: Data/SBV/Core/Data.hs#L821
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SWord16)" ▫︎ Perhaps: "SWord16"
hlint: Data/SBV/Core/Data.hs#L822
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SWord32)" ▫︎ Perhaps: "SWord32"
hlint: Data/SBV/Core/Data.hs#L823
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SWord64)" ▫︎ Perhaps: "SWord64"
hlint: Data/SBV/Core/Data.hs#L824
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SInt8)" ▫︎ Perhaps: "SInt8"
hlint: Data/SBV/Core/Data.hs#L825
Warning in module Data.SBV.Core.Data: Redundant bracket ▫︎ Found: "(SInt16)" ▫︎ Perhaps: "SInt16"
hlint
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
hlint
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
hlint
The `set-output` command is deprecated and will be disabled soon. Please upgrade to using Environment Files. For more information see: https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/