コード例 #1
0
def categorize_bounds(formula: FNode, sender_symbol: FNode):
    """
    categorize symbolic bounds for a given variable
    :param formula: FNode formula in CNF form
    :param sender_symbol: FNode of the bounded variable
    :return: upper_bounds, lower_bounds, parent_atoms
    """
    clauses = set()
    formula = simplify(formula)
    if formula.is_or() or is_literal(formula):
        clauses.add(formula)
    else:  # formula of CNF form
        for clause in formula.args():
            assert is_literal(clause) or clause.is_or()
            clauses.add(clause)

    bounds = defaultdict(list)
    for clause in clauses:
        if clause.is_le() or clause.is_lt():  # single literal clause
            bound, bound_type = atom_to_bound(clause, sender_symbol)
            bounds[bound_type].append(bound)
            continue
        for atom in clause.get_atoms():  # atom: inequality a * x + b * y < c
            assert atom.is_le() or atom.is_lt()
            bound, bound_type = atom_to_bound(atom, sender_symbol)
            bounds[bound_type].append(bound)
    return list(set(bounds[UPPER])), list(set(bounds[LOWER])), \
        list(set(bounds[NEITHER]))
コード例 #2
0
 def ast_contains(self, node: FNode, what: Callable[[FNode], bool]) -> bool:
     if what(node):
         return True
     for child in node.args():
         if self.ast_contains(child, what):
             return True
     return False
コード例 #3
0
def extract_labels_and_weight(weight: FNode) -> Tuple[label_dict_type, FNode]:
    labels = dict()
    terms = []
    if weight.is_times():
        for arg in weight.args():  # type: FNode
            label = get_bool_label(arg)
            if label is not None:
                labels[label[0]] = tuple(label[1:])
            else:
                terms.append(arg)
        return labels, Times(*terms)
    else:
        return labels, weight
コード例 #4
0
def formula_to_interval_set(formula: FNode, sender_symbol: FNode,
                            test_point: float):
    clauses = set()
    if formula.is_or() or is_literal(formula):
        clauses.add(formula)
    else:  # formula of CNF form
        for clause in formula.args():
            assert is_literal(clause) or clause.is_or()
            clauses.add(clause)

    interval_list = []
    for clause in clauses:
        intervals = clause_to_intervals(clause, sender_symbol, test_point)
        if intervals:
            interval_list.append(intervals)
    return interval_list
コード例 #5
0
def get_bool_label(formula: FNode) -> Optional[Tuple[str, FNode, FNode]]:
    if formula.is_ite():
        c, t, e = formula.args()  # type: FNode
        if c.is_symbol() and c.symbol_type() == BOOL:
            return c.symbol_name(), t, e
    return None
コード例 #6
0
def vlog_match_widths(left: FNode,
                      right: FNode,
                      extend=False) -> Tuple[FNode, FNode]:
    '''
    Match the bit-widths for assignment using the Verilog standard semantics.

    if extend:
       zero extend to largest width
    else:
       left_width == right_width: no change
       left_width > right_width: right side is zero extended or sign extended depending on signedness
       left_width < right_width: right side is truncated (MSBs removed)
    '''
    assert type(left) == FNode and get_type(
        left).is_bv_type(), "Expecting a bit-vector"
    assert type(right) == FNode and get_type(
        right).is_bv_type(), "Expecting a bit-vector"

    left_width, right_width = left.bv_width(), right.bv_width()

    if left_width == right_width:
        pass
    elif left_width > right_width:
        # TODO: Check signed-ness of right-side

        fun = None
        padding = 0

        # handle ops with overflow:
        if right.is_bv_add():
            fun = BVAdd
            padding = 1
        elif right.is_bv_mul():
            fun = BVMul
            padding = 1
        elif right.is_bv_lshl():
            fun = BVLShl
            padding = left_width - right_width

        assert padding >= 0, "Expecting a non-negative padding"

        # TODO: Handle signed values here as well
        # re-build the node
        if padding > 0:
            args = [BVZExt(a, padding) for a in right.args()]
            right = fun(*args)

        # re-evauluate left_width and right_width, in case they're updated
        left_width, right_width = left.bv_width(), right.bv_width()

        assert left_width >= right_width, "Unexpected bitwidth mismatch"

        if left_width > right_width:
            right = BVZExt(right, left_width - right_width)

    else:
        if extend:
            left = BVZExt(left, right_width - left_width)
        else:
            right = BVExtract(right, 0, left_width - 1)

    return simplify(left), simplify(right)