Example #1
0
    def addOriginSMTConstraints(self):
        """
        Realize to transfer the CCSL constraints into SMT formula.
        :return:
        """
        cnt = 0
        for each in self.newCCSLConstraintList:
            if each[0] == "<" and len(each) == 3:
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(
                            z3.Implies(
                                history1(i) == history2(i), z3.Not(tick2(i))))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n, history1(x) == history2(x)),
                    #     z3.Not(tick2(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                z3.And(x >= 1,
                                       history1(x) == history2(x)),
                                z3.Not(tick2(x)))))

            elif each[0] == "<" and len(each) == 4:
                tick1 = self.tickDict["t_%s" % (each[1])]
                delay = each[2]
                tick2 = self.tickDict["t_%s" % (each[3])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(
                            z3.Implies(
                                history2(i) - history1(i) == delay,
                                z3.Not(tick2(i))))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n, history2(x) - history1(x) == delay),
                    #     z3.Not(tick2(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                z3.And(x >= 1,
                                       history2(x) - history1(x) == delay),
                                z3.Not(tick2(x)))))

            elif each[0] == "≤":
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(history1(i) >= history2(i))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n + 1),
                    #     history1(x) >= history2(x))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x, z3.Implies(x >= 1,
                                          history1(x) >= history2(x))))

            elif each[0] == "⊆":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 1):
                        self.solver.add(z3.Implies(tick1(i), tick2(i)))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n, tick1(x)),
                    #     tick2(x))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x, z3.Implies(z3.And(x >= 1, tick1(x)), tick2(x))))

            elif each[0] == "#":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 1):
                        self.solver.add(
                            z3.Or(z3.Not(tick1(i)), z3.Not(tick2(i))))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n),
                    #     z3.Or(z3.Not(tick1(x)), z3.Not(tick2(x))))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 1,
                                z3.Or(z3.Not(tick1(x)), z3.Not(tick2(x))))))

            elif each[0] == "+":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                tick3 = self.tickDict["t_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 1):
                        self.solver.add(tick1(i) == z3.Or(tick2(i), tick3(i)))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #         z3.And(x >= 1, x <= self.n),
                    #         tick1(x) == z3.Or(tick2(x), tick3(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(x >= 1,
                                       tick1(x) == z3.Or(tick2(x), tick3(x)))))

            elif each[0] == "*":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                tick3 = self.tickDict["t_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 1):
                        self.solver.add(
                            z3.Implies(tick1(i), z3.And(tick2(i), tick3(i))))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #         z3.And(x >= 1, x <= self.n),
                    #         tick1(x) == z3.And(tick2(x), tick3(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(x >= 1,
                                       tick1(x) == z3.And(tick2(x),
                                                          tick3(x)))))

            elif each[0] == "∧":
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                history3 = self.historyDict["h_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(
                            history1(i) == z3.If(
                                history2(i) >= history3(i), history2(i),
                                history3(i)))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n + 1),
                    #     history1(x) == z3.If(history2(x) >= history3(x),history2(x),history3(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 1,
                                history1(x) == z3.If(
                                    history2(x) >= history3(x), history2(x),
                                    history3(x)))))

            elif each[0] == "∨":
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                history3 = self.historyDict["h_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(
                            history1(i) == z3.If(
                                history2(i) <= history3(i), history2(i),
                                history3(i)))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n + 1),
                    #     history1(x) == z3.If(history2(x) <= history3(x), history2(x), history3(x)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 1,
                                history1(x) == z3.If(
                                    history2(x) <= history3(x), history2(x),
                                    history3(x)))))

            elif each[0] == "$":
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                delay = z3.IntVal(int(each[3]))
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, self.bound + 2):
                        self.solver.add(
                            history1(i) == z3.If(
                                history2(i) >= delay,
                                history2(i) - delay, 0))
                    # self.solver.add(z3.ForAll(x, z3.Implies(
                    #     z3.And(x >= 1, x <= self.n + 1),
                    #     history1(x) == z3.If(history2(x) >= delay,history2(x) - delay,0))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 1,
                                history1(x) == z3.If(
                                    history2(x) >= delay,
                                    history2(x) - delay, 0))))

            elif each[0] == "on":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                tick3 = self.tickDict["t_%s" % (each[4])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                history3 = self.historyDict["h_%s" % (each[4])]
                self.addTickStep(each[1])
                self.addTickStep(each[2])
                self.addTickStep(each[4])
                tickStep1 = self.tickStep["s_%s" % (each[1])]
                tickStep2 = self.tickStep["s_%s" % (each[2])]
                tickStep3 = self.tickStep["s_%s" % (each[4])]
                x = z3.Int("x")
                if self.bound > 0:
                    for i in range(1, int(each[3]) + 1):
                        self.solver.add(z3.Not(tick1(i)))
                    for i in range(int(each[3]) + 1, self.bound + 1):
                        t = []
                        for j in range(1, i - int(each[3]) + 1):
                            t.append(
                                z3.And(
                                    tick2(j),
                                    history3(i) - history3(j) == int(each[3])))
                        self.solver.add(z3.And(tick3(i), z3.Or(t)) == tick1(i))
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(z3.And(x > 0, x <= self.n + 1),
                                       history2(x) >= history1(x))))
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(z3.And(x > 0, x <= self.n, tick1(x)),
                                       tick3(x))))
                    # self.solver.add(
                    #     z3.ForAll(x, z3.Implies(
                    #         z3.And(x > 0, x <= history1(self.bound + 1)),
                    #         history3(tickStep2(x)) - history3(tickStep1(x)) == int(each[3])
                    # )))
                    # for i in range(self.bound + 1):
                    #     self.solver.add(history2(i) >= history1(i))
                    # for i in range(self.bound):
                    #     self.solver.add(
                    #         z3.Implies(
                    #             tick1(i), tick3(i)
                    #         )
                    #     )
                    # for i in range(self.bound + 1):
                    #     self.solver.add(
                    #         history3(tickStep1(i)) - history3(tickStep2(i)) == int(each[3])
                    #     )

                    # self.solver.add(z3.ForAll(x, z3.And(
                    #     z3.Implies(z3.And(x >= 1, x <= history1(self.bound + 1),tick2(x)),
                    #         tick1(tickStep3(history3(x) + int(each[3])))
                    #     ))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.And(
                                z3.Implies(x >= 1,
                                           history2(x) >= history1(x)))))
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.And(
                                z3.Implies(z3.And(x >= 1, tick1(x)),
                                           tick3(x)))))
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.And(
                                z3.Implies(x >= 1, (history3(tickStep1(x)) -
                                                    history3(tickStep2(x))
                                                    == int(each[3]))))))
            elif each[0] == "∝":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                x = z3.Int("x")
                left = tick1(x)
                if is_number(each[3]):
                    k = z3.Int("k_%s" % (cnt))
                    self.solver.add(k >= 0, k < int(each[3]))
                    right = z3.And(tick2(x),
                                   history2(x) >= 0,
                                   (history2(x) + k) % z3.IntVal(each[3]) == 0)
                    cnt += 1
                    # right = z3.And(tick2(x), history2(x) > 0, (history2(x)) % z3.IntVal(each[3]) == 0)
                else:
                    period = z3.Int("%s" % each[3])
                    tmp = self.parameter[each[3]]
                    self.printParameter[each[3]] = period
                    k = z3.Int("k_%s" % (cnt))
                    self.solver.add(k >= 0, k < period)
                    right = z3.And(tick2(x),
                                   history2(x) >= 0,
                                   (history2(x) + k) % period == 0)
                    self.solver.add(period >= int(tmp[2]))
                    self.solver.add(period <= int(tmp[3]))
                    cnt += 1
                if self.bound > 0:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.And(
                                z3.Implies(z3.And(x >= 1, x <= self.n),
                                           left == right))))
                else:
                    self.solver.add(
                        z3.ForAll(x, z3.And(z3.Implies(x >= 1,
                                                       left == right))))

            elif each[0] == "☇":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                tick3 = self.tickDict["t_%s" % (each[3])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                history3 = self.historyDict["h_%s" % (each[3])]
                self.addTickStep(each[1])
                self.addTickStep(each[3])
                tickStep1 = self.tickStep["s_%s" % (each[1])]
                tickStep3 = self.tickStep["s_%s" % (each[3])]
                x = z3.Int("x")
                if self.bound > 0:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                z3.And(x >= 2, x <= history3(self.bound + 1)),
                                tick1(tickStep1(x)) == (
                                    history2(tickStep3(x)) -
                                    history2(tickStep3(x - 1)) >= 1))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 2,
                                z3.And(
                                    tick1(tickStep1(x)),
                                    history2(tickStep3(x)) -
                                    history2(tickStep3(x - 1)) >= 1))))

            elif each[0] == "==":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                x = z3.Int("x")
                if self.bound > 0:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(z3.And(x >= 1, x <= self.n),
                                       tick1(x) == tick2(x))))
                else:
                    self.solver.add(
                        z3.ForAll(x, z3.Implies(x >= 1,
                                                tick1(x) == tick2(x))))
            elif each[0] == "⋈±":
                tick1 = self.tickDict["t_%s" % (each[1])]
                tick2 = self.tickDict["t_%s" % (each[2])]
                history1 = self.historyDict["h_%s" % (each[1])]
                history2 = self.historyDict["h_%s" % (each[2])]
                self.addTickStep(each[1])
                self.addTickStep(each[2])
                tickStep1 = self.tickStep["s_%s" % (each[1])]
                tickStep2 = self.tickStep["s_%s" % (each[2])]

                lower = int(each[3]) - int(each[4])
                upper = int(each[3]) + int(each[4])
                x = z3.Int("x")
                if self.bound > 0:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                z3.And(x >= 1, x <= self.bound + 1, tick1(x)),
                                history1(tickStep2(history2(x) + upper)) -
                                history1(
                                    tickStep2(history2(x) + lower)) == 1)))
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                z3.And(x >= 2, x <= history1(self.bound + 1)),
                                z3.And(
                                    (history2(tickStep1(x)) -
                                     history2(tickStep1(x - 1)) >= lower),
                                    (history2(tickStep1(x)) -
                                     history2(tickStep1(x - 1)) <= upper)))))
                else:
                    self.solver.add(
                        z3.ForAll(
                            x,
                            z3.Implies(
                                x >= 2,
                                z3.And(
                                    (history2(tickStep1(x)) -
                                     history2(tickStep1(x - 1)) >= lower),
                                    (history2(tickStep1(x)) -
                                     history2(tickStep1(x - 1)) <= upper)))))
