GenZ-0.1.0.0: lib/Logic/Propositional/IPL.hs
module Logic.Propositional.IPL (intui) where
import Data.List as List
import qualified Data.Set as Set
import General
import Basics
import FormP
intui :: Logic FormP
intui = Log { name = "IPL"
, safeRules = [leftBot, isAxiom, additionRule safeIPL]
, unsafeRules = [additionRuleNoLoop unsafeIPL]
}
{-
-- Saturated saferules(local loopcheck)
Γ, φ ∧ ψ, φ, ψ ⇒ ∆
∧L Γ, φ ∧ ψ ⇒ ∆
Γ, φ ∨ ψ, φ ⇒ ∆ Γ, φ ∨ ψ, ψ ⇒ ∆
∨L Γ, φ ∨ ψ ⇒ ∆
Γ, φ → ψ ⇒ ∆, φ Γ, φ → ψ, ψ ⇒ ∆
→iL Γ, φ → ψ ⇒ ∆
Γ ⇒ ∆, φ ∧ ψ, φ Γ ⇒ ∆, φ ∧ ψ, ψ
∧R Γ ⇒ ∆, φ ∧ ψ
Γ ⇒ ∆, φ ∨ ψ, φ, ψ
∨R Γ ⇒ ∆, φ ∨ ψ
-- Unsaferule(local + global loopcheck)
Γ, φ ⇒ ψ
→iR Γ ⇒ ∆, φ → ψ
-}
safeIPL :: Either FormP FormP -> [(RuleName,[Sequent FormP])]
safeIPL (Left (ConP f g)) = [("∧L" , [Set.fromList [Left g, Left f]])]
safeIPL (Left (DisP f g)) = [("vL" , [Set.singleton (Left f), Set.singleton (Left g)])]
safeIPL (Left (ImpP f g)) = [("→iL", [Set.singleton (Right f), Set.singleton (Left g)])]
safeIPL (Right (ConP f g)) = [("∧R" , [Set.singleton (Right f), Set.singleton (Right g)])]
safeIPL (Right (DisP f g)) = [("vR" , [Set.fromList [Right g, Right f]])]
safeIPL _ = []
-- | The R-> rule.
unsafeIPL :: Either FormP FormP -> [(RuleName,[Sequent FormP])]
unsafeIPL (Right (ImpP f g)) = [("→iR", [Set.fromList [Right g, Left f]])]
unsafeIPL _ = []
-- | Local loopcheck: is this sequent saturated?
localLoopCheck :: Sequent FormP -> Either FormP FormP -> Bool
localLoopCheck fs f@(Right (ImpP _ _)) = not $ any (`Set.isSubsetOf` fs) (snd . head . unsafeIPL $ f)
localLoopCheck fs f = case safeIPL f of [] -> False
((_,results):_) -> not $ any (`Set.isSubsetOf` fs) results
-- * IPL-specific versions of `replaceRule`.
-- | Like `replaceRule` but keep principal formula (built-in weakening), and block when localLoopCheck.
additionRule :: (Either FormP FormP -> [(RuleName, [Sequent FormP])]) -> Rule FormP
additionRule fun _ fs g =
[ ( fst . head $ fun g
, [ fs `Set.union` newfs | newfs <- snd . head $ fun g ] -- not deleting `g` here!
)
| localLoopCheck fs g -- local loopcheck
, not (List.null (fun g)) ]
-- | Helper function for replaceRuleIPLunsafe.
applyIPL :: Sequent FormP -> Either FormP FormP -> [Sequent FormP] -> [Sequent FormP]
applyIPL fs _ = List.map (leftOfSet fs `Set.union`)
-- | Like `additionRule` but also doing a global loopcheck.
additionRuleNoLoop :: (Either FormP FormP -> [(RuleName, [Sequent FormP])]) -> Rule FormP
additionRuleNoLoop fun h fs g =
[ ( fst . head $ fun g
, applyIPL fs g $ snd . head . fun $ g
)
| localLoopCheck fs g -- local loopcheck
, globalLoopCheck h fs g -- gobal loopcheck
, not (List.null (fun g)) ]
-- | Check that the result of applying `unsafeIPL` to `f` does
-- not already occur (as a subset) in the history.
-- Helper function for `replaceRuleIPLunsafe`.
globalLoopCheck :: [Sequent FormP] -> Sequent FormP -> Either FormP FormP -> Bool
globalLoopCheck hs fs f@(Right (ImpP _ _)) =
let xs = applyIPL fs f (snd (head (unsafeIPL f)))
in not $ any (Set.isSubsetOf (head xs)) hs
globalLoopCheck _ _ _ = False