コード例 #1
0
def _bitvector_to_bdd(aut):
    """Return `Automaton` with BDD formulas.

    @type aut: `Automaton`
    """
    players = dict(aut.players)
    table = aut.vars
    bits = bv.bit_table(table, table)
    # index both, to allow for unquantified parameters
    ubits = set(b for b, d in bits.items() if d['owner'] == 'env')
    ebits = set(b for b, d in bits.items() if d['owner'] == 'sys')
    b = _pick_var_order(bits, ubits)
    b = _add_primed_bits(b)
    bdd = aut.bdd
    # define levels only if no existing vars
    if bdd.vars:
        for var in b:
            bdd.add_var(var)
    else:
        for level, var in enumerate(b):
            bdd.add_var(var, level)
    # bundle as:
    a = Automaton()
    a.vars = copy.deepcopy(table)
    a.players = players
    a.bdd = bdd
    # slugsin -> BDD
    # add long attributes first,
    # to improve  effectiveness of reordering.
    # better if each attr is one formula.
    from_sections = _make_section_map(aut)
    to_sections = _make_section_map(a)
    lengths = {k: _section_len(v) for k, v in from_sections.items()}
    sort = sorted(from_sections, key=lengths.__getitem__, reverse=True)
    for section in sort:
        p = from_sections[section]
        q = to_sections[section]
        _to_bdd(p, q, bdd)
    # vars
    player_vars = {k for k, d in table.items() if d['owner'] in players}
    if not player_vars:
        print('Warning: no player variables.')
        return a
    bits = bv.bit_table(player_vars, table)
    prime, partition = _partition_vars(bits, ubits, ebits)
    a.uvars = partition['uvars']
    a.upvars = partition['upvars']
    a.evars = partition['evars']
    a.epvars = partition['epvars']
    a.ubvars = set(a.uvars).union(a.upvars)
    a.ebvars = set(a.evars).union(a.epvars)
    a.uevars = set(a.uvars).union(a.evars)
    a.uepvars = set(a.upvars).union(a.epvars)
    # priming
    a.prime = prime
    a.unprime = {v: k for k, v in prime.items()}
    return a
コード例 #2
0
def _refine_vars(fol_vars, table):
    """Return bits that represent the `fol_vars`."""
    if fol_vars:
        bits = bv.bit_table(fol_vars, table)
    else:
        # `bit_table` raises `AssertionError` for
        # empty `fol_vars`
        bits = set()
    return bits
コード例 #3
0
ファイル: fol.py プロジェクト: johnyf/omega
def _refine_vars(fol_vars, table):
    """Return bits that represent the `fol_vars`."""
    if fol_vars:
        bits = bv.bit_table(fol_vars, table)
    else:
        # `bit_table` raises `AssertionError` for
        # empty `fol_vars`
        bits = set()
    return bits
コード例 #4
0
 def pick_iter(self, u, care_vars=None):
     """Generator of first-order satisfying assignments."""
     if care_vars is None:
         care_bits = None
     elif care_vars:
         care_bits = bv.bit_table(care_vars, self.vars)
     else:
         care_bits = set()
     for bit_assignment in self.bdd.pick_iter(u, care_vars=care_bits):
         for d in enum._bitfields_to_int_iter(bit_assignment, self.vars):
             yield d
コード例 #5
0
ファイル: fol.py プロジェクト: johnyf/omega
    def add_vars(self, dvars):
        r"""Refine variables in `dvars`.

        The variables in `dvars` should have type hints.
        A Boolean-valued variable remains so.
        An integer-valued variable is assumed to take the
        value resulting as a function of some (fresh)
        Boolean-valued variables.

        Sometimes these variables are called "bits".
        The function is based on two's complement,
        see `omega.logic.bitvector` for details.

        In other words, type hints are used to pick
        a refinement of integers by finitely many bits.
        A sufficient number of bits is selected,
        and operations assume this as type invariant,
        *not* the exact type hint given.

        For example, an integer `x` with type hint `x \in 0..2`
        will be refined using 2 Boolean-valued variables
        `x_0` and `x_1`. All operations and quantification
        will assume that `x \in 0..3`.
        Mind the extra value (3) allowed,
        compared to the hint (0..2).

        Attention:

        - Fine-grained type predicates
          (`n..m` with `n` and `m` other than powers of 2)
          are not managed here.

        - Priming is not reasoned about here.
          Priming is cared for by other modules.

        The method `add_vars` adds to `vars[var]` the keys:

          - `"bitnames"`: `list`
          - `"signed"`: `True` if signed integer
          - `"width"`: `len(bitnames)`
        """
        assert dvars, dvars
        self._avoid_redeclaration(dvars)
        vrs = {k: v for k, v in dvars.items()
               if k not in self.vars}
        if not vrs:
            return
        t = bv.bitblast_table(vrs)
        self.vars.update(t)
        bits = bv.bit_table(t, t)
        for bit in bits:
            self.bdd.add_var(bit)
コード例 #6
0
ファイル: fol.py プロジェクト: johnyf/omega
 def pick_iter(self, u, care_vars=None):
     """Generator of first-order satisfying assignments."""
     if care_vars is None:
         care_bits = None
     elif care_vars:
         care_bits = bv.bit_table(care_vars, self.vars)
     else:
         care_bits = set()
     for bit_assignment in self.bdd.pick_iter(
             u, care_vars=care_bits):
         for d in enum._bitfields_to_int_iter(
                 bit_assignment, self.vars):
             yield d
