Esempio n. 1
0
    def all_loopbacks(self, vars, k, heqvar=None):
        lvars = list(vars)
        vars_k = [TS.get_timed(v, k) for v in lvars]
        loopback = FALSE()
        eqvar = None
        heqvars = None

        if heqvar is not None:
            eqvar = Symbol(EQVAR, BOOL)
            heqvars = []

        peqvars = FALSE()

        for i in range(k):
            vars_i = [TS.get_timed(v, i) for v in lvars]
            eq_k_i = And(
                [EqualsOrIff(vars_k[j], vars_i[j]) for j in range(len(lvars))])
            if heqvar is not None:
                eqvar_i = TS.get_timed(eqvar, i)
                peqvars = Or(peqvars, eqvar_i)
                eq_k_i = And(eqvar_i, Iff(eqvar_i, eq_k_i))

                heqvars.append(Iff(TS.get_timed(heqvar, i), peqvars))

            loopback = Or(loopback, eq_k_i)

        if heqvar is not None:
            loopback = And(loopback, And(heqvars))

        return loopback
Esempio n. 2
0
    def all_simple_loopbacks(self, vars, k):
        lvars = list(vars)
        vars_k = [TS.get_timed(v, k) for v in lvars]
        loopback = []
        eqvar = None
        heqvars = None

        peqvars = FALSE()
            
        for i in range(k):
            vars_i = [TS.get_timed(v, i) for v in lvars]
            eq_k_i = And([EqualsOrIff(vars_k[j], vars_i[j]) for j in range(len(lvars))])
                
            loopback.append(eq_k_i)

        loopback.append(FALSE())
        return loopback
Esempio n. 3
0
    def _remap_model_zz(self, vars, model, k):
        retmodel = dict([el for el in dict(model).items() if not TS.is_ptimed(el[0])])

        for var in vars:
            for t in range(int(k/2)+1, k+1, 1):
                retmodel[TS.get_timed(var, t)] = model[TS.get_ptimed(var, k-t)]

        return retmodel
Esempio n. 4
0
def revise_abstract_clock(model, abstract_clock_list):
    newmodel = {}
    abs_clock = dict(abstract_clock_list)
    length = 0
    for var, value in model.items():
        refvar = TS.get_ref_var(var)
        time = TS.get_time(var)

        if time > 0:
            if refvar not in abs_clock:
                newmodel[TS.get_timed(refvar, (time*2)-1)] = value
                newmodel[TS.get_timed(refvar, (time*2))] = value
            else:
                newmodel[TS.get_timed(refvar, (time*2)-1)] = abs_clock[refvar][1]
                if value == abs_clock[refvar][1]:
                    newmodel[TS.get_timed(refvar, (time*2))] = abs_clock[refvar][0]
                else:
                    newmodel[TS.get_timed(refvar, (time*2))] = abs_clock[refvar][1]
                if ((time*2)+1) > length:
                    length = ((time*2))
        else:
            if refvar not in abs_clock:
                newmodel[TS.get_timed(refvar, 0)] = value
            else:
                newmodel[TS.get_timed(refvar, 0)] = abs_clock[refvar][0]

    return (newmodel, length)
Esempio n. 5
0
    def _remap_model_zz(self, vars, model, k):
        retmodel = dict(model)

        for var in vars:
            for t in range(int(k / 2) + 1, k + 1, 1):
                retmodel[TS.get_timed(var,
                                      t)] = model[TS.get_ptimed(var, k - t)]

        return retmodel
Esempio n. 6
0
    def _remap_model_bwd(self, vars, model, k):
        retmodel = dict()

        for var in vars:
            for t in range(k + 1):
                retmodel[TS.get_timed(var,
                                      t)] = model[TS.get_ptimed(var, k - t)]

        return retmodel
Esempio n. 7
0
    def loop_free(self, vars_, k_end, k_start=0):
        Logger.log("Simple path from %s to %s"%(k_start, k_end), 2)

        if k_end == k_start:
            return TRUE()

        def not_eq_states(vars1, vars2):
            assert len(vars1) == len(vars2)
            eqvars = []
            for i in range(len(vars1)):
                eqvars.append(EqualsOrIff(vars1[i], vars2[i]))
            return Not(And(eqvars))

        lvars = list(vars_)
        end_vars = [TS.get_timed(v, k_end) for v in lvars]

        formula = []
        for t in range(k_start, k_end, 1):
            formula.append(not_eq_states(end_vars, [TS.get_timed(v, t) for v in lvars]))

        return And(formula)
