Added (constant divisor, for now) modulo to the QuickCheck tests in ArrayUsageCheckTest
This commit is contained in:
parent
7fbb83a813
commit
d0b94e402c
|
@ -16,7 +16,7 @@ You should have received a copy of the GNU General Public License along
|
||||||
with this program. If not, see <http://www.gnu.org/licenses/>.
|
with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
-}
|
-}
|
||||||
|
|
||||||
module ArrayUsageCheck (BackgroundKnowledge(..), checkArrayUsage, FlattenedExp(..), makeEquations, VarMap) where
|
module ArrayUsageCheck (BackgroundKnowledge(..), checkArrayUsage, FlattenedExp(..), onlyConst, makeEquations, VarMap) where
|
||||||
|
|
||||||
import Control.Monad.Error
|
import Control.Monad.Error
|
||||||
import Control.Monad.State
|
import Control.Monad.State
|
||||||
|
|
|
@ -115,7 +115,7 @@ leq [] = []
|
||||||
leq [_] = []
|
leq [_] = []
|
||||||
leq (x:y:zs) = (x <== y) : (leq (y:zs))
|
leq (x:y:zs) = (x <== y) : (leq (y:zs))
|
||||||
|
|
||||||
(&&&) :: [HandyIneq] -> [HandyIneq] -> [HandyIneq]
|
(&&&) :: [a] -> [a] -> [a]
|
||||||
(&&&) = (++)
|
(&&&) = (++)
|
||||||
|
|
||||||
infixr 4 ===
|
infixr 4 ===
|
||||||
|
@ -537,7 +537,7 @@ genNewItem specialAllowed
|
||||||
-- ,(20, return (A.Dyadic emptyMeta A.Mul (exprVariable $ "y" ++ show nextId) (exprVariable $ "y" ++ show nextId))
|
-- ,(20, return (A.Dyadic emptyMeta A.Mul (exprVariable $ "y" ++ show nextId) (exprVariable $ "y" ++ show nextId))
|
||||||
] ++ if not specialAllowed then []
|
] ++ if not specialAllowed then []
|
||||||
else [(20, do ((eT,iT),fT) <- genNewItem False
|
else [(20, do ((eT,iT),fT) <- genNewItem False
|
||||||
((eB,iB),fB) <- genNewItem False
|
((eB,iB),fB) <- genConst -- TODO enable variable divisor
|
||||||
m <- get
|
m <- get
|
||||||
let nextId = 1 + maximum (0 : Map.elems m)
|
let nextId = 1 + maximum (0 : Map.elems m)
|
||||||
return (A.Dyadic emptyMeta A.Rem eT eB, Modulo (Set.singleton fT) (Set.singleton fB), nextId)
|
return (A.Dyadic emptyMeta A.Rem eT eB, Modulo (Set.singleton fT) (Set.singleton fB), nextId)
|
||||||
|
@ -555,19 +555,48 @@ generateEquationInput
|
||||||
= do ((items, upper),vm) <- flip runStateT Map.empty
|
= do ((items, upper),vm) <- flip runStateT Map.empty
|
||||||
(do upper <- frequency' [(80, genConst >>* fst), (20, genNewItem False >>* fst)]
|
(do upper <- frequency' [(80, genConst >>* fst), (20, genNewItem False >>* fst)]
|
||||||
itemCount <- lift $ choose (1,6)
|
itemCount <- lift $ choose (1,6)
|
||||||
items <- replicateM itemCount (genNewItem False >>* fst)
|
items <- replicateM itemCount (genNewItem True)
|
||||||
return (items, upper)
|
return (items, upper)
|
||||||
)
|
)
|
||||||
return (makeResults vm items upper, ParItems $ map (\(x,_) -> SeqItems [[x]]) items, fst upper)
|
return (makeResults vm items upper, ParItems $ map (\((x,_),_) -> SeqItems [[x]]) items, fst upper)
|
||||||
where
|
where
|
||||||
makeResults :: VarMap ->
|
makeResults :: VarMap ->
|
||||||
[GenEqItems] ->
|
[(GenEqItems, FlattenedExp)] ->
|
||||||
GenEqItems ->
|
GenEqItems ->
|
||||||
[((A.Expression, A.Expression),VarMap,[HandyEq],[HandyIneq])]
|
[((A.Expression, A.Expression),VarMap,[HandyEq],[HandyIneq])]
|
||||||
makeResults vm items upper = map (flip (makeResult vm) upper) (allPairs items)
|
makeResults vm items upper = concatMap (flip (makeResult vm) upper) (allPairs items)
|
||||||
|
|
||||||
makeResult :: VarMap -> (GenEqItems, GenEqItems) -> GenEqItems -> ((A.Expression, A.Expression),VarMap,[HandyEq],[HandyIneq])
|
makeResult :: VarMap -> ((GenEqItems, FlattenedExp), (GenEqItems, FlattenedExp)) -> GenEqItems -> [((A.Expression, A.Expression),VarMap,[HandyEq],[HandyIneq])]
|
||||||
makeResult vm ((ex,x),(ey,y)) (_,u) = ((ex, ey), vm, [x === y], leq [con 0, x, u ++ con (-1)] &&& leq [con 0, y, u ++ con (-1)])
|
makeResult vm (((ex,x),fx),((ey,y),fy)) (_,u) = mkItem (ex, moduloEq vm fx) (ey, moduloEq vm fy)
|
||||||
|
where
|
||||||
|
mkItem :: (A.Expression, [([(CoeffIndex, Integer)], [HandyEq], [HandyIneq])]) ->
|
||||||
|
(A.Expression, [([(CoeffIndex, Integer)], [HandyEq], [HandyIneq])]) ->
|
||||||
|
[((A.Expression, A.Expression),VarMap,[HandyEq],[HandyIneq])]
|
||||||
|
mkItem (ex, xinfo) (ey, yinfo) = map (\(eq,ineq) -> ((ex,ey),vm,eq,ineq)) $ map (uncurry joinItems) (product2 (xinfo, yinfo))
|
||||||
|
|
||||||
|
joinItems :: ([(CoeffIndex, Integer)], [HandyEq], [HandyIneq]) ->
|
||||||
|
([(CoeffIndex, Integer)], [HandyEq], [HandyIneq]) ->
|
||||||
|
([HandyEq],[HandyIneq])
|
||||||
|
joinItems (x, xEq, xIneq) (y, yEq, yIneq) = ([x === y] &&& xEq &&& yEq, xIneq &&& yIneq &&& arrayBound x u &&& arrayBound y u)
|
||||||
|
|
||||||
|
arrayBound :: [(CoeffIndex, Integer)] -> [(CoeffIndex, Integer)] -> [HandyIneq]
|
||||||
|
arrayBound x u = leq [con 0, x, u ++ con (-1)]
|
||||||
|
|
||||||
|
moduloEq :: VarMap -> FlattenedExp -> [([(CoeffIndex, Integer)], [HandyEq], [HandyIneq])]
|
||||||
|
moduloEq vm m@(Modulo top bottom) = let topVar = lookupF (Set.findMin top {-TODO-} ) vm in let modVar = lookupF m vm in case onlyConst (Set.toList bottom) of
|
||||||
|
Just c -> [ ([(0,0)], [topVar === con 0], [])
|
||||||
|
, (topVar ++ (abs c)**modVar, [], [topVar >== con 1, modVar <== con 0] &&& leq [con 0, topVar ++ (abs c)**modVar, con (abs c - 1)])
|
||||||
|
, (topVar ++ (abs c)**modVar, [], [topVar <== con (-1), modVar >== con 0] &&& leq [con (1 - abs c), topVar ++ (abs c)**modVar, con 0])
|
||||||
|
]
|
||||||
|
Nothing -> [] --TODO (variable divisor)
|
||||||
|
-- TODO add divide here with equations
|
||||||
|
moduloEq vm exp = [(lookupF exp vm, [], [])]
|
||||||
|
|
||||||
|
lookupF :: FlattenedExp -> VarMap -> [(CoeffIndex, Integer)]
|
||||||
|
lookupF (Const c) _ = con c
|
||||||
|
lookupF f@(Scale a v) vm = [(fromJust $ Map.lookup f vm, a)]
|
||||||
|
lookupF f@(Modulo t b) vm = [(fromJust $ Map.lookup f vm, 1)]
|
||||||
|
lookupF f@(Divide t b) vm = [(fromJust $ Map.lookup f vm, 1)]
|
||||||
|
|
||||||
qcTestMakeEquations :: [LabelledQuickCheckTest]
|
qcTestMakeEquations :: [LabelledQuickCheckTest]
|
||||||
qcTestMakeEquations = [("Turning Code Into Equations", scaleQC (100,100,100,100) prop)]
|
qcTestMakeEquations = [("Turning Code Into Equations", scaleQC (100,100,100,100) prop)]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user