Skip to content
Snippets Groups Projects
Rewrite.hs 2.78 KiB
Newer Older
  • Learn to ignore specific revisions
  • 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
    
    
    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)