Пример #1
0
    def addStepCompressedConstraints(self):
        self.noneVars = []
        clauses = []
        # None at the step has to be true unless some task is true at
        # the step.
        for i in range(len(self.tasks)):
            self.noneVars.append(z3.Bool("None@" + str(i)))
            clauses.append(Or(self.noneVars[i],\
                              *[varTable[i] for var, varTable in self.taskVars.items()]))

        # If none is true at the step, then no task can be
        # true. Together, these two sets of constraints make up
        # bi-implication between the none variable, and no tasks being
        # accomplished at this step.
        for t in range(len(self.tasks)):
            for taskVar, varTable in self.taskVars.items():
                clauses.append(Or(Not(self.noneVars[t]),\
                                  Not(varTable[t])))

        # If any none variable is true, then the one after it is
        # true. Because of transitivity, this means that all none
        # variables after it are true.
        for i in range(len(self.tasks) - 1):
            clauses.append(Or(Not(self.noneVars[i]), self.noneVars[i + 1]))

        for clause in clauses:
            if self.debugPrint:
                print "adding clause " + str(clause)
            self.solver.add(clause)
Пример #2
0
    def addUniqueTaskStepConstraint(self):
        uniqueTaskStepConstraints = []

        # There is at most one task accomplished at any given
        # timestep.
        for t in range(len(self.tasks)):
            tasksLeft = list(self.tasks)
            while len(tasksLeft) > 0:
                task = tasksLeft.pop()
                for otherTask in tasksLeft:
                    uniqueTaskStepConstraints.append(Or(Not(self.taskVars[task][t]), \
                                                        Not(self.taskVars[otherTask][t])))

        # Each task is accomplished at at most one timestep.
        for task in self.tasks:
            timesLeft = range(len(self.tasks))
            while len(timesLeft) > 0:
                time = timesLeft.pop()
                for otherTime in timesLeft:
                    uniqueTaskStepConstraints.append(Or(Not(self.taskVars[task][time]),\
                                                        Not(self.taskVars[task][otherTime])))

        for constraint in uniqueTaskStepConstraints:
            self.solver.add(constraint)
        if self.debugPrint:
            print "Added unique task step contraints: " + str(
                uniqueTaskStepConstraints)
Пример #3
0
    def _test_gate(self, gate, ctrl_ones, trgtvar):
        """use z3 sat solver to determine triviality of gate
        Args:
            gate (Gate): gate to inspect
            ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        Returns:
            bool: if gate is trivial
        """
        trivial = False
        self.solver.push()

        try:
            triv_cond = gate._trivial_if(*trgtvar)
        except AttributeError:
            self.solver.add(ctrl_ones)
            trivial = self.solver.check() == unsat
        else:
            if isinstance(triv_cond, bool):
                if triv_cond and len(trgtvar) == 1:
                    self.solver.add(Not(And(ctrl_ones, trgtvar[0])))
                    sol1 = self.solver.check() == unsat
                    self.solver.pop()
                    self.solver.push()
                    self.solver.add(And(ctrl_ones, trgtvar[0]))
                    sol2 = self.solver.check() == unsat
                    trivial = sol1 or sol2
            else:
                self.solver.add(And(ctrl_ones, Not(triv_cond)))
                trivial = self.solver.check() == unsat

        self.solver.pop()
        return trivial