Example #2
0
def symread_neq(a, b, size=MAX_SYM_READ_SIZE):
    return z3.Not(symread_eq(a, b, size))
Example #3
0
class Z3Context(Context):
    def __init__(self, *args, **kw):
        Context.__init__(self, *args, **kw)
        self.solver = z3.Solver()

    def __getitem__(self, key):
        if not isinstance(key, Sort) and key in self.storage:
            return self.storage[key]
        elif isinstance(key, Sort):
            if key.name in self.storage:
                return self.storage[key.name]
            val = self.new_from_sort(key)
            self.storage[key.name] = val
            return val
        else:
            raise ValueError("%s not found! %s. %s." %(key, type(key), self.storage))

    def new_from_sort(self, key):
        if isinstance(key, Bool):
            key = key.name
            val = z3.Bool(key)
            return val
        elif isinstance(key, Int):
            key = key.name
            val = z3.Int(key)
            return val
        elif isinstance(key, String):
            key = key.name
            val = z3.String(key)
            return val
        elif isinstance(key, BitVec):
            name = key.name
            size = key.size
            val = z3.BitVec(name, size)
            return val
        raise TypeError("%s not supported!" %type(key))

    def s_assert(self, expr):
        self.solver.assert_exprs(expr.cval(self))

    def s_check(self):
        res = self.solver.check()
        return res

    def s_model(self):
        try:
            m = self.solver.model()
            return self.process_model(m)
        except z3.Z3Exception:
            return {}

    def s_push(self):
        self.solver.push()

    def s_pop(self):
        self.solver.pop()

    def s_reset(self):
        self.solver.reset()

    def solve(self, AST):
        outputs = []
        self.s_reset()
        for node in AST:
            if isinstance(node, Sort):
                self.s_assert(node)
            elif isinstance(node, Let):
                self.s_assert(node.term)
            elif isinstance(node, Command):
                if node.cname == "push":
                    self.s_push()
                elif node.cname == "pop":
                    self.s_pop()
                elif node.cname == "check-sat":
                    logger.info("\n-------")
                    outputs.append(self.s_check())
                    logger.info("Check: %s" % outputs[-1])
                elif node.cname == "get-model":
                    outputs.append(self.s_model())
                    logger.info("Model: %s" % outputs[-1])
            else:
                raise ValueError("Command %s not supported!" %node)
        
        return outputs

    def process_model(self, z3_model):
        m = {}
        for v in z3_model:
            m[v.name()] = self.get_py_value(z3_model.get_interp(v))
        return m

    def get_py_value(self, assignment):
        if z3.is_ast(assignment):
            if z3.is_int_value(assignment):
                return assignment.as_long()
            if z3.is_bool(assignment):
                return z3.is_true(assignment)
            if z3.is_string_value(assignment):
                try:
                    val = assignment.as_string()[1:-1]  # remove quotes
                    val = val.replace("\\x00", "")
                    return str(val)
                # Z3 throws encoding errors. It can't decode its own solution..
                # TODO find a better fix.
                except UnicodeDecodeError:
                    val = assignment.as_ast()
                    return repr(val)
            raise ValueError("Unsupported Z3 type! %s" % type(assignment))
        
        return assignment

    BoolVal = lambda self, x : z3.BoolVal(x)
    StringVal = lambda self, x : z3.StringVal(x)
    IntVal = lambda self, x : z3.IntVal(x)
    BitVecVal = lambda self, val, size : z3.BitVecVal(val, size)

    And = lambda self, *x : z3.And(x)
    Or = lambda self, *x : z3.Or(x)
    Xor = lambda self, *x : reduce(xor, x)
    Implies = lambda self, x, y : z3.Implies(x, y)
    Distinct = lambda self, x, y : z3.Distinct(x, y)

    def Eq(self, x, y):
        # x = z3.String("x")
        # x == "test" #throws an error. This is a workaround for now.
        x = z3.StringVal(x) if isinstance(x,str) else x
        y = z3.StringVal(y) if isinstance(y,str) else y
        return eq(x,y)

    Not = lambda self, x : z3.Not(x)

    If = lambda self, *x : z3.If(*x)

    add = lambda self, *x : reduce(add, x)
    sub = lambda self, *x : reduce(sub, x) if len(x) > 1 else -x[0]
    mul = lambda self, *x : reduce(mul, x)
    
    lt = lambda self, *x : reduce(lt, x)
    le = lambda self, *x : reduce(le, x)
    gt = lambda self, *x : reduce(gt, x)
    ge = lambda self, *x : reduce(ge, x)

    concat = lambda self, *x : reduce(add, x)
    length = lambda self, x : z3.Length(x)
    contains = lambda self, x, y : z3.Contains(x, y)
    indexof = lambda self, x, y, z=0 : z3.IndexOf(x, y, z)
    extract = lambda self, x, y, z : z3.Extract(x, y, z)

    bvadd = add
    bvsub = sub
    bvmul = mul
    bvxor = Xor
    bvneg = lambda self, x : neg(x)
    bvnot = lambda self, x : inv(x)
    bvconcat = lambda self, *x : z3.Concat(*x)
    bvlshr = lambda self, x, y : z3.LShR(x, y)
    bvlshl = lambda self, x, y : z3.LShL(x, y)
    bvuge = lambda self, x, y : z3.UGE(x, y)
    bvurem = lambda self, x, y : z3.URem(x, y)

    # TODO Need to define all these with stuff in computation folder
    FPAbs = lambda self, *x : None
    FPNeg = lambda self, *x : None
    FPAdd = lambda self, *x : None
    FPSub = lambda self, *x : None
    FPMul = lambda self, *x : None
    FPDiv = lambda self, *x : None
    FPFMA = lambda self, *x : None
    FPRem = lambda self, *x : None
    FPSqrt = lambda self, *x : None
    FPRoundToIntegral = lambda self, *x : None
    FPMin = lambda self, *x : None
    FPMax = lambda self, *x : None
    FPLEQ = lambda self, *x : None
    FPLT = lambda self, *x : None
    FPGEQ = lambda self, *x : None
    FPGT = lambda self, *x : None
    FPEQ = lambda self, *x : None
    FPIsNormal = lambda self, *x : None
    FPIsSubNormal = lambda self, *x : None
    FPIsZero = lambda self, *x : None
    FPIsInfinite = lambda self, *x : None
    FPIsNan = lambda self, *x : None
    FPIsNegative = lambda self, *x : None
    FPIsPositive = lambda self, *x : None