Esempio n. 8
0
    def print_trace(self,
                    hts,
                    modeldic,
                    length,
                    map_function=None,
                    find_loop=False):
        trace = []
        prevass = []

        hex_values = False

        trace.append("---> INIT <---")

        if self.all_vars:
            varlist = list(hts.vars)
        else:
            varlist = list(
                hts.input_vars.union(hts.output_vars).union(hts.state_vars))
            if self.extra_vars is not None:
                varlist = list(set(varlist).union(set(self.extra_vars)))

        strvarlist = [(map_function(var.symbol_name()), var) for var in varlist
                      if not self.is_hidden(var.symbol_name())]
        strvarlist.sort()

        for var in strvarlist:
            var_0 = TS.get_timed(var[1], 0)
            if var_0 not in modeldic:
                continue
            varass = (var[0], modeldic[var_0])
            if hex_values:
                varass = (varass[0],
                          dec_to_hex(varass[1].constant_value(),
                                     int(var[1].symbol_type().width / 4)))
            if self.diff_only: prevass.append(varass)
            trace.append("  I: %s = %s" % (varass[0], varass[1]))

        if self.diff_only: prevass = dict(prevass)

        for t in range(length):
            trace.append("\n---> STATE %s <---" % (t + 1))

            for var in strvarlist:
                var_t = TS.get_timed(var[1], t + 1)
                if var_t not in modeldic:
                    continue
                varass = (var[0], modeldic[var_t])
                if hex_values:
                    varass = (varass[0],
                              dec_to_hex(varass[1].constant_value(),
                                         int(var[1].symbol_type().width / 4)))
                if (not self.diff_only) or (prevass[varass[0]] != varass[1]):
                    trace.append("  S%s: %s = %s" %
                                 (t + 1, varass[0], varass[1]))
                    if self.diff_only: prevass[varass[0]] = varass[1]

        if find_loop:
            last_state = [(var[0], modeldic[TS.get_timed(var[1], length)])
                          for var in strvarlist]
            last_state.sort()
            loop_id = -1
            for i in range(length):
                state_i = [(var[0], modeldic[TS.get_timed(var[1], i)])
                           for var in strvarlist]
                state_i.sort()
                if state_i == last_state:
                    loop_id = i
                    break
            if loop_id >= 0:
                trace.append("\n---> STATE %s loop to STATE %s <---" %
                             (length, loop_id))

        trace = NL.join(trace)
        return trace