Пример #4
0
def add_nurikabe_constraints(sym, sg, rc):
    """Add the nurikabe constraints (one connected sea with no 2x2 regions)."""
    # There must be only one sea, containing all black cells.
    sea_id = Int("sea-id")
    for p in sg.lattice.points:
        sg.solver.add(sg.cell_is(p, sym.W) == (rc.region_id_grid[p] != sea_id))

    # Constrain sea_id to be the index of one of the points in
    # the smallest area, among those areas of size greater than 4.
    area_to_points = defaultdict(list)
    for p in sg.lattice.points:
        area_to_points[AREAS[p.y][p.x]].append(p)
    area_points = min((ps for ps in area_to_points.values() if len(ps) > 4),
                      key=len)
    sg.solver.add(
        Or(*[sea_id == sg.lattice.point_to_index(p) for p in area_points]))

    # The sea is not allowed to contain 2x2 areas of black cells.
    for sy in range(HEIGHT - 1):
        for sx in range(WIDTH - 1):
            pool_cells = [
                sg.grid[Point(y, x)] for y in range(sy, sy + 2)
                for x in range(sx, sx + 2)
            ]
            sg.solver.add(
                Not(And(*[Not(cell == sym.W) for cell in pool_cells])))
Пример #5
0
    def addTaskConstraints(self):
        htConstraints = []
        for task in self.tasks:
            # Aggregate the variables indicating this task got done at
            # a particular time.
            taskAtTimes = []
            for t in range(len(self.tasks)):
                intervalVars = []
                # Did we do the task in any of our intervals?
                for i, (start, end) in enumerate(task.intervals):
                    # Create a variable for getting done in the interval.
                    intervalVar = z3.Bool(
                        str(task) + "@" + str(t) + "_for_" + str(i))
                    # The task must be contained within the interval.
                    htConstraints.append(Or(Not(intervalVar),\
                                            self.timeVars[t] >= start))
                    htConstraints.append(Or(Not(intervalVar),\
                                            self.timeVars[t] + self.world.duration(task.ID) <= end))
                    intervalVars.append(intervalVar)
                # For a task to get done at a particular time, that
                # time must be within one of our intervals.
                htConstraints.append(Or(Not(self.taskVars[task][t]),\
                                        *intervalVars))
                taskAtTimes.append(self.taskVars[task][t])
            # For a task to get done at all, it has to get done at
            # some time.
            htConstraints.append(Or(Not(self.taskVars[task][-1]),
                                    *taskAtTimes))
        for constraint in htConstraints:
            self.solver.add(constraint)

        if self.debugPrint:
            print "Added hard task constraints: " + str(htConstraints)
Пример #6
0
def addDistinctRule(myBools, x, numColors, graph):
    n = len(graph.items())

    for i in range(0, n):  # each row
        for c in range(0, numColors):  # each color
            for c2 in range(c + 1, numColors):  # each color
                x.add(Or(Not(myBools[i][c]), Not(myBools[i][c2])))  # this cell cant be both these colors
    return x
Пример #7
0
 def _get_sink_phi_zero_formula(self):
     vars_in_range = self.get_bounds_formula()
     not_goal = Not(self.goal_expr)
     no_guard_active = And([
         Not(command.guard)
         for command in self.input_program.module.commands
     ])
     return Implies(And(vars_in_range, not_goal, no_guard_active),
                    0 == self.env.apply_to_state_valuation(self.phi))
Пример #8
0
 def _get_frame_zero_formula(self):
     not_goal = Not(self.goal_expr)
     no_guard_active = And([
         Not(command.guard)
         for command in self.input_program.module.commands
     ])
     return self.env.forall(
         Implies(And(not_goal, no_guard_active),
                 0 == self.env.apply_to_state_valuation(self.frame)))
Пример #9
0
def addAdjacentRule(myBools, x, numColors, graph):
    n = len(graph.items())

    for i in range(0, n):  # each row
        for j in range(0, len(graph[i])):
            for c in range(0, numColors):  # each color
                if i < graph[i][j]:
                    x.add(Or(Not(myBools[i][c]), Not(myBools[graph[i][j]][c])))  # this cell cant be both these colors
    return x
Пример #10
0
def turn():
    m = yield {'block': orientation != 0}
    while True:
        if gv.action // 10 == 1:
            direction = 2 * (gv.action % 10) - 1
            new_orientation = (m[orientation] + direction) % 4
            m = yield {'block': Not(orientation == new_orientation)}
        else:
            m = yield {'block': Not(orientation == m[orientation])}
