Skip to content
Snippets Groups Projects
Z3.hs 3.85 KiB
Newer Older
  • Learn to ignore specific revisions
  • module LogicIR.Backend.Z3 (lExprToZ3Ast) where
    
    import Z3.Monad
    
    import LogicIR.Expr
    import LogicIR.Fold
    
    lExprToZ3Ast :: LExpr -> Z3 AST
    lExprToZ3Ast = foldLExpr lExprToZ3AstAlgebra
    
    
    -- TODO: support more types
    
    lExprToZ3AstAlgebra :: LExprAlgebra (Z3 AST)
    
    lExprToZ3AstAlgebra = (flConst, flVar, flNot, flBinop, flComp, flQuant, flArray, flNil, fnConst, fnUnop, fnBinop, fnIf, fnLen) where
    
        flConst b = mkBool b
        flVar (Var t n) = do symbol <- mkStringSymbol n
                             case t of
    
                                  TPrim PInt32 -> mkBvVar symbol 32
    
                                  TPrim PBool -> mkBoolVar symbol
    
                                  TArray (TPrim PInt32) -> do intSort <- mkBvSort 32
                                                              arraySort <- mkArraySort intSort intSort
                                                              mkVar symbol arraySort
                                  TArray (TPrim PBool) -> do intSort <- mkBvSort 32
                                                             arraySort <- mkBoolSort >>= mkArraySort intSort
                                                             mkVar symbol arraySort
    
    Ogilvie, D.H. (Duncan)'s avatar
    Ogilvie, D.H. (Duncan) committed
                                  _ -> error $ "unsupported type: " ++ show n
    
        flNot a = a >>= mkNot
        flBinop a' o b' = do a <- a'
                             b <- b'
                             case o of
                                LAnd -> mkAnd [a, b]
                                LOr -> mkOr [a, b]
                                LImpl -> mkImplies a b
        flComp a' o b' = do a <- a'
                            b <- b'
                            case o of
                                CEqual -> mkEq a b
                                CNEqual -> mkEq a b >>= mkNot
    
                                CLess -> mkBvslt a b
                                CGreater -> mkBvsgt a b
                                CLeq -> mkBvsle a b
                                CGeq -> mkBvsge a b
        flQuant o v@(Var t n) a' = do a <- a'
                                      case t of
                                           TPrim PInt32 -> do vApp <- flVar v >>= toApp
                                                              case o of
                                                                   QAll -> mkForallConst [] [vApp] a
                                                                   QAny -> mkExistsConst [] [vApp] a
    
    Ogilvie, D.H. (Duncan)'s avatar
    Ogilvie, D.H. (Duncan) committed
                                           _ -> error $ "unsupported quantifier domain type: " show (o, v)
    
        flArray v a' = do v <- flVar v
                          a <- a'
                          mkSelect v a
        flNil = do intSort <- mkBvSort 32
    
    Ogilvie, D.H. (Duncan)'s avatar
    Ogilvie, D.H. (Duncan) committed
                   zero <- mkBitvector 32 0 -- (isNull, data, length) TODO: support proper null types
    
                   mkConstArray intSort zero
        fnConst n = mkBitvector 32 (fromIntegral n)
        fnUnop o a' = do a <- a'
                         case o of
                              NNeg -> mkBvneg a
                              NNot -> mkBvnot a
    
        fnBinop a' o b' = do a <- a'
                             b <- b'
                             case o of
    
                                NAdd -> mkBvadd a b
                                NSub -> mkBvsub a b
                                NMul -> mkBvmul a b
                                NDiv -> mkBvsdiv a b -- NOTE: signed division
                                NRem -> mkBvsrem a b -- TODO: check if the correct remainder is taken
                                NShl -> mkBvshl a b
                                NShr -> mkBvashr a b -- NOTE: signed shift right will keep the sign
                                NAnd -> mkBvand a b
                                NOr -> mkBvor a b
                                NXor -> mkBvxor a b
        fnIf c' a' b' = do c <- c'
                           a <- a'
                           b <- b'
                           mkIte c a b
    
    Ogilvie, D.H. (Duncan)'s avatar
    Ogilvie, D.H. (Duncan) committed
        fnLen (Var (TArray (TPrim _)) n) = mkStringSymbol (n ++ ".length") >>= flip mkBvVar 32 -- TODO: support proper array lengths