{- |
Description: Simplification of 'PropositionalFormula's.
License: GNU LGPLv3
Maintainer: paul.bittner@uni-ulm.de
Functions for simplification of 'PropositionalFormula's.
-}
module Simplify (
removeRedundancy
) where
import Logic
import Propositions
( simplify,
PropositionalFormula(..) )
import SAT ( contradicts, taut )
import Data.List
removeRedundancy :: (Ord a, Show a) => PropositionalFormula a -> PropositionalFormula a -> PropositionalFormula a
removeRedundancy :: PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancy axiom :: PropositionalFormula a
axiom (PAnd cs :: [PropositionalFormula a]
cs) =
if PropositionalFormula a -> Bool
forall a. (Show a, Ord a) => PropositionalFormula a -> Bool
contradicts (PropositionalFormula a -> Bool) -> PropositionalFormula a -> Bool
forall a b. (a -> b) -> a -> b
$ [PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
PAnd ([PropositionalFormula a] -> PropositionalFormula a)
-> [PropositionalFormula a] -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$ PropositionalFormula a
axiomPropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a. a -> [a] -> [a]
:[PropositionalFormula a]
cs
then PropositionalFormula a
forall a. PropositionalFormula a
PFalse
else
PropositionalFormula a -> PropositionalFormula a
forall a. PropositionalFormula a -> PropositionalFormula a
simplify (PropositionalFormula a -> PropositionalFormula a)
-> PropositionalFormula a -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$
[PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
PAnd ([PropositionalFormula a] -> PropositionalFormula a)
-> [PropositionalFormula a] -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$
(PropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a])
-> [PropositionalFormula a]
-> [PropositionalFormula a]
-> [PropositionalFormula a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\elementToInspect :: PropositionalFormula a
elementToInspect b :: [PropositionalFormula a]
b -> if PropositionalFormula a -> Bool
forall a. (Show a, Ord a) => PropositionalFormula a -> Bool
taut (PropositionalFormula a -> Bool) -> PropositionalFormula a -> Bool
forall a b. (a -> b) -> a -> b
$ PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall l. Logic l => l -> l -> l
limplies PropositionalFormula a
axiom ([PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
PAnd ([PropositionalFormula a] -> PropositionalFormula a)
-> [PropositionalFormula a] -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$ PropositionalFormula a
elementToInspectPropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a. a -> [a] -> [a]
:[PropositionalFormula a]
b) then [PropositionalFormula a]
b else PropositionalFormula a
elementToInspectPropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a. a -> [a] -> [a]
:[PropositionalFormula a]
b) [] ([PropositionalFormula a] -> [PropositionalFormula a])
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a b. (a -> b) -> a -> b
$
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall a.
(Ord a, Show a) =>
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancy PropositionalFormula a
axiom (PropositionalFormula a -> PropositionalFormula a)
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PropositionalFormula a]
cs
removeRedundancy axiom :: PropositionalFormula a
axiom (POr cs :: [PropositionalFormula a]
cs) =
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall a.
(Ord a, Show a) =>
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancyBase PropositionalFormula a
axiom (PropositionalFormula a -> PropositionalFormula a)
-> PropositionalFormula a -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$
[PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
POr ([PropositionalFormula a] -> PropositionalFormula a)
-> [PropositionalFormula a] -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$
(PropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a])
-> [PropositionalFormula a]
-> [PropositionalFormula a]
-> [PropositionalFormula a]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\elementToInspect :: PropositionalFormula a
elementToInspect b :: [PropositionalFormula a]
b -> if PropositionalFormula a -> Bool
forall a. (Show a, Ord a) => PropositionalFormula a -> Bool
contradicts (PropositionalFormula a -> Bool) -> PropositionalFormula a -> Bool
forall a b. (a -> b) -> a -> b
$ [PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
PAnd [PropositionalFormula a
elementToInspect, PropositionalFormula a
axiom] then [PropositionalFormula a]
b else PropositionalFormula a
elementToInspectPropositionalFormula a
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a. a -> [a] -> [a]
:[PropositionalFormula a]
b) [] ([PropositionalFormula a] -> [PropositionalFormula a])
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall a b. (a -> b) -> a -> b
$
(PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall a.
(Ord a, Show a) =>
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancy PropositionalFormula a
axiom) (PropositionalFormula a -> PropositionalFormula a)
-> [PropositionalFormula a] -> [PropositionalFormula a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PropositionalFormula a]
cs
removeRedundancy axiom :: PropositionalFormula a
axiom x :: PropositionalFormula a
x =
let y :: PropositionalFormula a
y = PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall a.
(Ord a, Show a) =>
PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancyBase PropositionalFormula a
axiom PropositionalFormula a
x in
if PropositionalFormula a -> Bool
forall a. (Show a, Ord a) => PropositionalFormula a -> Bool
contradicts (PropositionalFormula a -> Bool) -> PropositionalFormula a -> Bool
forall a b. (a -> b) -> a -> b
$ [PropositionalFormula a] -> PropositionalFormula a
forall a. [PropositionalFormula a] -> PropositionalFormula a
PAnd [PropositionalFormula a
y, PropositionalFormula a
axiom] then PropositionalFormula a
forall a. PropositionalFormula a
PFalse else PropositionalFormula a
y
removeRedundancyBase :: (Ord a, Show a) => PropositionalFormula a -> PropositionalFormula a -> PropositionalFormula a
removeRedundancyBase :: PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
removeRedundancyBase axiom :: PropositionalFormula a
axiom x :: PropositionalFormula a
x = PropositionalFormula a -> PropositionalFormula a
forall a. PropositionalFormula a -> PropositionalFormula a
simplify (PropositionalFormula a -> PropositionalFormula a)
-> PropositionalFormula a -> PropositionalFormula a
forall a b. (a -> b) -> a -> b
$ if PropositionalFormula a -> Bool
forall a. (Show a, Ord a) => PropositionalFormula a -> Bool
taut (PropositionalFormula a -> Bool) -> PropositionalFormula a -> Bool
forall a b. (a -> b) -> a -> b
$ PropositionalFormula a
-> PropositionalFormula a -> PropositionalFormula a
forall l. Logic l => l -> l -> l
limplies PropositionalFormula a
axiom PropositionalFormula a
x then PropositionalFormula a
forall a. PropositionalFormula a
PTrue else PropositionalFormula a
x