コード例 #7
0
    def add_vars(self, dvars):
        r"""Refine variables in `dvars`.

        The variables in `dvars` should have type hints.
        A Boolean-valued variable remains so.
        An integer-valued variable is assumed to take the
        value resulting as a function of some (fresh)
        Boolean-valued variables.

        Sometimes these variables are called "bits".
        The function is based on two's complement,
        see `omega.logic.bitvector` for details.

        In other words, type hints are used to pick
        a refinement of integers by finitely many bits.
        A sufficient number of bits is selected,
        and operations assume this as type invariant,
        *not* the exact type hint given.

        For example, an integer `x` with type hint `x \in 0..2`
        will be refined using 2 Boolean-valued variables
        `x_0` and `x_1`. All operations and quantification
        will assume that `x \in 0..3`.
        Mind the extra value (3) allowed,
        compared to the hint (0..2).

        Attention:

        - Fine-grained type predicates
          (`n..m` with `n` and `m` other than powers of 2)
          are not managed here.

        - Priming is not reasoned about here.
          Priming is cared for by other modules.

        The method `add_vars` adds to `vars[var]` the keys:

          - `"bitnames"`: `list`
          - `"signed"`: `True` if signed integer
          - `"width"`: `len(bitnames)`
        """
        assert dvars, dvars
        self._avoid_redeclaration(dvars)
        vrs = {k: v for k, v in dvars.items() if k not in self.vars}
        if not vrs:
            return
        t = bv.bitblast_table(vrs)
        self.vars.update(t)
        bits = bv.bit_table(t, t)
        for bit in bits:
            self.bdd.add_var(bit)
コード例 #8
0
ファイル: fol.py プロジェクト: ciniks117/omega
 def pick_iter(self, u, care_vars=None):
     """Generator of first-order satisfying assignments."""
     if care_vars is None:
         care_bits = None
     elif care_vars:
         care_bits = bv.bit_table(care_vars, self.vars)
     else:
         care_bits = set()
     vrs = self.support(u)
     if care_vars:
         vrs.update(care_vars)
     for bit_assignment in self.bdd.pick_iter(u, care_vars=care_bits):
         for d in enum._bitfields_to_int_iter(bit_assignment, self.vars):
             assert set(d).issubset(vrs), (d, vrs, bit_assignment)
             yield d
コード例 #9
0
 def exist(self, qvars, u):
     """Existentially quantify `qvars` in `u`."""
     if len(qvars) == 0:
         return u
     qbits = bv.bit_table(qvars, self.vars)
     return self.bdd.exist(qbits, u)
コード例 #10
0
ファイル: fol.py プロジェクト: johnyf/omega
 def exist(self, qvars, u):
     """Existentially quantify `qvars` in `u`."""
     if len(qvars) == 0:
         return u
     qbits = bv.bit_table(qvars, self.vars)
     return self.bdd.exist(qbits, u)
コード例 #11
0
ファイル: symbolic.py プロジェクト: johnyf/omega
def _bitvector_to_bdd(aut):
    """Return `Automaton` with BDD formulas.

    @type aut: `Automaton`
    """
    players = dict(aut.players)
    table = aut.vars
    bits = bv.bit_table(table, table)
    # index both, to allow for unquantified parameters
    ubits = set(b for b, d in bits.items()
                if d['owner'] == 'env')
    ebits = set(b for b, d in bits.items()
                if d['owner'] == 'sys')
    b = _pick_var_order(bits, ubits)
    b = _add_primed_bits(b)
    bdd = aut.bdd
    # define levels only if no existing vars
    if bdd.vars:
        for var in b:
            bdd.add_var(var)
    else:
        for level, var in enumerate(b):
            bdd.add_var(var, level)
    # bundle as:
    a = Automaton()
    a.vars = copy.deepcopy(table)
    a.players = players
    a.bdd = bdd
    # slugsin -> BDD
    # add long attributes first,
    # to improve  effectiveness of reordering.
    # better if each attr is one formula.
    from_sections = _make_section_map(aut)
    to_sections = _make_section_map(a)
    lengths = {
        k: _section_len(v)
        for k, v in from_sections.items()}
    sort = sorted(
        from_sections,
        key=lengths.__getitem__,
        reverse=True)
    for section in sort:
        p = from_sections[section]
        q = to_sections[section]
        _to_bdd(p, q, bdd)
    # vars
    player_vars = {k for k, d in table.items()
                   if d['owner'] in players}
    if not player_vars:
        print('Warning: no player variables.')
        return a
    bits = bv.bit_table(player_vars, table)
    prime, partition = _partition_vars(bits, ubits, ebits)
    a.uvars = partition['uvars']
    a.upvars = partition['upvars']
    a.evars = partition['evars']
    a.epvars = partition['epvars']
    a.ubvars = set(a.uvars).union(a.upvars)
    a.ebvars = set(a.evars).union(a.epvars)
    a.uevars = set(a.uvars).union(a.evars)
    a.uepvars = set(a.upvars).union(a.epvars)
    # priming
    a.prime = prime
    a.unprime = {v: k for k, v in prime.items()}
    return a