module AutoProof.Internal.Intuitionistic.Proof.Search.Implication
( proveImp,
)
where
import AutoProof.Internal.Formula (Formula (Imp, Var))
import AutoProof.Internal.Judgement (Judgement (Judgement))
import AutoProof.Internal.Proof.Types (Proof (Axiom, ImpElim, ImpIntr))
import Control.Applicative ((<|>))
import qualified Data.Set as Set
proveImp :: Ord a => Judgement a -> Maybe (Proof a)
proveImp :: Judgement a -> Maybe (Proof a)
proveImp = Set (Judgement a) -> Judgement a -> Maybe (Proof a)
forall a.
Ord a =>
Set (Judgement a) -> Judgement a -> Maybe (Proof a)
search Set (Judgement a)
forall a. Set a
Set.empty
where
search :: Set (Judgement a) -> Judgement a -> Maybe (Proof a)
search s :: Set (Judgement a)
s j :: Judgement a
j@(Judgement g :: Context a
g i :: Formula a
i@(Imp a :: Formula a
a b :: Formula a
b)) =
if Formula a -> Context a -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Formula a
i Context a
g
then Proof a -> Maybe (Proof a)
forall a. a -> Maybe a
Just (Judgement a -> Proof a
forall a. Judgement a -> Proof a
Axiom Judgement a
j)
else Judgement a -> Proof a -> Proof a
forall a. Judgement a -> Proof a -> Proof a
ImpIntr Judgement a
j (Proof a -> Proof a) -> Maybe (Proof a) -> Maybe (Proof a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Set (Judgement a) -> Judgement a -> Maybe (Proof a)
search Set (Judgement a)
s (Context a -> Formula a -> Judgement a
forall a. Context a -> Formula a -> Judgement a
Judgement (Formula a -> Context a -> Context a
forall a. Ord a => a -> Set a -> Set a
Set.insert Formula a
a Context a
g) Formula a
b)
search s :: Set (Judgement a)
s j :: Judgement a
j@(Judgement g :: Context a
g v :: Formula a
v@(Var x :: a
x)) =
if Judgement a -> Set (Judgement a) -> Bool
forall a. Ord a => a -> Set a -> Bool
Set.member Judgement a
j Set (Judgement a)
s
then Maybe (Proof a)
forall a. Maybe a
Nothing
else (Formula a -> Maybe (Proof a) -> Maybe (Proof a))
-> Maybe (Proof a) -> Context a -> Maybe (Proof a)
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (Maybe (Proof a) -> Maybe (Proof a) -> Maybe (Proof a)
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
(<|>) (Maybe (Proof a) -> Maybe (Proof a) -> Maybe (Proof a))
-> (Formula a -> Maybe (Proof a))
-> Formula a
-> Maybe (Proof a)
-> Maybe (Proof a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Formula a -> Maybe (Proof a)
findImp) Maybe (Proof a)
forall a. Maybe a
Nothing Context a
g
where
findImp :: Formula a -> Maybe (Proof a)
findImp a :: Formula a
a = do
[Formula a]
as <- Formula a -> Maybe [Formula a]
splitImp Formula a
a
[Formula a] -> Formula a -> Maybe (Proof a)
construct [Formula a]
as Formula a
v
splitImp :: Formula a -> Maybe [Formula a]
splitImp = [Formula a] -> Formula a -> Maybe [Formula a]
go []
where
go :: [Formula a] -> Formula a -> Maybe [Formula a]
go l :: [Formula a]
l (Var y :: a
y) = if a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
y then [Formula a] -> Maybe [Formula a]
forall a. a -> Maybe a
Just [Formula a]
l else Maybe [Formula a]
forall a. Maybe a
Nothing
go l :: [Formula a]
l (Imp a :: Formula a
a b :: Formula a
b) = [Formula a] -> Formula a -> Maybe [Formula a]
go (Formula a
a Formula a -> [Formula a] -> [Formula a]
forall a. a -> [a] -> [a]
: [Formula a]
l) Formula a
b
go _ _ = Maybe [Formula a]
forall a. Maybe a
Nothing
construct :: [Formula a] -> Formula a -> Maybe (Proof a)
construct [] b :: Formula a
b = Proof a -> Maybe (Proof a)
forall a. a -> Maybe a
Just (Judgement a -> Proof a
forall a. Judgement a -> Proof a
Axiom (Context a -> Formula a -> Judgement a
forall a. Context a -> Formula a -> Judgement a
Judgement Context a
g Formula a
b))
construct (a :: Formula a
a : as :: [Formula a]
as) b :: Formula a
b = do
Proof a
q <- Set (Judgement a) -> Judgement a -> Maybe (Proof a)
search (Judgement a -> Set (Judgement a) -> Set (Judgement a)
forall a. Ord a => a -> Set a -> Set a
Set.insert Judgement a
j Set (Judgement a)
s) (Context a -> Formula a -> Judgement a
forall a. Context a -> Formula a -> Judgement a
Judgement Context a
g Formula a
a)
Proof a
p <- [Formula a] -> Formula a -> Maybe (Proof a)
construct [Formula a]
as (Formula a -> Formula a -> Formula a
forall a. Formula a -> Formula a -> Formula a
Imp Formula a
a Formula a
b)
Proof a -> Maybe (Proof a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Judgement a -> Proof a -> Proof a -> Proof a
forall a. Judgement a -> Proof a -> Proof a -> Proof a
ImpElim (Context a -> Formula a -> Judgement a
forall a. Context a -> Formula a -> Judgement a
Judgement Context a
g Formula a
b) Proof a
p Proof a
q)
search _ _ = Maybe (Proof a)
forall a. Maybe a
Nothing