Пример #11
0
    def __init__(
        self,
        list_of_tasks,
        nb_tasks_to_schedule,
        list_of_time_intervals,
        kind: Optional[str] = "exact",
        optional: Optional[bool] = False,
    ) -> None:
        super().__init__(optional)

        problem_function = {"min": PbGe, "max": PbLe, "exact": PbEq}

        # first check that all tasks from the list_of_optional_tasks are
        # actually optional
        if not isinstance(list_of_tasks, list):
            raise TypeError("list_of_task must be a list")

        if not isinstance(list_of_time_intervals, list):
            raise TypeError("list_of_time_intervals must be a list of list")

        # count the number of tasks that re scheduled in this time interval
        all_bools = []
        for task in list_of_tasks:
            # for this task, the logic expression is that any of its start or end must be
            # between two consecutive intervals
            bools_for_this_task = []
            for time_interval in list_of_time_intervals:
                task_in_time_interval = Bool(
                    "InTimeIntervalTask_%s_%i" % (task.name, uuid.uuid4().int)
                )
                lower_bound, upper_bound = time_interval
                cstrs = [
                    task.start >= lower_bound,
                    task.end <= upper_bound,
                    Not(
                        And(task.start < lower_bound, task.end > lower_bound)
                    ),  # overlap at start
                    Not(
                        And(task.start < upper_bound, task.end > upper_bound)
                    ),  # overlap at end
                    Not(And(task.start < lower_bound, task.end > upper_bound)),
                ]  # full overlap
                asst = Implies(task_in_time_interval, And(cstrs))
                self.set_z3_assertions(asst)
                bools_for_this_task.append(task_in_time_interval)
            # only one maximum bool to True from the previous possibilities
            asst_tsk = PbLe([(scheduled, True) for scheduled in bools_for_this_task], 1)
            self.set_z3_assertions(asst_tsk)
            all_bools.extend(bools_for_this_task)

        # we also have to exclude all the other cases, where start or end can be between two intervals
        # then set the constraint for the number of tasks to schedule
        asst_pb = problem_function[kind](
            [(scheduled, True) for scheduled in all_bools], nb_tasks_to_schedule
        )
        self.set_z3_assertions(asst_pb)
Пример #12
0
def findConfig(ships, observations, dimensions=(10, 10)):
    (M, N) = dimensions
    NS = len(ships)
    s = Solver()
    W = map(lambda (w, h): w, ships)
    H = map(lambda (w, h): h, ships)
    (xs, ys, ds) = ([], [], [])
    for k in range(NS):
        xs.append(Int('x_%d' % k))
        ys.append(Int('y_%d' % k))
        ds.append(Bool('d_%d' % k))
        #assert that x,y are in the dimensions' range
        s.add(xs[k] < M, xs[k] >= 0, ys[k] < N, ys[k] >= 0)

    occupied = dict()
    observe = dict()

    for i in range(M):
        occupied[i] = dict()
        observe[i] = dict()
        for j in range(N):
            occupied[i][j] = dict()
            observe[i][j] = False
            for k in range(NS):
                rect1 = rect(xs[k], ys[k], W[k], H[k], i, j)
                rect2 = rect(xs[k], ys[k], H[k], W[k], i, j)
                occupied[i][j][k] = Or(And(ds[k], rect1),
                                       And(Not(ds[k]), rect2))
                observe[i][j] = Or(occupied[i][j][k], observe[i][j])
    sumvar = 0
    for ((i, j), hit) in observations:
        if hit:
            s.add(observe[i][j])
        else:
            s.add(Not(observe[i][j]))

    for i in range(M):
        for j in range(N):
            sumvar = If(observe[i][j], 1, 0) + sumvar

    s.add(sumvar == getAreaCount(ships))
    if s.check() == sat:
        model = s.model()
        output = []
        for k in range(NS):
            output.append((model[xs[k]].as_long(), model[ys[k]].as_long(),
                           is_true(model[ds[k]])))
        return output
    else:
        #print "UNSAT!"
        return "UNSAT"
