summaryrefslogtreecommitdiff
path: root/compiler/utils/BooleanFormula.hs
diff options
context:
space:
mode:
authorEdward Z. Yang <ezyang@cs.stanford.edu>2017-01-05 13:52:12 -0800
committerEdward Z. Yang <ezyang@cs.stanford.edu>2017-01-11 06:54:00 -0800
commit5def07fadd386a7a7c3a12963c0736529e377a74 (patch)
tree1b2b5dbde6f6a227c4b2faa777080b4014fc4ee6 /compiler/utils/BooleanFormula.hs
parente41c61fa7792d12ac7ffbacda7a5b3ba6ef2a267 (diff)
downloadhaskell-5def07fadd386a7a7c3a12963c0736529e377a74.tar.gz
Revamp Backpack/hs-boot handling of type class signatures.
Summary: A basket of fixes and improvements: - The permissible things that one can write in a type class definition in an hsig file has been reduced to encompass the following things: - Methods - Default method signatures (but NOT implementation) - MINIMAL pragma It is no longer necessary nor encouraged to specify that a method has a default if it is mentioned in a MINIMAL pragma; the MINIMAL pragma is assumed to provide the base truth as to what methods need to be implemented when writing instances of a type class. - Handling of default method signatures in hsig was previously buggy, as these identifiers were not exported, so we now treat them similarly to DFuns. - Default methods are merged, where methods with defaults override those without. - MINIMAL pragmas are merged by ORing together pragmas. - Matching has been relaxed: a method with a default can be used to fill a signature which did not declare the method as having a default, and a more relaxed MINIMAL pragma can be used (we check if the signature pragma implies the final implementation pragma, on the way fixing a bug with BooleanFormula.implies, see #13073) Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu> Test Plan: validate Reviewers: simonpj, bgamari, austin Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D2925 GHC Trac Issues: #13041
Diffstat (limited to 'compiler/utils/BooleanFormula.hs')
-rw-r--r--compiler/utils/BooleanFormula.hs37
1 files changed, 32 insertions, 5 deletions
diff --git a/compiler/utils/BooleanFormula.hs b/compiler/utils/BooleanFormula.hs
index 1509321e62..43a71f0080 100644
--- a/compiler/utils/BooleanFormula.hs
+++ b/compiler/utils/BooleanFormula.hs
@@ -23,6 +23,8 @@ import MonadUtils
import Outputable
import Binary
import SrcLoc
+import Unique
+import UniqSet
----------------------------------------------------------------------
-- Boolean formula type and smart constructors
@@ -157,11 +159,36 @@ And xs `impliesAtom` y = any (\x -> (unLoc x) `impliesAtom` y) xs
Or xs `impliesAtom` y = all (\x -> (unLoc x) `impliesAtom` y) xs
Parens x `impliesAtom` y = (unLoc x) `impliesAtom` y
-implies :: Eq a => BooleanFormula a -> BooleanFormula a -> Bool
-x `implies` Var y = x `impliesAtom` y
-x `implies` And ys = all (implies x . unLoc) ys
-x `implies` Or ys = any (implies x . unLoc) ys
-x `implies` Parens y = x `implies` (unLoc y)
+implies :: Uniquable a => BooleanFormula a -> BooleanFormula a -> Bool
+implies e1 e2 = go (Clause emptyUniqSet [e1]) (Clause emptyUniqSet [e2])
+ where
+ go :: Uniquable a => Clause a -> Clause a -> Bool
+ go l@Clause{ clauseExprs = hyp:hyps } r =
+ case hyp of
+ Var x | memberClauseAtoms x r -> True
+ | otherwise -> go (extendClauseAtoms l x) { clauseExprs = hyps } r
+ Parens hyp' -> go l { clauseExprs = unLoc hyp':hyps } r
+ And hyps' -> go l { clauseExprs = map unLoc hyps' ++ hyps } r
+ Or hyps' -> all (\hyp' -> go l { clauseExprs = unLoc hyp':hyps } r) hyps'
+ go l r@Clause{ clauseExprs = con:cons } =
+ case con of
+ Var x | memberClauseAtoms x l -> True
+ | otherwise -> go l (extendClauseAtoms r x) { clauseExprs = cons }
+ Parens con' -> go l r { clauseExprs = unLoc con':cons }
+ And cons' -> all (\con' -> go l r { clauseExprs = unLoc con':cons }) cons'
+ Or cons' -> go l r { clauseExprs = map unLoc cons' ++ cons }
+ go _ _ = False
+
+-- A small sequent calculus proof engine.
+data Clause a = Clause {
+ clauseAtoms :: UniqSet a,
+ clauseExprs :: [BooleanFormula a]
+ }
+extendClauseAtoms :: Uniquable a => Clause a -> a -> Clause a
+extendClauseAtoms c x = c { clauseAtoms = addOneToUniqSet (clauseAtoms c) x }
+
+memberClauseAtoms :: Uniquable a => a -> Clause a -> Bool
+memberClauseAtoms x c = x `elementOfUniqSet` clauseAtoms c
----------------------------------------------------------------------
-- Pretty printing