Esempio n. 9
0
    def print_trace(self, hts, model, length, map_function=None, find_loop=False, abstract_clock_list=None):
        abstract_clock = (abstract_clock_list is not None) and (len(abstract_clock_list) > 0)
        if abstract_clock:
            (model, length) = revise_abstract_clock(model, abstract_clock_list)

        trace = []
        prevass = []

        # Initial state printing
        trace.append("%sINIT%s"%(PRE_TRACE, POS_TRACE))

        if self.all_vars:
            varlist = list(hts.vars)
        else:
            varlist = list(hts.input_vars.union(hts.output_vars))
            if self.prop_vars is not None:
                varlist = list(set(varlist).union(set(self.prop_vars)))

        strvarlist = [(map_function(var[0]), var[1]) for var in sort_system_variables(varlist, True) if not self.is_hidden(var[0])]

        for var in strvarlist:
            var_0 = TS.get_timed(var[1], 0)
            if var_0 not in model:
                prevass.append((var[0], None))
                continue
            varass = (var[0], model[var_0])
            if (self.values_base == TraceValuesBase.HEX) and (var[1].symbol_type().is_bv_type()):
                varass = (varass[0], "%d'h%s"%(var[1].symbol_type().width, dec_to_hex(varass[1].constant_value(), int(var[1].symbol_type().width/4))))
            if (self.values_base == TraceValuesBase.BIN) and (var[1].symbol_type().is_bv_type()):
                varass = (varass[0], "%d'b%s"%(var[1].symbol_type().width, dec_to_bin(varass[1].constant_value(), int(var[1].symbol_type().width))))
            if self.diff_only: prevass.append(varass)
            trace.append("  I: %s = %s"%(varass[0], varass[1]))

        if self.diff_only: prevass = dict(prevass)

        # Success state printing

        for t in range(length):
            trace.append("\n%s%s %d%s"%(PRE_TRACE, STATE, t+1, POS_TRACE))

            for var in strvarlist:
                var_t = TS.get_timed(var[1], t+1)
                if var_t not in model:
                    continue
                varass = (var[0], model[var_t])
                if (self.values_base == TraceValuesBase.HEX) and (var[1].symbol_type().is_bv_type()):
                    varass = (varass[0], "%d'h%s"%(var[1].symbol_type().width, dec_to_hex(varass[1].constant_value(), int(var[1].symbol_type().width/4))))
                if (self.values_base == TraceValuesBase.BIN) and (var[1].symbol_type().is_bv_type()):
                    varass = (varass[0], "%d'b%s"%(var[1].symbol_type().width, dec_to_bin(varass[1].constant_value(), int(var[1].symbol_type().width))))
                if (not self.diff_only) or (prevass[varass[0]] != varass[1]):
                    trace.append("  S%s: %s = %s"%(t+1, varass[0], varass[1]))
                    if self.diff_only: prevass[varass[0]] = varass[1]

        if find_loop:
            last_state = [(var[0], model[TS.get_timed(var[1], length)]) for var in strvarlist]
            last_state.sort()
            loop_id = -1
            for i in range(length):
                state_i = [(var[0], model[TS.get_timed(var[1], i)]) for var in strvarlist]
                state_i.sort()
                if state_i == last_state:
                    loop_id = i
                    break
            if loop_id >= 0:
                end = ("STATE %s"%loop_id) if loop_id > 0 else "INIT"
                trace.append("\n---> %s (Loop) <---"%(end))

        strtrace = NL.join(trace)
        trace = Trace(strtrace, length)
        trace.human_readable = True
        return trace
Esempio n. 10
0
    def sim_no_unroll(self, hts, cover, k, all_vars=True, inc=False):
        init = hts.single_init()
        invar = hts.single_invar()
        trans = hts.single_trans()

        init_0 = self.at_time(init, 0)
        invar_0 = self.at_time(invar, 0)
        trans_01 = self.unroll(trans, invar, 1)
        cover_1 = self.at_time(cover, 1)

        full_model = {}

        if all_vars:
            relevant_vars = hts.vars
        else:
            relevant_vars = hts.state_vars | hts.output_vars

        relevant_vars_0 = [TS.get_timed(v, 0) for v in relevant_vars]
        relevant_vars_1 = [TS.get_timed(v, 1) for v in relevant_vars]

        relevant_vars_01 = [(TS.get_timed(v, 0), TS.get_timed(v, 1), v) for v in relevant_vars]

        self._reset_assertions(self.solver)

        # Picking Initial State
        Logger.log("\nSolving for k=0", 1)
        self._add_assertion(self.solver, And(init_0, invar_0))

        if self._solve(self.solver):
            init_model =  self._get_model(self.solver, relevant_vars_0)
            init_0 = And([EqualsOrIff(v, init_model[v]) for v in relevant_vars_0])

            for v in relevant_vars_0:
                full_model[v] = init_model[v]

            Logger.msg(".", 0, not(Logger.level(1)))
        else:
            return (0, None)

        self._reset_assertions(self.solver)

        if inc:
            self._add_assertion(self.solver, trans_01)
            self._add_assertion(self.solver, invar_0)

        init_model = None
        for t in range(1, k + 1):
            Logger.log("\nSolving for k=%s"%(t), 1)

            if not inc:
                self._reset_assertions(self.solver, True)

                formula = And(init_0, invar_0)
                self._add_assertion(self.solver, trans_01)
            else:
                formula = init_0
                self._push(self.solver)

            self._add_assertion(self.solver, formula)

            res_step = self._solve(self.solver)

            if res_step:
                Logger.msg(".", 0, not(Logger.level(1)))
                Logger.log("Able to step forward at k=%s"%(t), 2)
                if all_vars:
                    init_model = self._get_model(self.solver)
                else:
                    init_model = self._get_model(self.solver, relevant_vars_1)
                model = init_model
            else:
                Logger.log("System deadlocked at k=%s"%(t), 2)
                return (-1, full_model)

            # Use previous model as initial state for next sat call
            init_0 = []
            init_1 = []

            for v in relevant_vars_01:
                if v[1] not in init_model:
                    continue
                val = init_model[v[1]]
                full_model[TS.get_timed(v[2], t)] = val
                init_0.append(EqualsOrIff(v[0], val))
                init_1.append(EqualsOrIff(v[1], val))

            init_0 = And(init_0)

            if cover != TRUE():
                init_1 = And(init_1)

                self._add_assertion(self.solver, init_1)
                self._add_assertion(self.solver, cover_1)

                res_cont = self._solve(self.solver)

                if res_cont:
                    Logger.log('Reached cover in no unroll simulation at k=%s'%(t), 2)
                    model = init_model
                    return (t, full_model)
                else:
                    Logger.log('Cover not reached at k=%s'%t, 2)

            if inc:
                self._pop(self.solver)

        return (t, full_model)