Пример #13
0
def move():
    m = yield {'block': Not(And(x == 1, y == 1))}
    while True:
        if gv.action // 10 == 2:
            if m[orientation] == 0:
                m = yield {'block': y != m[y] + 1}
            elif m[orientation] == 1:
                m = yield {'block': x != m[x] + 1}
            elif m[orientation] == 2:
                m = yield {'block': y != m[y] - 1}
            elif m[orientation] == 3:
                m = yield {'block': x != m[x] - 1}
        else:
            m = yield {'block': Not(And(y == m[y], x == m[x]))}
    def generate_reaching_constraints(self):
        visitor = ConditionVisitor()

        for (start,
             end), reaching_condition in self.reaching_conditions.items():
            or_exprs = []

            for condition in reaching_condition:
                and_exprs = []

                for edge in condition:
                    if edge.type == BranchType.UnconditionalBranch:
                        continue

                    if edge.type == BranchType.TrueBranch:
                        and_exprs.append(
                            visitor.simplify(edge.source[-1].condition))

                    elif edge.type == BranchType.FalseBranch:
                        and_exprs.append(
                            simplify(
                                Not(visitor.simplify(
                                    edge.source[-1].condition))))

                if and_exprs:
                    or_exprs.append(reduce(And, and_exprs))

            if or_exprs:
                self._reaching_constraints[(start, end)] = simplify(
                    reduce(Or, or_exprs))
    def find_if_else_for_node(self, header: MediumLevelILBasicBlock,
                              nodes: list):
        nodes_to_check = list(nodes)

        nodes_to_remove = []

        while nodes_to_check:
            ni = nodes_to_check.pop()

            if not isinstance(ni, MediumLevelILAstCondNode):
                continue

            for nj in nodes_to_check:
                if not isinstance(nj, MediumLevelILAstCondNode):
                    continue

                if ni.start == nj.start:
                    continue

                cni = ni.condition
                cnj = nj.condition

                if is_true(simplify(cni == Not(cnj))):
                    if cni.decl().name() == 'not':
                        self._make_if_else(nj, ni)
                        nodes_to_check.remove(nj)
                        nodes_to_remove.append(ni)
                    else:
                        self._make_if_else(ni, nj)
                        nodes_to_check.remove(nj)
                        nodes_to_remove.append(nj)
                    break

        return nodes_to_remove
Пример #16
0
    def is_byte_swap(self):
        try:
            self.model_variable()
        except ModelIsConstrained:
            return False

        # Figure out if this might be a byte swap
        byte_values_len = len(self.byte_values)
        #print self.byte_values
        if 1 < byte_values_len <= self.var.src.var.type.width:
            var = create_BitVec(self.var.src, self.var.src.var.type.width)
           
            ordering = list(reversed([
                self.byte_values[x]
                for x in sorted(self.byte_values.keys())
            ]))

            reverse_var = Concat(
                *reversed([
                    Extract(i-1, i-8, var)
                    for i in range(len(ordering) * 8, 0, -8)
                ])
            )

            if len(ordering) < 4:
                reverse_var = Concat(
                    Extract(
                        31,
                        len(ordering)*8, var
                    ),
                    reverse_var
                )

            reversed_ordering = reversed(ordering)
            reversed_ordering = Concat(*reversed_ordering)

            # The idea here is that if we add the negation of this, if it's
            # not satisfiable, then that means there is no value such that
            # the equivalence does not hold. If that is the case, then this
            # should be a byte-swapped value.

            self.solver.add(
                Not(
                    And(
                        var == ZeroExt(
                            var.size() - len(ordering)*8,
                            Concat(*ordering)
                        ),
                        reverse_var == ZeroExt(
                            reverse_var.size() - reversed_ordering.size(),
                            reversed_ordering
                        )
                    )
                )
            )

            if self.solver.check() == unsat:
                return True

        return False
