-
Notifications
You must be signed in to change notification settings - Fork 2
/
LogicClasses.hs
158 lines (128 loc) · 5.36 KB
/
LogicClasses.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleContexts #-}
module LogicClasses (
Variable(..),
Shiftable(..),
Mappable(..),
Satisfiable(..),
EqRaw(..),
Boolean(..),
QBF(..),
AllOps(..),
Serialisable(..),
Cubeable(..),
oneSatAndCube,
cube,
EqConst(..),
eqVars,
BoolOp(..),
CUDDLike(..),
VarDecl(..)
) where
import Control.Monad.Error
import Data.List
import Data.Bits
import Util
--Variables
class Variable c v | c -> v where
vzero :: c -> v
vplus :: c -> v -> v -> v
vconcat :: c -> [v] -> v
vminus :: c -> v -> v -> v
--Operations
--Have to have stupid names because of clashes with prelude names
class Boolean c a | c -> a where
iteOp :: c -> a -> a -> a -> a
andOp, orOp, xorOp, xnorOp, impOp, nandOp, norOp :: c -> a -> a -> a
nandOp c x y = notOp c $ andOp c x y
norOp c x y = notOp c $ orOp c x y
xnorOp c x y = notOp c $ xorOp c x y
impOp c x y = orOp c (notOp c x) y
orOp c x y = notOp c $ andOp c (notOp c x) (notOp c y)
andOp c x y = notOp c $ orOp c (notOp c x) (notOp c y)
xorOp c x y = andOp c (orOp c x y) (notOp c (andOp c x y))
notOp :: c -> a -> a
topOp, botOp :: c -> a
topOp c = notOp c (botOp c)
botOp c = notOp c (topOp c)
conjOp, disjOp :: c -> [a] -> a
conjOp d xs = foldl (andOp d) (topOp d) xs
disjOp d xs = foldl (orOp d) (botOp d) xs
eqOp :: c -> a -> a -> Bool
cube :: (Boolean c a) => c -> [a] -> [Bool] -> a
cube m nodes phase = conjOp m $ zipWith (alt id (notOp m)) phase nodes
class Boolean c a => QBF c v a | c -> v, c -> a where
exists, forall :: c -> v -> a -> a
--Renaming
class Shiftable c v a | c -> v, c -> a where
shift :: c -> Int -> v -> v -> a -> a
swap :: c -> v -> v -> a -> a
class Mappable c v a | c -> v, c -> a where
varMap :: c -> a -> a
--Minterm and cube extraction
class Cubeable c v a where
oneCube :: c -> v -> a -> Maybe a
allCubes :: c -> v -> a -> [a]
oneMinterm :: c -> v -> a -> Maybe a
allMinterms :: c -> v -> a -> [a]
--Satisfiability
class Satisfiable c v a s r | c -> v, c -> a, c -> s, c -> r where
sat :: c -> a -> s
satOne :: c -> a -> Maybe r
extract :: c -> v -> r -> r
expand :: c -> [v] -> s -> [[r]]
expandOne :: c -> v -> s -> [r]
oneSat :: c -> v -> a -> Maybe r
oneSatAndCube :: (Satisfiable c v a s [Bool], BoolOp c v a) => c -> v -> a -> Maybe ([Bool], a)
oneSatAndCube c v a = do
res <- oneSat c v a
return (res, cube c (compVar c v) res)
--Serialization
class Serialisable c a where
toStr :: (MonadError String me) => c -> a -> me String
fromStr :: (MonadError String me) => c -> String -> me a
--Constant equality
class EqRaw c v a r | c -> v, c -> a, c -> r where
eqRaw :: c -> v -> r -> a
class EqConst c v a where
eqConstLE :: (Bits b) => c -> v -> b -> a
eqConstBE :: (Bits b) => c -> v -> b -> a
eqConst :: (Bits b) => c -> v -> b -> a
--It makes more sense to have compVar return another abstract type that represents compiled vars and use these in the compiler and for EqConst
class QBF c v a => BoolOp c v a | c -> a, c -> v where
compVar :: c -> v -> [a]
eqVars :: (BoolOp c v a) => c -> v -> v -> a
eqVars c l r = conjOp c $ zipWith (xnorOp c) (compVar c l) (compVar c r)
class VarDecl c v where
varAtIndex :: c -> Int -> v
class (Variable c v, Shiftable c v a, QBF c v a, BoolOp c v a, EqConst c v a) => AllOps c v a
class (AllOps c v a, Satisfiable c v a s r) => AllAndSat c v a s r
class (AllOps c v a, VarDecl c v) => AllAndDecl c v a
--Stuff specific to BDD libraries
class AllOps c v a => CUDDLike c v a where
andAbs, xorAbs, faImp, faXnor :: c -> v -> a -> a -> a
andAbs m v x y = exists m v $ andOp m x y
xorAbs m v x y = exists m v $ xorOp m x y
faImp m v x y = notOp m $ andAbs m v x (notOp m y)
faXnor m v x y = notOp m $ xorAbs m v x y
liCompaction :: c -> a -> a -> a
largestCube :: c -> a -> a
makePrime :: c -> a -> a -> a
supportIndices :: c -> a -> [Int]
project :: (VarDecl c v) => c -> [Int] -> a -> a
project m ids x = exists m v x
where v = vconcat m $ map (varAtIndex m) $ filter (\i -> not $ elem i ids) $ supportIndices m x
primeImplicant :: c -> a -> a
primeImplicant m x = makePrime m (largestCube m x) x
primeCover :: c -> a -> [a]
primeCover m y = unfoldr func y
where
func x
| eqOp m x (botOp m) = Nothing
| otherwise = Just (ret, st)
where
ret = makePrime m (largestCube m x) y
st = andOp m (notOp m ret) x
leq :: c -> a -> a -> Bool
leq m l r = eqOp m (impOp m l r) (topOp m)
intersects :: c -> a -> a -> Bool
intersects m l r = not $ leq m l (notOp m r)