Esempio n. 11
0
    def solve_safety_inc_bwd(self, hts, prop, k, assert_property=False, generalize=None):
        solver = self.solver.copy("inc_bwd")

        self._reset_assertions(solver)

        has_next = TS.has_next(prop)

        if has_next:
            prop = TS.to_prev(prop)

        init = hts.single_init()
        trans = hts.single_trans()
        invar = hts.single_invar()

        formula = self.at_ptime(And(Not(prop), invar), -1)
        Logger.log("Add not property at time %d"%0, 2)
        self._add_assertion(solver, formula)

        skip_push = False
        constraints = TRUE()

        models = 0

        t = 0
        k_min = 1 if has_next else 0
        while (t < k+1):
            if not skip_push:
                self._push(solver)
                skip_push = False

            if not skip_push:
                pinit = self.at_ptime(init, t-1)
                Logger.log("Add init at time %d"%t, 2)
                self._add_assertion(solver, pinit)

            if constraints != TRUE():
                for j in range(t+1):
                    self._add_assertion(solver, self.at_ptime(constraints, j-1), "Addditional Constraints")

            if self.preferred is not None:
                try:
                    for (var, val) in self.preferred:
                        solver.solver.set_preferred_var(TS.get_timed(var, t), val)
                except:
                    Logger.warning("Current solver does not support preferred variables")
                    self.preferred = None

            if (t >= k_min) and self._solve(solver):
                Logger.log("Counterexample found with k=%s"%(t), 1)
                model = self._get_model(solver)
                models += 1

                if models > 20:
                    Logger.msg("R", 0, not(Logger.level(1)))
                    self._reset_solver(solver)
                    models = 0

                if generalize is not None:
                    constr, res = generalize(model, t)
                    if res:
                        return (t, model)
                    constraints = And(constraints, Not(constr))
                    skip_push = True
                    continue
                else:
                    return (t, model)
            else:
                Logger.log("No counterexample found with k=%s"%(t), 1)
                Logger.msg(".", 0, not(Logger.level(1)))

            self._pop(solver)
            skip_push = False

            trans_t = self.unroll(trans, invar, t, t+1)
            self._add_assertion(solver, trans_t)

            if assert_property and t > 0:
                prop_t = self.unroll(TRUE(), prop, t-1, t)
                self._add_assertion(solver, prop_t)

                Logger.log("Add property at time %d"%t, 2)

            t += 1

        return (t-1, None)