Пример #17
0
    def _add_postconditions(self, gate, ctrl_ones, trgtqb, trgtvar):
        """create boolean variables for each qubit the gate is applied to
            and apply the relevant post conditions.
            a gate rotating out of the z-basis will not have any valid
            post-conditions, in which case the qubit state is unknown
        Args:
            gate (Gate): gate to inspect
            ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
            trgtqb (list((QuantumRegister, int))): list of target qubits
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        """
        new_vars = []
        for qbt in trgtqb:
            new_vars.append(self._gen_variable(qbt))

        try:
            self.solver.add(
                Implies(ctrl_ones,
                        gate._postconditions(*(trgtvar + new_vars))))
        except AttributeError:
            pass

        for i, tvar in enumerate(trgtvar):
            self.solver.add(Implies(Not(ctrl_ones), new_vars[i] == tvar))
Пример #18
0
def load_puzzle(
        url: str) -> Tuple[SymbolGrid, Optional[Callable[[Point, int], str]]]:
    params = url.split('/')
    height = int(params[-2])
    width = int(params[-3])

    givens: PuzzleGivens = parse_url(url)

    lattice = get_rectangle_lattice(height, width)
    sym = LoopSymbolSet(lattice)
    sym.append('EMPTY', chr(0x25AE))
    sg = SymbolGrid(lattice, sym)
    lc = LoopConstrainer(sg, single_loop=True)

    set_loop_order_zero = False
    # Construct puzzle from URL
    for p in sg.lattice.points:
        if givens[p]:
            sg.solver.add(sg.cell_is(p, sym.EMPTY))
        else:
            sg.solver.add(Not(sg.cell_is(p, sym.EMPTY)))
            # Restrict loop order to an empty cell
            if not set_loop_order_zero:
                sg.solver.add(lc.loop_order_grid[p] == 0)
                set_loop_order_zero = True

    return sg, None
Пример #19
0
    def entails(S, claim):
        """
        Checking the validity of S => claim
        """
        if __debug__:
            assert isinstance(S, Solver), S
            assert is_expr(claim), claim

        logger.debug('premise:\n{}\n'.format(S))
        logger.debug('claim:\n{}\n'.format(claim))
        # print 'entail'
        # print S
        # print claim
        S.push()
        S.add(Not(claim))

        check_rs = S.check()
        if check_rs == sat:
            r = False, S.model()
        elif check_rs == unsat:
            r = True, None  #unsat, no model
        elif check_rs == unknown:
            logger.warn('unknown for {}'.format(S))
            r = unknown, None  #unknown, error
        else:
            raise AssertionError('result: {} for\n{}'.format(check_rs, S))

        S.pop()
        return r
Пример #20
0
    def elimination_ordering(self, n):
        ord = lambda p, q: self.literal(self.ord[p][q]) if p < q else Not(
            self.literal(self.ord[q][p]))
        tord = lambda p, q: 'ord_{p}{q}'.format(
            p=p, q=q) if p < q else '(not ord_{q}{p})'.format(p=p, q=q)

        logging.info('Ordering')
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if i == j:
                    continue
                for l in range(1, n + 1):
                    if i == l or j == l:
                        continue
                    C = [
                        -self.ord[i][j] if i < j else self.ord[j][i],
                        -self.ord[j][l] if j < l else self.ord[l][j],
                        self.ord[i][l] if i < l else -self.ord[l][i]
                    ]
                    self.add_clause(C)

        logging.info('Edges')
        for e in self.hypergraph.edges():
            # PRIMAL GRAPH CONSTRUCTION
            for i, j in combinations(self.hypergraph.get_edge(e), 2):
                if i > j:
                    i, j = j, i
                if i < j:
                    # AS CLAUSE
                    self.add_clause([self.ord[i][j], self.arc[j][i]])
                    self.add_clause([-self.ord[i][j], self.arc[i][j]])

        logging.info('Edges Elimintation')
        for i in range(1, n + 1):
            for j in range(1, n + 1):
                if i == j:
                    continue
                for l in range(j + 1, n + 1):
                    if i == l:
                        continue
                    # AS CLAUSE
                    self.add_clause([
                        -self.arc[i][j], -self.arc[i][l], -self.ord[j][l],
                        self.arc[j][l]
                    ])
                    self.add_clause([
                        -self.arc[i][j], -self.arc[i][l], self.ord[j][l],
                        self.arc[l][j]
                    ])
                    # redunant
                    self.add_clause([
                        -self.arc[i][j], -self.arc[i][l], self.arc[j][l],
                        self.arc[l][j]
                    ])

        logging.info('Forbid Self Loops')
        # forbid self loops
        for i in range(1, n + 1):
            # self.stream.write("(assert (not arc_{i}_{i}))\n".format(i=i))
            self.add_clause([-self.arc[i][i]])
