guarded-rewriting-0.1: performance/Gen/Arith/Rules.hs
module Gen.Arith.Rules where
import Common.Arith
import Common.GuardedRewriting
import Test.QuickCheck
import Data.Maybe (isJust, fromJust, catMaybes)
type PropRule = Rule (Prop (Equation Expr))
type EqRule = Rule (Equation Expr)
type ExprRule = Rule Expr
go = quickCheck $ forAll (sized propGen) (isSolved . solve rules)
rules :: [Prop (Equation Expr) -> Maybe (Prop (Equation Expr))]
rules = [ somewhereProp $ applyOne (map rewriteM propRules)
, liftToProp $ applyOne (map rewriteM eqRules)
, liftToProp $ liftToEq $ somewhereExpr $ applyOne (map rewriteM exprRules)
]
where
propRules :: [PropRule]
propRules =
[ coverPowerEven, divisionByZero
, eqSame, eqDifferent
, andTrueLeft, andTrueRight, andFalseLeft, andFalseRight
, orTrueLeft, orTrueRight, orFalseLeft, orFalseRight
, notTrue, notFalse
]
eqRules :: [EqRule]
eqRules =
[ coverPlusLeft, coverPlusRight, coverMinLeft, coverMinRight
, coverTimesLeft, coverTimesRight, coverDivLeft, coverDivRight
, coverPowerOdd
]
exprRules :: [ExprRule]
exprRules = [timesZeroLeft, timesZeroRight]
-- Rules
coverPlusLeft :: Rule (Equation Expr)
coverPlusLeft = synthesise $ \a b c ->
a :+: b :==: c +->
a :==: c :-: b // hasVaria a && noVaria b
coverPlusRight = synthesise $ \a b c ->
a :+: b :==: c +->
b :==: c :-: a // noVaria a && hasVaria b
coverMinLeft = synthesise $ \a b c ->
a :-: b :==: c +->
a :==: c :+: b // hasVaria a && noVaria b
coverMinRight = synthesise $ \a b c ->
a :-: b :==: c +->
b :==: a :-: c // noVaria a && hasVaria b
coverTimesLeft = synthesise $ \a b c ->
a :**: Const b :==: c +->
a :==: c :/: Const b // hasVaria a && b /= 0
coverTimesRight = synthesise $ \a b c ->
Const a :**: b :==: c +->
b :==: c :/: Const a // a /= 0 && hasVaria b
coverDivLeft = synthesise $ \a b c ->
a :/: Const b :==: c +->
a :==: c :**: Const b // hasVaria a && b /= 0
coverDivRight = synthesise $ \a b c ->
Const a :/: b :==: c +->
b :==: Const a :/: c // hasVaria b -- and b should not be zero here!
coverPowerEven = synthesise $ \a n b -> let new = b :^: Const (1/n) in
VarP (a :^: Const n :==: b) +->
VarP (a :==: new) :\/: VarP (a :==: Const 0 :-: new)
// hasVaria a && n > 0 && isEven n
coverPowerOdd = synthesise $ \a n b ->
a :^: Const n :==: b +->
a :==: b :^: Const (1/n) // hasVaria a && n > 0 && isOdd n
timesZeroLeft = synthesise $ \x ->
Const 0 :**: x +->
Const 0
timesZeroRight = synthesise $ \x ->
x :**: Const 0 +->
Const 0
divisionByZero = synthesise $ \a b ->
VarP (a :==: b) +->
F // hasDivisionByZero a || hasDivisionByZero b
--------------------------------------------------------
-- Rules for comparing the two sides of an equation
eqSame = synthesise $ \a b ->
VarP (a :==: b) +->
T // a == b
eqDifferent = synthesise $ \a b ->
VarP (Const a :==: Const b) +->
F // a /= b
----------------------------------
-- Propagating boolean constants
andTrueLeft = synthesise $ \p ->
T :/\: p +->
p
andTrueRight = synthesise $ \p ->
p :/\: T +->
p
andFalseLeft = synthesise $ \p ->
F :/\: p +->
F
andFalseRight = synthesise $ \p ->
p :/\: F +->
F
orTrueLeft = synthesise $ \p ->
T :\/: p +->
T
orTrueRight = synthesise $ \p ->
p :\/: T +->
T
orFalseLeft = synthesise $ \p ->
F :\/: p +->
p
orFalseRight = synthesise $ \p ->
p :\/: F +->
p
notTrue = synthesise $
Not T +->
F
notFalse = synthesise $
Not F +->
T