Esempio n. 12
0
    def solve_safety_inc_fwd(self, hts, prop, k, k_min, \
                             all_vars=False, generalize=None, prove=None):

        add_unsat_cons = False
        prove = self.config.prove if prove is None else prove

        solver_name = "inc_fwd%s"%("_prove" if prove else "")
        solver = self.solver.copy(solver_name)

        self._reset_assertions(solver)

        if prove:
            solver_ind = self.solver.copy("%s_ind"%solver_name)
            self._reset_assertions(solver_ind)

            if all_vars:
                relevant_vars = hts.vars
            else:
                relevant_vars = hts.state_vars | hts.output_vars

        init = hts.single_init()
        trans = hts.single_trans()
        invar = hts.single_invar()

        acc_init = TRUE()
        acc_prop = TRUE()
        acc_loop_free = TRUE()
        trans_t = TRUE()

        if self.config.simplify:
            Logger.log("Simplifying the Transition System", 1)
            if Logger.level(2):
                timer = Logger.start_timer("Simplify")

            init = simplify(init)
            trans = simplify(trans)
            invar = simplify(invar)
            if Logger.level(2):
                Logger.get_timer(timer)

        n_prop_t = FALSE()
        init_0 = self.at_time(And(init, invar), 0)
        Logger.log("Add init and invar", 2)
        self._add_assertion(solver, init_0)

        if prove:
            # add invariants at time 0, but not init
            self._add_assertion(solver_ind, self.at_time(invar, 0), "invar")

        next_prop = TS.has_next(prop)
        if next_prop:
            if k < 1:
                Logger.error("Invariant checking with next variables requires at least k=1")
            k_min = 1

        skip_push = False

        constraints = TRUE()

        t = k_min
        for i in range(t):
            trans_t = self.unroll(trans, invar, i+1, i)
            self._add_assertion(solver, trans_t)
            Logger.msg("Unroll and call check-sat without property", 2)
            # Note: Seems to help a lot to call check-sat here
            #       without this some solvers will run out of memory on large problems
            #       it likely lets them do some internal clean up, and learn some things
            #       about the model
            self._solve(solver)
            Logger.msg("_", 0, not(Logger.level(1)))
        while (t < k+1):
            if not skip_push:
                self._push(solver)
                skip_push = False

            t_prop = t-1 if next_prop else t

            if k_min > 0:
                if (not next_prop) or (next_prop and t>0):
                    if n_prop_t == FALSE():
                        n_prop_t = self.at_time(Not(prop), t_prop)
                    else:
                        n_prop_t = Or(n_prop_t, self.at_time(Not(prop), t_prop))
            else:
                n_prop_t = self.at_time(Not(prop), t)

            Logger.log("Add not property at time %d"%t, 2)
            if not skip_push:
                self._add_assertion(solver, n_prop_t, "Property")

            if constraints != TRUE():
                self._add_assertion(solver, self.at_time(constraints, t), "Addditional Constraints")

            if t >= k_min:
                Logger.log("\nSolving for k=%s"%(t), 1)

                if self.preferred is not None:
                    try:
                        for (var, val) in self.preferred:
                            for j in range(t+1):
                                solver.solver.set_preferred_var(TS.get_timed(var, j), val)
                    except:
                        Logger.warning("Current solver does not support preferred variables")
                        self.preferred = None

                if self._solve(solver):
                    Logger.log("Counterexample found with k=%s"%(t), 1)
                    model = self._get_model(solver)

                    if generalize is not None:
                        constr, res = generalize(model, t)
                        if res:
                            return (t, model)
                        constraints = And(constraints, Not(constr))
                        skip_push = True
                        continue
                    else:
                        return (t, model)
                else:
                    Logger.log("No counterexample found with k=%s"%(t), 1)
                    Logger.msg(".", 0, not(Logger.level(1)))

                    if add_unsat_cons and prove:
                        self._add_assertion(solver, Implies(self.at_time(And(init, invar), 1), self.at_time(Not(prop), t_prop+1)))
                        self._add_assertion(solver, Not(n_prop_t))
            else:
                Logger.log("\nSkipping solving for k=%s (k_min=%s)"%(t,k_min), 1)
                Logger.msg("_", 0, not(Logger.level(1)))

            self._pop(solver)
            skip_push = False

            if prove:
                if t > k_min:
                    loop_free = self.loop_free(relevant_vars, t, t-1)

                    # Checking I & T & loopFree
                    acc_init = And(acc_init, self.at_time(Not(init), t))
                    acc_loop_free = And(acc_loop_free, loop_free)

                    self._push(solver)

                    self._add_assertion(solver, acc_init)
                    self._add_assertion(solver, acc_loop_free)

                    if self._solve(solver):
                        Logger.log("Induction (I & lF) failed with k=%s"%(t), 1)
                    else:
                        Logger.log("Induction (I & lF) holds with k=%s"%(t), 1)
                        return (t, True)

                    self._pop(solver)

                    # Checking T & loopFree & !P
                    self._add_assertion(solver_ind, trans_t, comment="trans")
                    self._add_assertion(solver_ind, loop_free, comment="loop_free")

                    self._push(solver_ind)

                    self._add_assertion(solver_ind, self.at_time(Not(prop), t_prop))

                    if self._solve(solver_ind):
                        Logger.log("Induction (lF & !P) failed with k=%s"%(t), 1)
                    else:
                        Logger.log("Induction (lF & !P) holds with k=%s"%(t), 1)
                        return (t, True)

                    self._pop(solver_ind)

                    self._add_assertion(solver_ind, self.at_time(prop, t_prop), "prop")
                else:
                    if not next_prop:
                        self._add_assertion(solver_ind, self.at_time(prop, t_prop), "prop")
                    else:
                        # add skipped transition
                        self._add_assertion(solver_ind, trans_t, comment="trans")


            trans_t = self.unroll(trans, invar, t+1, t)
            self._add_assertion(solver, trans_t)

            t += 1

        return (t-1, None)