Пример #21
0
 def add_constraints(self, s, X, t, HOPS, GRID_SZ):
     nx, ny = self.x, self.y
     while t < HOPS+1:
         if((0 <= nx < GRID_SZ) and (0 <= ny  < GRID_SZ)):
             s.add(Not(X[t][nx][ny]))
         nx, ny = self.next_move()
         t += 1
Пример #22
0
def to_z3(node):
    """Translate a (quantifier-free) ATLAS property to a Z3 constraint
    """
    if isinstance(node, OfNode):
        raise ValueError
    if isinstance(node, BinOp):
        ops = {
            "=": lambda x, y: x == y,
            "!=": lambda x, y: x != y,
            ">": lambda x, y: x > y,
            ">=": lambda x, y: x >= y,
            "<": lambda x, y: x < y,
            "<=": lambda x, y: x <= y,
            "%": lambda x, y: x % y,
            "or": lambda x, y: Or(x, y),
            "and": lambda x, y: And(x, y)
        }
        return ops[node.op](to_z3(node.e1), to_z3(node.e2))
    elif isinstance(node, BuiltIn):
        funs = {
            "abs": lambda x: abs(x[0]),
            "max": lambda x: symMax(x),
            "min": lambda x: symMin(x),
            "not": lambda x: Not(x[0])
        }
        args = [to_z3(a) for a in node.args]
        return funs[node.fn](args)
    elif isinstance(node, Nary):
        ops = {"and": lambda x: And(*x), "or": lambda x: Or(*x)}
        return ops[node.fn]([to_z3(a) for a in node.args])
    else:
        return node
Пример #23
0
 def not_expr(self, expr):
     val = expr.value.convert(self)
     (hit, result) = self.checkCache("Not", [val])
     if hit:   
         return result
     else:
         return self.cache(Not(val), result)
Пример #24
0
def no_intersections(belt1: Belt, belt2: Belt):
    assert isinstance(belt1, Belt)
    assert isinstance(belt2, Belt)

    i,j = Consts("i j", IntSort())
    return ForAll([i,j], Implies(And(0 <= i, i < belt1.belt_len, 0 <=j, j < belt2.belt_len),
                                 Not(belt1[i] == belt2[j])))
Пример #25
0
def consecutive(cells, hint):
    return Or([
        And([
            cell if i <= j < i + hint else Not(cell)
            for j, cell in enumerate(cells)
        ]) for i in range(len(cells) - hint + 1)
    ])
