def test_below_and_suff(): fol = _fol.Context() fol.declare(p=(0, 3), q=(0, 3)) # define a fragment of a lattice prm = Parameters() prm.p_vars = {'p'} prm.q_vars = {'q'} prm.p_to_q = {'p': 'q'} prm.q_to_p = {'q': 'p'} # 3 # | | # 1 2 # | # 0 prm.p_leq_q = fol.add_expr(r''' \/ (p = 0 /\ q = 1) \/ (p = 0 /\ q = 3) \/ (p = 1 /\ q = 3) \/ (p = 2 /\ q = 3) \/ (p \in 0..3 /\ p = q) ''') ymax = fol.add_expr('p = 3') cover = fol.add_expr('p = 3') x = fol.add_expr('p = 0') y = fol.add_expr(r'p \in 1..3') yk_set = cov_enum._below_and_suff(ymax, cover, x, y, prm, fol) yk_set_ = fol.add_expr(r'p = 1 \/ p = 3') assert yk_set == yk_set_, list(fol.pick_iter(yk_set))
def test_pick_iter_as_bdd(): fol = _fol.Context() fol.declare(x=(0, 5)) u = fol.add_expr(r' x \in 0..1 ') t = list(cov_enum._pick_iter_as_bdd(u, fol)) t_ = [fol.add_expr('x = 0'), fol.add_expr('x = 1')] assert t == t_, (t, t_)
def test_lm_tail(): fol = _fol.Context() fol.declare(x=(0, 5)) # N = 3 lm = [ fol.add_expr('x = 0'), # index 1 fol.add_expr('x = 1'), # index 2 fol.add_expr('x = 2') ] # index 3 k = 0 with assert_raises(AssertionError): cov_enum._lm_tail(k, lm) k = 1 r = cov_enum._lm_tail(k, lm) r_ = fol.add_expr(r'x \in 0..2') assert r == r_, list(fol.pick_iter(r)) k = 2 r = cov_enum._lm_tail(k, lm) r_ = fol.add_expr(r'x \in 1..2') assert r == r_, list(fol.pick_iter(r)) k = 3 r = cov_enum._lm_tail(k, lm) r_ = fol.add_expr('x = 2') assert r == r_, list(fol.pick_iter(r)) k = 4 with assert_raises(AssertionError): cov_enum._lm_tail(k, lm)
def test_orthotopes_iter(): fol = _fol.Context() fol.declare(p=(2, 9)) # careful with the type hint u = fol.add_expr('(0 <= p) /\ (p <= 10)') c = list(lat._orthotopes_iter(u, fol)) assert len(c) == 11, c
def setup_orthotope_vars(): fol = _fol.Context() fol.declare( x=(0, 5), y=(2, 14), px=(0, 5), qx=(0, 5), py=(2, 14), qy=(2, 14), ax=(0, 5), bx=(0, 5), ay=(2, 14), by=(2, 14), ) xvars = ['x', 'y'] px = dict(x=dict(a='px', b='qx'), y=dict(a='py', b='qy')) qx = dict(x=dict(a='ax', b='bx'), y=dict(a='ay', b='by')) prm = lat.Parameters() prm.x_vars = xvars prm._px = px prm._qx = qx prm.p_to_q = dict(px='ax', py='ay', qx='bx', qy='by') prm.p_vars = set(prm.p_to_q) prm.q_vars = set(prm.p_to_q.values()) varmap = lat.parameter_varmap(px, qx) prm.p_leq_q = lat.subseteq(varmap, fol) prm.p_eq_q = lat.eq(varmap, fol) return fol, prm
def test_y_unfloor(): fol = _fol.Context() fol.declare(p=(0, 3), q=(0, 3)) # define a fragment of a lattice prm = Parameters() prm.p_vars = {'p'} prm.p_to_q = {'p': 'q'} prm.q_to_p = {'q': 'p'} # 2 3 # | | # 0 1 prm.p_leq_q = fol.add_expr(r''' \/ (p = 0 /\ q = 2) \/ (p = 1 /\ q = 3) ''') y = fol.add_expr(r'p \in 2..3') # yfloor = 0 yfloor = fol.add_expr('p = 0') y_over = cov_enum._y_unfloor(yfloor, y, prm, fol) y_over_ = fol.add_expr('p = 2') assert y_over == y_over_, list(fol.pick_iter(y_over)) # yfloor = 1 yfloor = fol.add_expr('p = 1') y_over = cov_enum._y_unfloor(yfloor, y, prm, fol) y_over_ = fol.add_expr('p = 3') assert y_over == y_over_, list(fol.pick_iter(y_over))
def test_enumerate_mincovers_below(): """Test the function `enumerate_mincovers_below`.""" fol = _fol.Context() fol.declare(x=(0, 5)) u = fol.add_expr(r' x \in 0..1 ') care = fol.true prm = lat.setup_aux_vars(u, care, fol) lat.setup_lattice(prm, fol) x = fol.add_expr(r' a_x = 0 /\ b_x = 2 ') y = fol.add_expr(r''' \/ (a_x = 0 /\ b_x = 1) \/ (a_x = 0 /\ b_x = 3) \/ (a_x = 0 /\ b_x = 4) ''') cover_from_max = fol.add_expr(r''' a_x = 0 /\ b_x = 4 ''') mincovers_below = cov_enum._enumerate_mincovers_below( cover_from_max, x, y, prm, fol) mincovers_below_ = cov_enum._enumerate_mincovers_below_set_based( cover_from_max, x, y, prm, fol) assert mincovers_below == mincovers_below_, mincovers_below r = fol.add_expr(r''' \/ (a_x = 0 /\ b_x = 3) \/ (a_x = 0 /\ b_x = 4) ''') mincovers_below_ = set(fol.assign_from(d) for d in fol.pick_iter(r)) assert mincovers_below == mincovers_below_, (mincovers_below, mincovers_below_)
def setup_aut(xmax=15, ymax=15): fol = _fol.Context() fol.bdd.configure(reordering=True) # CAUTION: remember that type hints (safety) # needs to be added as care set fol.declare(x=(0, xmax), y=(0, ymax)) x_vars = ['x', 'y'] p_table = lat._parameter_table( x_vars, fol.vars, a_name='a', b_name='b') q_table = lat._parameter_table( x_vars, fol.vars, a_name='u', b_name='v') fol.declare(**p_table) fol.declare(**q_table) px = lat._map_vars_to_parameters( x_vars, a_name='a', b_name='b') qx = lat._map_vars_to_parameters( x_vars, a_name='u', b_name='v') varmap = lat.parameter_varmap(px, qx) p_to_q = lat._renaming_between_parameters(px, qx) prm = lat.Parameters() prm.x_vars = x_vars prm.p_vars = set(p_table) prm.q_vars = set(q_table) prm.p_to_q = p_to_q prm._px = px prm._qx = qx prm._varmap = varmap return fol, prm
def test_branching(): aut = _fol.Context() aut.bdd.configure(reordering=True) # aut.bdd = _bdd.BDD(memory_estimate=2 * _bdd.GB) # aut.bdd.configure( # max_memory=2 * _bdd.GB, # max_cache_hard=2**25) aut.declare(x=(0, 10), y=(0, 25), z=(0, 25)) s = ( '( ' '(z = 1 /\ y <= 0) \/ ' '(x = 0 /\ z = 1) \/ ' '(y >= 1 /\ x <= 0) \/ ' '(y >= 1 /\ z <= 0) \/ ' '(x >= 1 /\ z <= 0) \/ ' '(x >= 1 /\ y <= 0) ' ') ') f = aut.add_expr(s) s = ( '0 <= x /\ x <= 2 /\ ' '0 <= y /\ y <= 1 /\ ' '0 <= z /\ z <= 1 ' ) care_set = aut.add_expr(s) # care_set = aut.true cover = cov.minimize(f, care_set, aut) s = cov.dumps_cover(cover, f, care_set, aut) log.info(s)
def test_max_transpose(): fol = _fol.Context() # `p'` serves as `u` dvars = {'p': (0, 4), 'q': (0, 4), "p_cp": (0, 4)} fol.declare(**dvars) s = '(p = 2) \/ (p = 4)' p_is_prime = fol.add_expr(s) s = '(p = 1) \/ (p = 3)' p_is_signature = fol.add_expr(s) p_to_q = {'p': 'q'} # we use intervals `0..p` as literals px = dict(p=dict(a='0', b='p')) qx = dict(p=dict(a='0', b='q')) u_leq_p = fol.add_expr("p_cp <= p") p_leq_u = fol.add_expr("p <= p_cp") p_leq_q = fol.add_expr("p <= q") p_eq_q = fol.add_expr("p = q") # /\ (0 = 0) prm = lat.Parameters() prm._px = px prm._qx = qx prm.u_leq_p = u_leq_p prm.p_leq_u = p_leq_u prm.p_leq_q = p_leq_q prm.p_eq_q = p_eq_q prm.p_to_q = p_to_q prm.p_vars = {'p'} prm.q_vars = {'q'} prm.u_vars = {'p_cp'} prm.p_to_u = {'p': 'p_cp'} bab = cov._BranchAndBound(prm, fol) max_tau_x = cov._max_transpose( p_is_signature, p_is_prime, bab, fol) s = 'p = 3' max_tau_x_ = fol.add_expr(s) assert max_tau_x == max_tau_x_
def test_transpose(): fol = _fol.Context() dvars = {'p': (0, 4), 'q': (0, 4), "p_cp": (0, 4)} fol.declare(**dvars) s = '(p = 1) \/ (p = 2) \/ (p = 4)' p_is_prime = fol.add_expr(s) s = '(p = 1) \/ (p = 3)' p_is_signature = fol.add_expr(s) p_to_q = {'p': 'q'} p_leq_q = fol.add_expr("p <= q") u_leq_p = fol.add_expr("p_cp <= p") p_leq_u = fol.add_expr("p <= p_cp") prm = lat.Parameters() prm.u_leq_p = u_leq_p prm.p_leq_u = p_leq_u prm.p_leq_q = p_leq_q prm.p_to_q = p_to_q prm.p_vars = {'p'} prm.q_vars = {'q'} prm.u_vars = {'p_cp'} prm.p_to_u = {'p': 'p_cp'} bab = cov._BranchAndBound(prm, fol) tau = cov._floor( p_is_signature, p_is_prime, bab, fol) s = 'p = 1 \/ p = 3' tau_ = fol.add_expr(s) assert tau == tau_
def test_needs_unfloors(): """Floors shrinks both primes to one smaller implicant. The returned cover is a minimal cover, so the assertion `_covers` in the function `cover.minimize` passes. However, the returned cover is not made of primes from the set `y` computed by calling `prime_implicants`. Finding the primes takes into account the care set. The resulting covering problem is such that shrinking happens. Therefore, unfloors is necessary in this problem. """ fol = _fol.Context() fol.declare(x=(0, 1), y=(0, 1)) f = fol.add_expr('x = 0 /\ y = 0') care = fol.add_expr(''' \/ (x = 0 /\ y = 0) \/ (x = 1 /\ y = 1) ''') cover = cov.minimize(f, care, fol) implicants = list(fol.pick_iter(cover)) assert len(implicants) == 1, implicants (d,) = implicants d_1 = dict(a_x=0, b_x=1, a_y=0, b_y=0) d_2 = dict(a_x=0, b_x=0, a_y=0, b_y=1) assert d == d_1 or d == d_2, d
def test_cyclic_core_recursion(): """Two cyclic cores, in orthogonal subspaces.""" fol = _fol.Context() fol.declare( x=(0, 1), y=(0, 1), z=(0, 1), u=(0, 1), v=(0, 1), w=(0, 1)) s = r''' ( \/ (z = 1 /\ y = 0) \/ (x = 0 /\ z = 1) \/ (y = 1 /\ x = 0) \/ (y = 1 /\ z = 0) \/ (x = 1 /\ z = 0) \/ (x = 1 /\ y = 0) ) \/ ( \/ (w = 1 /\ v = 0) \/ (u = 0 /\ w = 1) \/ (v = 1 /\ u = 0) \/ (v = 1 /\ w = 0) \/ (u = 1 /\ w = 0) \/ (u = 1 /\ v = 0) ) ''' f = fol.add_expr(s) care_set = fol.true cover = cov.minimize(f, care_set, fol) n = fol.count(cover) assert n == 6, n
def test_cyclic_core_recursion_2(): """Two cyclic cores, in orthogonal subspaces.""" fol = _fol.Context() fol.declare(x=(0, 1), y=(0, 1), z=(0, 1), u=(0, 1), v=(0, 1), w=(0, 1)) s = r''' ( \/ (z = 1 /\ y = 0) \/ (x = 0 /\ z = 1) \/ (y = 1 /\ x = 0) \/ (y = 1 /\ z = 0) \/ (x = 1 /\ z = 0) \/ (x = 1 /\ y = 0) ) \/ ( \/ (w = 1 /\ v = 0) \/ (u = 0 /\ w = 1) \/ (v = 1 /\ u = 0) \/ (v = 1 /\ w = 0) \/ (u = 1 /\ w = 0) \/ (u = 1 /\ v = 0) ) ''' f = fol.add_expr(s) care_set = fol.true mincovers = cov_enum.minimize(f, care_set, fol) n = len(mincovers) assert n == 4, (n, mincovers) for cover in mincovers: n = fol.count(cover) primes = list(fol.pick_iter(cover)) assert n == 6, (n, primes)
def test_cyclic_core_recursion(): """One cyclic core.""" fol = _fol.Context() fol.declare(x=(0, 1), y=(0, 1), z=(0, 1)) s = r''' ( \/ (z = 1 /\ y = 0) \/ (x = 0 /\ z = 1) \/ (y = 1 /\ x = 0) \/ (y = 1 /\ z = 0) \/ (x = 1 /\ z = 0) \/ (x = 1 /\ y = 0) ) ''' f = fol.add_expr(s) care = fol.true # setup variables and lattice prm = lat.setup_aux_vars(f, care, fol) lat.setup_lattice(prm, fol) # covering problem fcare = f | ~care x = lat.embed_as_implicants(f, prm, fol) y = lat.prime_implicants(fcare, prm, fol) # enumerative check enumerated_covers(x, y, prm, fol) # symbolically minimize mincovers = cov_enum.minimize(f, care, fol) n = len(mincovers) assert n == 2, (n, mincovers) for cover in mincovers: n = fol.count(cover) primes = list(fol.pick_iter(cover)) assert n == 3, (n, primes)
def replace_with_bdd(): fol = _fol.Context() fol.declare(x='bool', y='bool') u = fol.add_expr('x => y') subs = {'x': fol.bdd.true} u = fol.replace_with_bdd(u, subs) u_ = fol.add_expr('y') assert u == u_, (u, u_)
def test_declare(): # Boolean-valued variable fol = _fol.Context() bdd = fol.bdd fol.declare(x='bool') assert 'x' in fol.vars, fol.vars dx = fol.vars['x'] assert 'type' in dx, dx type_x = dx['type'] assert type_x == 'bool', type_x assert 'x' in bdd.vars assert 'x_0' not in bdd.vars # integer-valued variable fol = _fol.Context() bdd = fol.bdd fol.declare(y=(0, 2)) assert 'y' in fol.vars, fol.vars dy = fol.vars['y'] assert 'type' in dy, dy type_dy = dy['type'] assert type_dy == 'int', type_dy # regression regarding bit naming convention assert 'y_0' in bdd.vars assert 'y_1' in bdd.vars assert 'y_2' not in bdd.vars assert 'y' not in bdd.vars # primed vars fol = _fol.Context() bdd = fol.bdd d = {"y'": (0, 1)} fol.declare(**d) assert "y'" in fol.vars, fol.vars assert "y_0'" in bdd.vars, bdd.vars assert "y'_0" not in bdd.vars, bdd.vars # adding same vars twice fol = _fol.Context() fol.declare(x='bool') fol.declare(x='bool') # mismatch with existing var with nt.assert_raises(ValueError): fol.declare(x=(1, 5)) # mixed new and existing fol.declare(x='bool', y=(0, 5)) with nt.assert_raises(ValueError): fol.declare(x='bool', y=(3, 15))
def test_cyclic_core_with_care_set(): aut = _fol.Context() aut.declare(x=(0, 17)) # cover = {True} s = '(x < 15)' f = aut.add_expr(s) s = '(x < 15)' care_set = aut.add_expr(s) cov.cyclic_core(f, care_set, aut)
def test_add_expr(): fol = _fol.Context() bdd = fol.bdd u = fol.add_expr('False') assert u == bdd.false, bdd.to_expr(u) fol.declare(x=(0, 100), y=(5, 23)) u = fol.add_expr('x < y + 5') v = fol.add_expr('x - 5 < y') assert u == v, (u, v)
def test_cyclic_core_with_care_set(): fol = _fol.Context() fol.declare(x=(0, 17)) s = '(x < 15)' f = fol.add_expr(s) care_set = fol.true mincovers = cov_enum.minimize(f, care_set, fol) mincovers_ = {fol.add_expr('a_x = 0 /\ b_x = 14')} assert mincovers == mincovers_, list(fol.pick_iter(mincovers))
def test_cyclic_core_fixpoint_recursive(): fol = _fol.Context() p_vars = dict(p=(0, 3)) q_vars = dict(q=(0, 3)) u_vars = dict(p_cp=(0, 3)) fol.declare(**p_vars) fol.declare(**q_vars) fol.declare(**u_vars) p_eq_q = fol.to_bdd(r'p \in 0..3 /\ p = q') # 3 # | | # 1 2 # | | # 0 leq = r''' # (* layer 1 *) \/ (p = 0 /\ q = 1) \/ (p = 0 /\ q = 2) # (* layer 2 *) \/ (p = 1 /\ q = 3) \/ (p = 2 /\ q = 3) # transitivity \/ (p = 0 /\ q = 3) # equality \/ (p = q /\ p \in 0..3) ''' p_leq_q = fol.to_bdd(leq) u_leq_p = fol.to_bdd(leq.replace('p', 'p_cp').replace('q', 'p')) p_leq_u = fol.to_bdd(leq.replace('q', 'p_cp')) # bundle prm = Parameters() prm.p_vars = set(p_vars) prm.q_vars = set(q_vars) prm.u_vars = set(u_vars) # prm.p_to_q = dict(p='q') prm.q_to_p = dict(q='p') prm.p_to_u = dict(p='p_cp') # prm.u_leq_p = u_leq_p prm.p_leq_u = p_leq_u prm.p_leq_q = p_leq_q prm.p_eq_q = p_eq_q # x = fol.add_expr('p = 0') y = fol.add_expr(r'p \in 1..2') # path_cost = 0.0 bab = cov._BranchAndBound(prm, fol) bab.upper_bound = cov._upper_bound(x, y, prm.p_leq_q, prm.p_to_q, fol) path_cost = 0.0 mincovers = cov_enum._cyclic_core_fixpoint_recursive( x, y, path_cost, bab, fol) assert len(mincovers) == 2, mincovers mincovers_ = {fol.add_expr('p = 1'), fol.add_expr('p = 2')} assert mincovers == mincovers_, list(fol.pick_iter(mincovers))
def test_add_to_visited(): c = _fol.Context() c.declare(x='bool', y=(0, 10)) bdd = c.bdd values = dict(x=True, y=5) visited = bdd.false new_visited = enum._add_to_visited(values, visited, c) s = 'x /\ (y = 5)' u = c.add_expr(s) assert new_visited == u
def test_apply(): fol = _fol.Context() bdd = fol.bdd fol.declare(x='bool') u = fol.add_expr('x') v = fol.add_expr(' ~ x') w = fol.apply('and', u, v) assert w == bdd.false w = fol.apply('or', u, v) assert w == bdd.true
def test_f_implies_care(): fol = _fol.Context() fol.declare(x=(-4, 5)) f = fol.add_expr('0 < x /\ x < 4') care = fol.add_expr('-2 <= x /\ x <= 4') r = cov._f_implies_care(f, care, fol) assert r is True, r care = fol.add_expr('-2 <= x /\ x <= 2') r = cov._f_implies_care(f, care, fol) assert r is False, r
def test_enumerate_mincovers_unfloor(): fol = _fol.Context() fol.declare(p=(0, 4), q=(0, 4)) # define a fragment of a lattice prm = Parameters() prm.p_vars = {'p'} prm.p_to_q = {'p': 'q'} prm.q_to_p = {'q': 'p'} # 2 3 # | | # 0 1 prm.p_leq_q = fol.add_expr(r''' \/ (p = 0 /\ q = 2) \/ (p = 1 /\ q = 3) ''') # {0..1} |-> {2..3} y = fol.add_expr(r'p \in 2..3') cover_from_floors = fol.add_expr(r'p \in 0..1') mincovers = cov_enum._enumerate_mincovers_unfloor(cover_from_floors, y, prm, fol) assert len(mincovers) == 1, mincovers assert y in mincovers, (mincovers, y) # non-injective case # 2 2 3 # | | | # 0 1 1 prm.p_leq_q = fol.add_expr(r''' \/ (p = 0 /\ q = 2) \/ (p = 1 /\ q = 2) \/ (p = 1 /\ q = 3) ''') y = fol.add_expr(r'p \in 2..3') cover_from_floors = fol.add_expr(r'p \in 0..1') with assert_raises(AssertionError): # The assertion error is raised because the cover's cardinality # is reduced by the mapping, so the cardinality of the # partial cover is smaller than expected (`assert k == k_` within # the function `_enumerate_mincovers_unfloor`). mincovers = cov_enum._enumerate_mincovers_unfloor( cover_from_floors, y, prm, fol) # {0..1} |-> {2..3, {2, 4}} prm.p_leq_q = fol.add_expr(r''' \/ (p = 0 /\ q = 2) \/ (p = 1 /\ q = 3) \/ (p = 1 /\ q = 4) ''') y = fol.add_expr(r'p \in 2..4') cover_from_floors = fol.add_expr(r'p \in 0..1') mincovers = cov_enum._enumerate_mincovers_unfloor(cover_from_floors, y, prm, fol) assert len(mincovers) == 2, mincovers cover = fol.add_expr(r'p \in 2..3') assert cover in mincovers, (mincovers, cover) cover = fol.add_expr(r'p = 2 \/ p = 4') assert cover in mincovers, (mincovers, cover)
def test_pick(): fol = _fol.Context() fol.declare(x='bool', y=(0, 2)) u = fol.add_expr('x') p = fol.pick(u, care_vars=['x']) for i in range(10): q = fol.pick(u, care_vars=['x']) assert p == q, (p, q) u = fol.add_expr('False') p = fol.pick(u, care_vars=['x']) assert p is None, p
def test_partial_order(): fol = _fol.Context() fol.declare(x=(0, 4), w=(0, 4), w_cp=(0, 4), t=(0, 4), t_cp=(0, 4)) px = dict(x=dict(a='w', b='t')) u_leq_p, p_leq_u = lat.partial_order(px, fol) s = '(w <= w_cp) /\ (t_cp <= t)' u_leq_p_ = fol.add_expr(s) assert u_leq_p == u_leq_p_ s = '(w_cp <= w) /\ (t <= t_cp)' p_leq_u_ = fol.add_expr(s) assert p_leq_u == p_leq_u_
def test_dumps_cover(): fol = _fol.Context() fol.declare(x=(0, 4), y=(-5, 9)) # care = TRUE s = '2 <= x /\ x <= 4' u = fol.add_expr(s) care = fol.true cover = cov.minimize(u, care, fol) s = cov.dumps_cover(cover, u, care, fol) s_ = ( '(* `f` depends on: x *)\n' '(* `care` depends on: *)\n' '(* The minimal cover is: *)\n' '(x \in 2 .. 4)') assert s == s_, (s, s_) # care doesn't imply type hints s = cov.dumps_cover( cover, u, care, fol, show_dom=True) s_ = ( '(* `f` depends on: x *)\n' '(* `care` depends on: *)\n' '(* The minimal cover is: *)\n' '(x \in 2 .. 4)') assert s == s_, (s, s_) # with limits s = cov.dumps_cover( cover, u, care, fol, show_dom=True, show_limits=True) s_ = ( '(* `f` depends on: x *)\n' '(* `care` depends on: *)\n' '(* The minimal cover is: *)\n' ' /\ x \in 0 .. 7\n' ' /\ (x \in 2 .. 4)') assert s == s_, (s, s_) # care = type hints care = tyh._conjoin_type_hints(['x', 'y'], fol) cover = cov.minimize(u, care, fol) s = cov.dumps_cover( cover, u, care, fol, show_dom=True) s_ = ( '(* `f` depends on: x *)\n' '(* `care` depends on: x, y *)\n' '(* The minimal cover is: *)\n' ' /\ x \in 0 .. 4\n' ' /\ y \in -5 .. 9\n' ' /\ (x \in 2 .. 4)\n' ' /\ care expression') assert s == s_, (s, s_)
def test_care_implies_type_hints(): fol = _fol.Context() fol.declare(x=(-4, 5), y=(-7, 15)) f = fol.add_expr('0 < x /\ x < 4') care = fol.add_expr('-2 <= y /\ y <= 4') r = cov._care_implies_type_hints(f, care, fol) assert r is False, r care = fol.add_expr('1 <= x /\ x <= 6 /\ ' '-2 <= y /\ y <= 4') r = cov._care_implies_type_hints(f, care, fol) assert r is False, r care = fol.add_expr('1 <= x /\ x <= 5 /\ ' '-2 <= y /\ y <= 4') r = cov._care_implies_type_hints(f, care, fol) assert r is True, r
def test_assert_uniform_cardinality(): fol = _fol.Context() fol.declare(p=(0, 3)) bdds = { fol.add_expr(r'p \in 0..1'), fol.add_expr(r'p \in 2..3'), fol.add_expr(r'p = 0 \/ p = 3') } cov_enum._assert_uniform_cardinality(bdds, fol) # not of uniform cardinality bdds = {fol.add_expr('p = 0'), fol.add_expr(r'p \in 2..3')} with assert_raises(AssertionError): cov_enum._assert_uniform_cardinality(bdds, fol)