less prototype, less bad code implementation of CCHM type theory
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
3.0 KiB

  1. module Elab.Eval.Formula where
  2. import qualified Data.Map.Strict as Map
  3. import qualified Data.Sequence as Seq
  4. import qualified Data.Set as Set
  5. import Data.Map.Strict (Map)
  6. import Data.Set (Set)
  7. import Syntax
  8. import {-# SOURCE #-} Elab.WiredIn (inot, ior, iand)
  9. import Elab.Eval (substitute, trueCaseSentinel)
  10. toDnf :: Value -> Maybe Value
  11. toDnf = fmap (dnf2Val . normalise) . val2Dnf where
  12. val2Dnf (VNe _ _) = Nothing
  13. val2Dnf x = toDnf x where
  14. toDnf (VIAnd x y) = idist <$> toDnf (inot x) <*> toDnf (inot y)
  15. toDnf (VIOr x y) = ior <$> toDnf x <*> toDnf y
  16. toDnf (VINot x) = inot <$> toDnf x
  17. toDnf VI0 = pure VI0
  18. toDnf VI1 = pure VI1
  19. toDnf v@(VNe _ Seq.Empty) = pure v
  20. toDnf _ = Nothing
  21. dnf2Val xs = Set.foldl ior VI0 (Set.map (Set.foldl iand VI1) xs)
  22. type Nf = Set (Set Value)
  23. normalise :: Value -> Nf
  24. normalise = normaliseOr where
  25. normaliseOr (VIOr x y) = Set.singleton (normaliseAnd x) <> normaliseOr y
  26. normaliseOr x = Set.singleton (normaliseAnd x)
  27. normaliseAnd (VIAnd x y) = Set.insert x (normaliseAnd y)
  28. normaliseAnd x = Set.singleton x
  29. compareDNFs :: Value -> Value -> Bool
  30. compareDNFs (VIOr x y) (VIOr x' y') =
  31. let (a, a') = swap x y
  32. (b, b') = swap x' y'
  33. in compareDNFs a b && compareDNFs a' b'
  34. compareDNFs (VIAnd x y) (VIAnd x' y') =
  35. let (a, a') = swap x x'
  36. (b, b') = swap y y'
  37. in compareDNFs a a' && compareDNFs b b'
  38. compareDNFs x y = x == y
  39. swap :: Ord b => b -> b -> (b, b)
  40. swap x y =
  41. if x <= y then (x, y) else (y, x)
  42. possible :: Map Head Bool -> Value -> (Bool, Map Head Bool)
  43. possible sc (VINot (VNe n Seq.Empty)) =
  44. case Map.lookup n sc of
  45. Just True -> (False, sc)
  46. _ -> (True, Map.insert n False sc)
  47. possible sc (VNe n Seq.Empty) =
  48. case Map.lookup n sc of
  49. Just False -> (False, sc)
  50. _ -> (True, Map.insert n True sc)
  51. possible sc (VIAnd x y) =
  52. let (a, sc') = possible sc x
  53. (b, sc'') = possible sc' y
  54. in (a && b, sc'')
  55. possible sc (VIOr x y) =
  56. case possible sc x of
  57. (True, sc') -> (True, sc')
  58. (False, _) -> possible sc y
  59. possible sc VI0 = (False, sc)
  60. possible sc VI1 = (True, sc)
  61. possible sc _ = (False, sc)
  62. truthAssignments :: NFEndp -> Map Name (NFType, NFEndp) -> [Map Name (NFType, NFEndp)]
  63. truthAssignments VI0 _ = []
  64. truthAssignments VI1 m = pure m
  65. truthAssignments (VIOr x y) m = truthAssignments x m ++ truthAssignments y m
  66. truthAssignments (VIAnd x y) m = truthAssignments x =<< truthAssignments y m
  67. truthAssignments (VNe (HVar x) Seq.Empty) m = pure (Map.insert x (VI, VI1) (sub x VI1 <$> m))
  68. truthAssignments (VINot (VNe (HVar x) Seq.Empty)) m = pure (Map.insert x (VI, VI0) (sub x VI0 <$> m))
  69. truthAssignments (VCase _ _ (VNe (HVar x) _) _) m = pure (Map.insert x (VI, VVar trueCaseSentinel) m)
  70. truthAssignments _ m = pure m
  71. sub :: Name -> Value -> (NFType, NFEndp) -> (Value, Value)
  72. sub x v (a, b) = (substitute (Map.singleton x v) a, substitute (Map.singleton x v) b)
  73. idist :: Value -> Value -> Value
  74. idist (VIOr x y) z = (x `idist` z) `ior` (y `idist` z)
  75. idist z (VIOr x y) = (z `idist` x) `ior` (z `idist` y)
  76. idist z x = iand z x