Пример #26
0
def encodeTarget(target):
    if target in BOOL_VARS.keys():
        return BOOL_VARS[target]
    elif target[0] in ENUM_VARS.keys():
        attrName = target[0]
        var = ENUM_VARS[attrName]
        values = target[2]
        disjunctions = []
        for val in values:
            disjunctions.append(
                ENUM_VARS[attrName] == ENUM_VALUES[attrName][val])
        return Or(disjunctions)
    elif target[0] in NUMERIC_VARS.keys():
        var = NUMERIC_VARS[target[0]]
        _min = int(target[2][0])
        _max = int(target[2][1])
        return And(var >= _min, var <= _max)
    elif target[0] == 'not':
        return Not(encodeTarget(target[1]))
    elif target[0] == 'and':
        return And([encodeTarget(x) for x in target[1:]])
    elif target[0] == 'or':
        return Or([encodeTarget(x) for x in target[1:]])
    elif target[0] == '=>':
        return Implies(encodeTarget(target[1]), encodeTarget(target[2]))
    elif target == 'true':
        return True
    elif target == 'false':
        return False
    else:
        raise NameError(
            'could not convert propositional formula to the Z3 format')
Пример #27
0
def is_tautology(a, solver=None):
    """
    Check if claim is a tautology (always True)

    EXAMPLES:

    >>> from z3 import *
    >>> x,y = Bools('x y')
    >>> is_tautology(Implies(x,x))
    True

    >>> is_tautology(Implies(x,y))
    False

    >>> is_tautology(x==(x==TRUE))
    True

    >>> is_tautology(Not(x)==(x==FALSE))
    True

    >>> assert is_tautology(TRUE)
    >>> assert not is_tautology(FALSE)

    >>> pre_x = Bool('pre_x')
    >>> f = And(Not(pre_x == FALSE), x == FALSE)
    >>> g = And(Not(pre_x == TRUE), x == TRUE)
    >>> assert not is_tautology(Or(f,g),Solver())

    """
    return check_sat(Not(a), solver) == unsat
Пример #28
0
    def D(self, i, s):
        """
        Return a formula expressing state s_i is different
        than states [0, s_0, s_1, ..., s_(i-1)].

        If s is None then the returned formula expresses
        state i different than states [0 ... i-1]
        """
        if __debug__:
            assert i >= 2, 'i ({}) must start from 2!'.format(i)

        if len(self.state_vars) == 0:
            return None

        def S(i, s):
            """
            Return a set (list) consisting of the variables at state i.
            I.e. x_1i, x_2i, ...
            """
            return [self._at_state(v, i, s) for v in self.state_vars]

        cur_state = S(i, s)
        #states s_0 ... s_(j-1)
        pre_states = [S(i_, s) for i_ in range(i)]

        if s:
            #D(s,s+i) = s_i #  [0,s_0,s_1,..,s_(i-1)]
            pre_states = [S(0, None)] + pre_states

        f = [
            Not(self.state_eq(cur_state, pre_state))
            for pre_state in pre_states
        ]

        return myAnd(f)
Пример #29
0
def encode_eq(eq, Y):
    expr = eq.left == eq.right
    if eq.negated:
        expr = Not(expr)
    A = c.as_constraint(expr)
    B = c.And(*(fp.is_empty() for fp in Y.all_fps()))
    return as_split_constraints(A, B, eq)
Пример #30
0
    def command_specific_forall(self, z3_formula: z3.ExprRef) -> z3.ExprRef:
        """
        See `ForallMode` documentation.
        """
        if self.forall_mode == ForallMode.FORALL_QUANTIFIER:
            return ForAll(self._z3_local_var_list,
                          substitute(z3_formula, *self._z3_local_subst))
        elif self.forall_mode in [ForallMode.FORALL_MACRO, ForallMode.FORALL_GLOBALS]:

            result = []

            for command in self.input_module.commands:
                # For every command, we add a conjunct
                # "No goal" AND "guard of command" >=   (conjunction of substituted formulae for corresponding frame variables)
                result.append(Implies(And(Not(self.smt_program.goal_expr), command.guard),

                                      And([
                                          substitute(z3_formula, substitution)
                                          for substitution in self.command_to_substs[command]
                                      ])
                                      ))

            return And(result)
        else:
            raise ValueError("invalid forall_mode: %s" % self.forall_mode)