Newer
Older
module LogicIR.Backend.Rewrite (replaceQuantifiers) where
import LogicIR.Expr
import LogicIR.Fold
import LogicIR.Backend.Pretty
-- Expands quantifiers in given LExpr and returns a quantifier free LExpr.
replaceQuantifiers :: LExpr -> LExpr
replaceQuantifiers = foldLExpr replaceQuantifiersAlgebra
Joris ten Tusscher
committed
type Env = Int
replaceQuantifiersEnvAlgebra :: LExprAlgebra (Env -> LExpr)
replaceQuantifiersEnvAlgebra = (cnst, var, uni, bin, iff, quant, arr, snull, len)
where cnst c = \env -> LConst c
uni op e = \env -> LUnop op (e env)
bin e1 op e2 = \env -> LBinop (e1 env) op (e2 env)
iff ge e1 e2 = \env -> LIf (ge env) (e1 env) (e2 env)
var v = \env -> LVar v
quant t v d e = \env -> replaceQuantifier t v (d (env*2)) (e (env*2+1))
arr v e = \env -> LArray v (e env)
snull v = \env -> LIsnull v
len v = \env -> LLen v
replaceQuantifiersAlgebra :: LExprAlgebra LExpr
replaceQuantifiersAlgebra = (cnst, var, uni, bin, iff, quant, arr, snull, len)
where cnst = LConst
uni = LUnop
bin = LBinop
iff = LIf
var = LVar
quant t v d e = replaceQuantifier t v d e
arr = LArray
snull = LIsnull
len = LLen
-- replaces an LQuant with a conjunction (if universal) or disjunction (if
-- existential). In the second argument of the con/disjunct, the quantifier Var
-- is replaced by Var'. This makes it possible to just substitute both of them
-- with a value in the end. Since Java identifiers can't contain the ' char,
-- we can safely assume that Varname ++ ' is always a fresh identifier.
replaceQuantifier :: QOp -> Var -> LExpr -> LExpr -> LExpr
replaceQuantifier op var domain e = LBinop e1 combiner e2
where prime (Var t name) = Var t (name ++ "'")
e1 = LBinop domain LImpl e
e2 = replace var (prime var) (LBinop domain LImpl e)
combiner = if op == QAll then LAnd else LOr
-- Returns an LExpr where all occurences of vOld in the given LExpr are
-- replaced by vNew.
replace :: Var -> Var -> LExpr -> LExpr
replace vOld vNew = foldLExpr algebra
where algebra :: LExprAlgebra LExpr
algebra = (cnst, var, uni, bin, iff, quant, arr, snull, len)
subst v = if v == vOld then vNew else v
cnst c = LConst c
uni o c = LUnop o c
bin le o re = LBinop le o re
iff ge e1 e2 = LIf ge e1 e2
var v = LVar (subst v)
quant t v d e = replaceQuantifier t v d e
arr v e = LArray (subst v) e
snull v = LIsnull (subst v)
len v = LLen (subst v)