{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE FlexibleInstances #-}
module ATP.Pretty.FOL (
Pretty(..),
pprint,
hprint
) where
import Control.Applicative (liftA2)
import Control.Monad (foldM)
import Data.Char (digitToInt)
import Data.Foldable (toList)
import Data.Functor (($>))
import Data.List (genericIndex, find)
import Data.List.NonEmpty (NonEmpty(..), nonEmpty)
import Data.Map (Map, (!))
import qualified Data.Text as T (unpack, null)
import System.IO (Handle)
import Text.PrettyPrint.ANSI.Leijen hiding ((<$>))
import ATP.Internal.Enumeration
import ATP.Error
import ATP.FOL
pprint :: Pretty a => a -> IO ()
pprint :: a -> IO ()
pprint = Doc -> IO ()
putDoc (Doc -> IO ()) -> (a -> Doc) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. Pretty a => a -> Doc
pretty
hprint :: Pretty a => Handle -> a -> IO ()
hprint :: Handle -> a -> IO ()
hprint Handle
h = Handle -> Doc -> IO ()
hPutDoc Handle
h (Doc -> IO ()) -> (a -> Doc) -> a -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Doc
forall a. Pretty a => a -> Doc
pretty
prettySequent :: Pretty a => Doc -> a -> Doc
prettySequent :: Doc -> a -> Doc
prettySequent Doc
h a
f = Doc -> Doc
bold (Doc
h Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
dot) Doc -> Doc -> Doc
<+> a -> Doc
forall a. Pretty a => a -> Doc
pretty a
f Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
line
prettySequents :: Pretty a => Doc -> [a] -> Doc
prettySequents :: Doc -> [a] -> Doc
prettySequents Doc
h = [Doc] -> Doc
hcat ([Doc] -> Doc) -> ([a] -> [Doc]) -> [a] -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Integer -> a -> Doc) -> [Integer] -> [a] -> [Doc]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Integer -> a -> Doc
forall a. Pretty a => Integer -> a -> Doc
sequent [Integer
1..]
where sequent :: Integer -> a -> Doc
sequent Integer
i = Doc -> a -> Doc
forall a. Pretty a => Doc -> a -> Doc
prettySequent (Doc
h Doc -> Doc -> Doc
<+> Integer -> Doc
integer Integer
i)
prettyVar :: Var -> Doc
prettyVar :: Integer -> Doc
prettyVar Integer
v = Doc -> Doc
cyan (Doc -> Doc) -> (String -> Doc) -> String -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Doc
text (String -> Doc) -> String -> Doc
forall a b. (a -> b) -> a -> b
$ [String] -> Integer -> String
forall i a. Integral i => [a] -> i -> a
genericIndex [String]
variables (Integer -> Integer
forall a. Num a => a -> a
abs Integer
v)
where
variables :: [String]
variables :: [String]
variables = (Integer -> String -> String) -> [Integer] -> [String] -> [String]
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Integer -> String -> String
prime [Integer
0..] [String
"v", String
"x", String
"y", String
"z", String
"t"]
prime :: Integer -> String -> String
prime :: Integer -> String -> String
prime Integer
n String
w = String
letter String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
index
where
letter :: String
letter = if Integer
v Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
>= Integer
0 then String
w else String
w String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"′"
index :: String
index = if Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 then String
"" else (Int -> Char) -> [Int] -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String
"₀₁₂₃₄₅₆₇₈₉" String -> Int -> Char
forall a. [a] -> Int -> a
!!) (Integer -> [Int]
digits Integer
n)
digits :: Integer -> [Int]
digits = (Char -> Int) -> String -> [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Int
digitToInt (String -> [Int]) -> (Integer -> String) -> Integer -> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> String
forall a. Show a => a -> String
show
sepBy :: Doc -> NonEmpty Doc -> Doc
sepBy :: Doc -> NonEmpty Doc -> Doc
sepBy Doc
s = (Doc -> Doc -> Doc) -> NonEmpty Doc -> Doc
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldl1 (\Doc
a Doc
b -> Doc
a Doc -> Doc -> Doc
<+> Doc
s Doc -> Doc -> Doc
<+> Doc
b)
commaSep :: NonEmpty Doc -> Doc
commaSep :: NonEmpty Doc -> Doc
commaSep (Doc
d :| [Doc]
ds) = Doc -> Doc
align (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ Doc
d Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> [Doc] -> Doc
forall a. Monoid a => [a] -> a
mconcat ((Doc -> Doc) -> [Doc] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Doc
comma Doc -> Doc -> Doc
<+>) [Doc]
ds)
prettyApplication :: Doc -> [Doc] -> Doc
prettyApplication :: Doc -> [Doc] -> Doc
prettyApplication Doc
s [Doc]
as
| Just NonEmpty Doc
as' <- [Doc] -> Maybe (NonEmpty Doc)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Doc]
as = Doc
s Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc -> Doc
parens (NonEmpty Doc -> Doc
commaSep NonEmpty Doc
as')
| Bool
otherwise = Doc
s
prettyParens :: Pretty e => (e -> Bool) -> e -> Doc
prettyParens :: (e -> Bool) -> e -> Doc
prettyParens e -> Bool
simple e
e
| e -> Bool
simple e
e = e -> Doc
forall a. Pretty a => a -> Doc
pretty e
e
| Bool
otherwise = Doc -> Doc
parens (e -> Doc
forall a. Pretty a => a -> Doc
pretty e
e)
instance Pretty FunctionSymbol where
pretty :: FunctionSymbol -> Doc
pretty (FunctionSymbol Text
s) = String -> Doc
text (Text -> String
T.unpack Text
s)
instance Pretty Term where
pretty :: Term -> Doc
pretty = \case
Variable Integer
v -> Integer -> Doc
prettyVar Integer
v
Function FunctionSymbol
f [Term]
ts -> Doc -> [Doc] -> Doc
prettyApplication (FunctionSymbol -> Doc
forall a. Pretty a => a -> Doc
pretty FunctionSymbol
f) ((Term -> Doc) -> [Term] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Term -> Doc
forall a. Pretty a => a -> Doc
pretty [Term]
ts)
instance Pretty PredicateSymbol where
pretty :: PredicateSymbol -> Doc
pretty (PredicateSymbol Text
p) = String -> Doc
text (Text -> String
T.unpack Text
p)
instance Pretty Literal where
pretty :: Literal -> Doc
pretty = \case
Propositional Bool
True -> Doc -> Doc
blue Doc
"⟙"
Propositional Bool
False -> Doc -> Doc
blue Doc
"⟘"
Predicate PredicateSymbol
p [Term]
ts -> Doc -> [Doc] -> Doc
prettyApplication (PredicateSymbol -> Doc
forall a. Pretty a => a -> Doc
pretty PredicateSymbol
p) ((Term -> Doc) -> [Term] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Term -> Doc
forall a. Pretty a => a -> Doc
pretty [Term]
ts)
Equality Term
a Term
b -> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
a Doc -> Doc -> Doc
<+> Doc
"=" Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
b
instance Pretty (Signed Literal) where
pretty :: Signed Literal -> Doc
pretty = \case
Signed Sign
Negative (Equality Term
a Term
b) -> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
a Doc -> Doc -> Doc
<+> Doc
"!=" Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
b
Signed Sign
Negative Literal
l -> Doc -> Doc
blue Doc
"¬" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
l
Signed Sign
Positive Literal
l -> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
l
instance Pretty Clause where
pretty :: Clause -> Doc
pretty (Literals [Signed Literal]
ls) = case [Signed Literal] -> Maybe (NonEmpty (Signed Literal))
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [Signed Literal]
ls of
Maybe (NonEmpty (Signed Literal))
Nothing -> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty (Bool -> Literal
Propositional Bool
False)
Just NonEmpty (Signed Literal)
nls -> Doc -> NonEmpty Doc -> Doc
sepBy (Connective -> Doc
forall a. Pretty a => a -> Doc
pretty Connective
Or) ((Signed Literal -> Doc)
-> NonEmpty (Signed Literal) -> NonEmpty Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Signed Literal -> Doc
forall a. Pretty a => a -> Doc
pretty NonEmpty (Signed Literal)
nls)
prettyList :: [Clause] -> Doc
prettyList = Doc -> [Clause] -> Doc
forall a. Pretty a => Doc -> [a] -> Doc
prettySequents Doc
"Axiom"
instance Pretty Connective where
pretty :: Connective -> Doc
pretty = Doc -> Doc
blue (Doc -> Doc) -> (Connective -> Doc) -> Connective -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
Connective
And -> Doc
"⋀"
Connective
Or -> Doc
"⋁"
Connective
Implies -> Doc
"=>"
Connective
Equivalent -> Doc
"<=>"
Connective
Xor -> Doc
"<~>"
instance Pretty Quantifier where
pretty :: Quantifier -> Doc
pretty = \case
Quantifier
Forall -> Doc
"∀"
Quantifier
Exists -> Doc
"∃"
instance Pretty Formula where
pretty :: Formula -> Doc
pretty = \case
Atomic Literal
l -> Literal -> Doc
forall a. Pretty a => a -> Doc
pretty Literal
l
Negate (Atomic (Equality Term
a Term
b)) -> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
a Doc -> Doc -> Doc
<+> Doc
"!=" Doc -> Doc -> Doc
<+> Term -> Doc
forall a. Pretty a => a -> Doc
pretty Term
b
Negate Formula
f -> Doc -> Doc
blue Doc
"¬" Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> (Formula -> Bool) -> Formula -> Doc
forall e. Pretty e => (e -> Bool) -> e -> Doc
prettyParens Formula -> Bool
unitary Formula
f
Connected Connective
c Formula
f Formula
g -> (Formula -> Bool) -> Formula -> Doc
forall e. Pretty e => (e -> Bool) -> e -> Doc
prettyParens (Connective -> Formula -> Bool
under Connective
c) Formula
f Doc -> Doc -> Doc
<+> Connective -> Doc
forall a. Pretty a => a -> Doc
pretty Connective
c
Doc -> Doc -> Doc
<+> (Formula -> Bool) -> Formula -> Doc
forall e. Pretty e => (e -> Bool) -> e -> Doc
prettyParens (Connective -> Formula -> Bool
under Connective
c) Formula
g
Quantified Quantifier
q Integer
v Formula
f -> Quantifier -> Doc
forall a. Pretty a => a -> Doc
pretty Quantifier
q Doc -> Doc -> Doc
<+> Integer -> Doc
prettyVar Integer
v Doc -> Doc -> Doc
<+> Doc
dot
Doc -> Doc -> Doc
<+> (Formula -> Bool) -> Formula -> Doc
forall e. Pretty e => (e -> Bool) -> e -> Doc
prettyParens Formula -> Bool
unitary Formula
f
prettyList :: [Formula] -> Doc
prettyList = Doc -> [Formula] -> Doc
forall a. Pretty a => Doc -> [a] -> Doc
prettySequents Doc
"Axiom"
unitary :: Formula -> Bool
unitary :: Formula -> Bool
unitary = \case
Atomic{} -> Bool
True
Negate{} -> Bool
True
Connected{} -> Bool
False
Quantified{} -> Bool
True
under :: Connective -> Formula -> Bool
under :: Connective -> Formula -> Bool
under Connective
c = \case
Connected Connective
c' Formula
_ Formula
_ | Connective
c Connective -> Connective -> Bool
forall a. Eq a => a -> a -> Bool
== Connective
c' Bool -> Bool -> Bool
&& Connective -> Bool
chainable Connective
c -> Bool
True
Quantified{} -> Bool
False
Formula
f -> Formula -> Bool
unitary Formula
f
chainable :: Connective -> Bool
chainable :: Connective -> Bool
chainable = \case
Connective
And -> Bool
True
Connective
Or -> Bool
True
Connective
Implies -> Bool
False
Connective
Equivalent -> Bool
False
Connective
Xor -> Bool
False
instance Pretty LogicalExpression where
pretty :: LogicalExpression -> Doc
pretty = \case
Clause Clause
c -> Clause -> Doc
forall a. Pretty a => a -> Doc
pretty Clause
c
Formula Formula
f -> Formula -> Doc
forall a. Pretty a => a -> Doc
pretty Formula
f
instance Pretty Clauses where
pretty :: Clauses -> Doc
pretty (Clauses [Clause]
cs) = [Clause] -> Doc
forall a. Pretty a => [a] -> Doc
prettyList [Clause]
cs
instance Pretty Theorem where
pretty :: Theorem -> Doc
pretty (Theorem [Formula]
as Formula
c) = [Formula] -> Doc
forall a. Pretty a => [a] -> Doc
prettyList [Formula]
as Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc -> Formula -> Doc
forall a. Pretty a => Doc -> a -> Doc
prettySequent Doc
"Conjecture" Formula
c
instance Pretty l => Pretty (Rule l) where
pretty :: Rule l -> Doc
pretty Rule l
rule = RuleName -> Doc
forall a. Pretty a => a -> Doc
pretty (Rule l -> RuleName
forall f. Rule f -> RuleName
ruleName Rule l
rule) Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> case [l] -> Maybe (NonEmpty l)
forall a. [a] -> Maybe (NonEmpty a)
nonEmpty (Rule l -> [l]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Rule l
rule) of
Just NonEmpty l
as -> Doc
space Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> NonEmpty Doc -> Doc
commaSep ((l -> Doc) -> NonEmpty l -> NonEmpty Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Doc -> Doc
bold (Doc -> Doc) -> (l -> Doc) -> l -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. l -> Doc
forall a. Pretty a => a -> Doc
pretty) NonEmpty l
as)
Maybe (NonEmpty l)
Nothing -> Doc
empty
instance Pretty RuleName where
pretty :: RuleName -> Doc
pretty (RuleName Text
rn) =
case Text
rn of
Text
"negated conjecture" -> Doc -> Doc
underline (Doc -> Doc
yellow Doc
name)
Text
"unknown" -> Doc -> Doc
red Doc
name
Text
"other" -> Doc
name
Text
_ -> Doc -> Doc
yellow Doc
name
where
name :: Doc
name = String -> Doc
text (Text -> String
T.unpack Text
rn)
instance Pretty l => Pretty (Inference l) where
pretty :: Inference l -> Doc
pretty (Inference Rule l
r LogicalExpression
f) = LogicalExpression -> Doc
forall a. Pretty a => a -> Doc
pretty LogicalExpression
f Doc -> Doc -> Doc
<+> Doc -> Doc
brackets (Rule l -> Doc
forall a. Pretty a => a -> Doc
pretty Rule l
r)
instance Pretty l => Pretty (Sequent l) where
pretty :: Sequent l -> Doc
pretty (Sequent l
c Inference l
i) = Doc -> Doc
bold (l -> Doc
forall a. Pretty a => a -> Doc
pretty l
c Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
dot) Doc -> Doc -> Doc
<+> Inference l -> Doc
forall a. Pretty a => a -> Doc
pretty Inference l
i
instance (Ord l, Pretty l) => Pretty (Derivation l) where
pretty :: Derivation l -> Doc
pretty Derivation l
d = [Doc] -> Doc
vsep (Sequent Integer -> Doc
forall a. Pretty a => a -> Doc
pretty (Sequent Integer -> Doc) -> [Sequent Integer] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Derivation l -> [Sequent Integer]
forall l. Ord l => Derivation l -> [Sequent Integer]
derivation Derivation l
d) Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
line
instance (Ord l, Pretty l) => Pretty (Refutation l) where
pretty :: Refutation l -> Doc
pretty Refutation l
r = [Doc] -> Doc
vsep (Sequent Integer -> Doc
forall a. Pretty a => a -> Doc
pretty (Sequent Integer -> Doc) -> [Sequent Integer] -> [Doc]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Refutation l -> [Sequent Integer]
forall l. Ord l => Refutation l -> [Sequent Integer]
sequents Refutation l
r) Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
line
sequents :: Ord l => Refutation l -> [Sequent Integer]
sequents :: Refutation l -> [Sequent Integer]
sequents (Refutation Derivation l
d Contradiction l
c) = Enumeration l [Sequent Integer] -> [Sequent Integer]
forall a e. Enumeration a e -> e
evalEnumeration (Enumeration l [Sequent Integer] -> [Sequent Integer])
-> Enumeration l [Sequent Integer] -> [Sequent Integer]
forall a b. (a -> b) -> a -> b
$ do
[Sequent Integer]
ss <- Derivation l -> Enumeration l [Sequent Integer]
forall l. Ord l => Derivation l -> Enumeration l [Sequent Integer]
derivationS Derivation l
d
Sequent Integer
s <- Integer -> Inference Integer -> Sequent Integer
forall f. f -> Inference f -> Sequent f
Sequent (Integer -> Inference Integer -> Sequent Integer)
-> EnumerationT l Identity Integer
-> EnumerationT l Identity (Inference Integer -> Sequent Integer)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> EnumerationT l Identity Integer
forall (m :: * -> *) a. Monad m => EnumerationT a m Integer
next EnumerationT l Identity (Inference Integer -> Sequent Integer)
-> EnumerationT l Identity (Inference Integer)
-> EnumerationT l Identity (Sequent Integer)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (l -> EnumerationT l Identity Integer)
-> Inference l -> EnumerationT l Identity (Inference Integer)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse l -> EnumerationT l Identity Integer
forall a (m :: * -> *).
(Ord a, Monad m) =>
a -> EnumerationT a m Integer
enumerate (Contradiction l -> Inference l
forall f. Contradiction f -> Inference f
liftContradiction Contradiction l
c)
[Sequent Integer] -> Enumeration l [Sequent Integer]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Sequent Integer] -> [Sequent Integer]
forall a. [a] -> [a]
reverse (Sequent Integer
sSequent Integer -> [Sequent Integer] -> [Sequent Integer]
forall a. a -> [a] -> [a]
:[Sequent Integer]
ss))
derivation :: Ord l => Derivation l -> [Sequent Integer]
derivation :: Derivation l -> [Sequent Integer]
derivation = Enumeration l [Sequent Integer] -> [Sequent Integer]
forall a e. Enumeration a e -> e
evalEnumeration (Enumeration l [Sequent Integer] -> [Sequent Integer])
-> (Derivation l -> Enumeration l [Sequent Integer])
-> Derivation l
-> [Sequent Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Sequent Integer] -> [Sequent Integer])
-> Enumeration l [Sequent Integer]
-> Enumeration l [Sequent Integer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Sequent Integer] -> [Sequent Integer]
forall a. [a] -> [a]
reverse (Enumeration l [Sequent Integer]
-> Enumeration l [Sequent Integer])
-> (Derivation l -> Enumeration l [Sequent Integer])
-> Derivation l
-> Enumeration l [Sequent Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Derivation l -> Enumeration l [Sequent Integer]
forall l. Ord l => Derivation l -> Enumeration l [Sequent Integer]
derivationS
derivationS :: Ord l => Derivation l -> Enumeration l [Sequent Integer]
derivationS :: Derivation l -> Enumeration l [Sequent Integer]
derivationS Derivation l
d = ([Sequent Integer] -> Sequent l -> Enumeration l [Sequent Integer])
-> [Sequent Integer]
-> [Sequent l]
-> Enumeration l [Sequent Integer]
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldM (Map l LogicalExpression
-> [Sequent Integer]
-> Sequent l
-> Enumeration l [Sequent Integer]
forall l.
Ord l =>
Map l LogicalExpression
-> [Sequent Integer]
-> Sequent l
-> Enumeration l [Sequent Integer]
sequentsS Map l LogicalExpression
es) [] [Sequent l]
ss
where
ss :: [Sequent l]
ss = Derivation l -> [Sequent l]
forall f. Ord f => Derivation f -> [Sequent f]
breadthFirst Derivation l
d
es :: Map l LogicalExpression
es = [Sequent l] -> Map l LogicalExpression
forall f. Ord f => [Sequent f] -> Map f LogicalExpression
labeling [Sequent l]
ss
sequentsS :: Ord l => Map l LogicalExpression ->
[Sequent Integer] -> Sequent l ->
Enumeration l [Sequent Integer]
sequentsS :: Map l LogicalExpression
-> [Sequent Integer]
-> Sequent l
-> Enumeration l [Sequent Integer]
sequentsS Map l LogicalExpression
es [Sequent Integer]
ss s :: Sequent l
s@(Sequent l
l Inference l
i) =
case (l -> Bool) -> [l] -> Maybe l
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find l -> Bool
trivialClausification (Inference l -> [l]
forall f. Inference f -> [f]
antecedents Inference l
i) of
Just l
a -> l -> l -> EnumerationT l Identity ()
forall a (m :: * -> *).
(Ord a, Monad m) =>
a -> a -> EnumerationT a m ()
alias l
l l
a EnumerationT l Identity ()
-> [Sequent Integer] -> Enumeration l [Sequent Integer]
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> [Sequent Integer]
ss
Maybe l
Nothing -> (Sequent Integer -> [Sequent Integer])
-> EnumerationT l Identity (Sequent Integer)
-> Enumeration l [Sequent Integer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Sequent Integer -> [Sequent Integer] -> [Sequent Integer]
forall a. a -> [a] -> [a]
:[Sequent Integer]
ss) ((l -> EnumerationT l Identity Integer)
-> Sequent l -> EnumerationT l Identity (Sequent Integer)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse l -> EnumerationT l Identity Integer
forall a (m :: * -> *).
(Ord a, Monad m) =>
a -> EnumerationT a m Integer
enumerate Sequent l
s)
where trivialClausification :: l -> Bool
trivialClausification l
a = Map l LogicalExpression
es Map l LogicalExpression -> l -> LogicalExpression
forall k a. Ord k => Map k a -> k -> a
! l
a LogicalExpression -> LogicalExpression -> Bool
~~= Inference l -> LogicalExpression
forall f. Inference f -> LogicalExpression
consequent Inference l
i
(~~=) :: LogicalExpression -> LogicalExpression -> Bool
Clause Clause
c ~~= :: LogicalExpression -> LogicalExpression -> Bool
~~= Formula Formula
f = Formula -> Clause -> Bool
triviallyClausified Formula
f Clause
c
Formula Formula
f ~~= Clause Clause
c = Formula -> Clause -> Bool
triviallyClausified Formula
f Clause
c
LogicalExpression
_ ~~= LogicalExpression
_ = Bool
False
triviallyClausified :: Formula -> Clause -> Bool
triviallyClausified :: Formula -> Clause -> Bool
triviallyClausified Formula
f Clause
c
| Just Clause
k <- Formula -> Maybe Clause
unliftClause Formula
f = Clause
k Clause -> Clause -> Bool
forall e. FirstOrder e => e -> e -> Bool
~= Clause
c
| Bool
otherwise = Bool
False
instance Pretty Solution where
pretty :: Solution -> Doc
pretty = \case
Saturation Derivation Integer
d -> [Doc] -> Doc
vsep [Doc -> Doc
yellow Doc
saturated, Derivation Integer -> Doc
forall a. Pretty a => a -> Doc
pretty Derivation Integer
d]
Proof Refutation Integer
r -> [Doc] -> Doc
vsep [Doc -> Doc
green Doc
proven, Refutation Integer -> Doc
forall a. Pretty a => a -> Doc
pretty Refutation Integer
r]
where
saturated :: Doc
saturated = Doc
"Disproven by constructing the saturated set of clauses."
proven :: Doc
proven = Doc
"Found a proof by refutation."
instance Pretty Error where
pretty :: Error -> Doc
pretty Error
err = Doc -> Doc
red (Doc -> Doc) -> Doc -> Doc
forall a b. (a -> b) -> a -> b
$ case Maybe Doc
explanation of
Just Doc
ex -> [Doc] -> Doc
vsep [Doc
failure, Doc
ex]
Maybe Doc
Nothing -> Doc
failure
where
failure :: Doc
failure = Doc
"Failed to find a solution because" Doc -> Doc -> Doc
<+> Doc
reason Doc -> Doc -> Doc
forall a. Semigroup a => a -> a -> a
<> Doc
"."
reason :: Doc
reason = case Error
err of
Error
TimeLimitError -> Doc
"the theorem prover exceeded its time limit"
Error
MemoryLimitError -> Doc
"the theorem prover exceeded its memory limit"
ParsingError{} -> Doc
"of the following parsing error"
ProofError{} -> Doc
"of the following problem with the proof"
OtherError{} -> Doc
"of the following error"
ExitCodeError Int
c Text
_ -> Doc
"the theorem prover terminated with exit code" Doc -> Doc -> Doc
<+>
Doc -> Doc
bold Doc
exitCode Doc -> Doc -> Doc
<+> Doc
"and the following error message"
where exitCode :: Doc
exitCode = String -> Doc
text (Int -> String
forall a. Show a => a -> String
show Int
c)
explanation :: Maybe Doc
explanation = (Text -> Doc) -> Maybe Text -> Maybe Doc
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (String -> Doc
text (String -> Doc) -> (Text -> String) -> Text -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> String
T.unpack) (Maybe Text -> Maybe Doc) -> Maybe Text -> Maybe Doc
forall a b. (a -> b) -> a -> b
$ case Error
err of
Error
TimeLimitError -> Maybe Text
forall a. Maybe a
Nothing
Error
MemoryLimitError -> Maybe Text
forall a. Maybe a
Nothing
ParsingError Text
e -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
e
ProofError Text
e -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
e
OtherError Text
e -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
e
ExitCodeError Int
_ Text
e -> if Text -> Bool
T.null Text
e then Maybe Text
forall a. Maybe a
Nothing else Text -> Maybe Text
forall a. a -> Maybe a
Just Text
e
instance Pretty a => Pretty (Partial a) where
pretty :: Partial a -> Doc
pretty = (Error -> Doc) -> (a -> Doc) -> Either Error a -> Doc
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Error -> Doc
forall a. Pretty a => a -> Doc
pretty a -> Doc
forall a. Pretty a => a -> Doc
pretty (Either Error a -> Doc)
-> (Partial a -> Either Error a) -> Partial a -> Doc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Partial a -> Either Error a
forall a. Partial a -> Either Error a
liftPartial