Esempio n. 13
0
    def encode_l(self, formula, t_i, t_k, t_l):

        if formula.is_constant():
            return formula

        if formula.is_symbol():
            assert (t_i >= 0)
            return TS.get_timed(formula, t_i)

        if formula.is_equals():
            return self.mgr.Equals(
                self.encode_l(formula.args()[0], t_i, t_k, t_l),
                self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_and():
            return self.mgr.And(
                self.encode_l(formula.args()[0], t_i, t_k, t_l),
                self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_or():
            return self.mgr.Or(self.encode_l(formula.args()[0], t_i, t_k, t_l),
                               self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_lt():
            return self.mgr.LT(self.encode_l(formula.args()[0], t_i, t_k, t_l),
                               self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_bv_ult():
            return self.mgr.BVULT(
                self.encode_l(formula.args()[0], t_i, t_k, t_l),
                self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_bv_ule():
            return self.mgr.BVULE(
                self.encode_l(formula.args()[0], t_i, t_k, t_l),
                self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_implies():
            return self.mgr.Implies(
                self.encode_l(formula.args()[0], t_i, t_k, t_l),
                self.encode_l(formula.args()[1], t_i, t_k, t_l))

        if formula.is_not():
            return self.mgr.Not(self.encode_l(formula.args()[0], t_i, t_k,
                                              t_l))

        if formula.node_type() == LTL_X:
            if t_i < t_k:
                return self.encode_l(formula.args()[0], t_i + 1, t_k, t_l)
            return self.encode_l(formula.args()[0], t_l, t_k, t_l)

        if formula.node_type() == LTL_G:
            return And([
                self.encode_l(formula.args()[0], j, t_k, t_l)
                for j in range(min(t_i, t_l), t_k + 1, 1)
            ])

        if formula.node_type() == LTL_F:
            return Or([
                self.encode_l(formula.args()[0], j, t_k, t_l)
                for j in range(min(t_i, t_l), t_k + 1, 1)
            ])

        if formula.node_type() == LTL_U:
            formula_h = formula.args()[0]
            formula_g = formula.args()[1]

            u1 = Or([And(self.encode_l(formula_g, j, t_k, t_l), \
                         And([self.encode_l(formula_h, n, t_k, t_l) for n in range(t_i, j, 1)])) for j in range(t_i, t_k+1, 1)])

            u2 = Or([And(self.encode_l(formula_g, j, t_k, t_l), \
                         And([self.encode_l(formula_h, n, t_k, t_l) for n in range(t_i, t_k+1, 1)]), \
                         And([self.encode_l(formula_h, n, t_k, t_l) for n in range(t_l, j, 1)])) for j in range(t_l, t_i, 1)])

            return Or(u1, u2)

        if formula.node_type() == LTL_R:
            formula_h = formula.args()[0]
            formula_g = formula.args()[1]

            r1 = And([
                self.encode_l(formula_g, j, t_k, t_l)
                for j in range(min(t_i, t_l), t_k + 1, 1)
            ])

            r2 = Or([And(self.encode_l(formula_h, j, t_k, t_l), \
                         And([self.encode_l(formula_g, n, t_k, t_l) for n in range(t_i, j+1, 1)])) for j in range(t_i, t_k+1, 1)])

            r3 = Or([And(self.encode_l(formula_h, j, t_k, t_l), \
                         And([self.encode_l(formula_g, n, t_k, t_l) for n in range(t_i, t_k+1, 1)]), \
                         And([self.encode_l(formula_g, n, t_k, t_l) for n in range(t_l, j+1, 1)])) for j in range(t_l, t_i, 1)])

            return Or(r1, r2, r3)

        if formula.node_type() == LTL_O:
            return Or([
                self.encode_l(formula.args()[0], j, t_k, t_l)
                for j in range(t_i, t_k + 1, 1)
            ])

        if formula.node_type() == LTL_H:
            return And([
                self.encode_l(formula.args()[0], j, t_k, t_l)
                for j in range(t_i, t_k + 1, 1)
            ])

        Logger.error("Invalid LTL operator")
Esempio n. 14
0
    def encode(self, formula, t_i, t_k):
        if formula.is_constant():
            return formula

        if formula.is_symbol():
            assert (t_i >= 0)
            return TS.get_timed(formula, t_i)

        if formula.is_equals():
            return self.mgr.Equals(self.encode(formula.args()[0], t_i, t_k),
                                   self.encode(formula.args()[1], t_i, t_k))

        if formula.is_and():
            return self.mgr.And(self.encode(formula.args()[0], t_i, t_k),
                                self.encode(formula.args()[1], t_i, t_k))

        if formula.is_implies():
            return self.mgr.Or(
                self.mgr.Not(self.encode(formula.args()[0], t_i, t_k)),
                self.encode(formula.args()[1], t_i, t_k))

        if formula.is_not():
            return self.mgr.Not(self.encode(formula.args()[0], t_i, t_k))

        if formula.is_lt():
            return self.mgr.LT(self.encode(formula.args()[0], t_i, t_k),
                               self.encode(formula.args()[1], t_i, t_k))

        if formula.is_bv_ult():
            return self.mgr.BVULT(self.encode(formula.args()[0], t_i, t_k),
                                  self.encode(formula.args()[1], t_i, t_k))

        if formula.is_bv_ule():
            return self.mgr.BVULE(self.encode(formula.args()[0], t_i, t_k),
                                  self.encode(formula.args()[1], t_i, t_k))

        if formula.is_or():
            return self.mgr.Or(self.encode(formula.args()[0], t_i, t_k),
                               self.encode(formula.args()[1], t_i, t_k))

        if formula.node_type() == LTL_X:
            if t_i < t_k:
                return self.encode(formula.args()[0], t_i + 1, t_k)
            return FALSE()

        if formula.node_type() == LTL_G:
            return FALSE()

        if formula.node_type() == LTL_F:
            return Or([
                self.encode(formula.args()[0], j, t_k)
                for j in range(t_i, t_k + 1, 1)
            ])

        if formula.node_type() == LTL_U:
            formula_h = formula.args()[0]
            formula_g = formula.args()[1]

            return Or([And(self.encode(formula_g, j, t_k), \
                           And([self.encode(formula_h, n, t_k) for n in range(t_i, j, 1)])) for j in range(t_i, t_k+1, 1)])

        if formula.node_type() == LTL_R:
            formula_h = formula.args()[0]
            formula_g = formula.args()[1]

            return Or([And(self.encode(formula_h, j, t_k), \
                           And([self.encode(formula_g, n, t_k) for n in range(t_i, j+1, 1)])) for j in range(t_i, t_k+1, 1)])

        if formula.node_type() == LTL_O:
            return Or([
                self.encode(formula.args()[0], j, t_k)
                for j in range(t_i, t_k + 1, 1)
            ])

        if formula.node_type() == LTL_H:
            return And([
                self.encode(formula.args()[0], j, t_k)
                for j in range(t_i, t_k + 1, 1)
            ])

        Logger.error("Invalid LTL operator")