def Nat_mult_antichain_Min(m): """ Returns the Minimal set of elements of Nat so that their product is at least m: Min { (a, b) | a * b >= m } """ # (top, 1) or (1, top) P = Nat() P.belongs(m) top = P.get_top() if is_top(P, m): s = set([(top, 1), (1, top)]) # XXX: return s assert isinstance(m, int) if m == 0: # any (r1,r2) is such that r1*r2 >= 0 return set([(0, 0)]) s = set() for o1 in range(1, m + 1): assert o1 >= 1 # We want the minimum x such that o1 * x >= f # x >= f / o1 # x* = ceil(f / o1) x = int(np.ceil(m * 1.0 / o1)) assert x * o1 >= m assert (x - 1) * o1 < m assert x >= 1 s.add((o1, x)) return s
def __init__(self, c_value): """ Give a positive constant here """ N = Nat() N.belongs(c_value) amap = MinusValueNatMap(c_value) amap_dual = PlusValueNatMap(c_value) WrapAMap.__init__(self, amap, amap_dual)
def Nat_mult_antichain_Max(m): """ Returns the set of elements of Nat so that their product is at most m: Max { (a, b) | a * b <= m } """ # top -> [(top, top)] P = Nat() P.belongs(m) top = P.get_top() if is_top(P, m): s = set([(top, top)]) return s assert isinstance(m, int) if m < 1: return set([(0, 0)]) s = set() for o1 in range(1, m + 1): assert o1 >= 1 # We want the minimum x such that o1 * x >= f # x >= f / o1 # x* = ceil(f / o1) x = int(np.floor(m * 1.0 / o1)) assert x * o1 <= m # feasible assert (x + 1) * o1 > m, (x + 1, o1, m) # and minimum s.add((o1, x)) return s
def __init__(self, value): N = Nat() N.belongs(value) amap = InvMultValueNatMap(value) amap_dual = InvMultDualValueNatMap(value) WrapAMap.__init__(self, amap, amap_dual)
def dominates(self, s1, s2): n1 = (40 - s1.num_connection_options, s1.num_resources_need_connecting) n2 = (40 - s2.num_connection_options, s2.num_resources_need_connecting) N = PosetProduct((Nat(), Nat())) # create a joint one from mcdp_opt_tests.test_basic import add_extra l1b = add_extra(s1.ur, N, n1) l2b = add_extra(s2.ur, N, n2) # cdr = CompareDifferentResources() return less_resources2(l1b, l2b)
def eval_space(r, context): cases = { CDP.RcompUnit: eval_space_rcompunit, CDP.SpaceProduct: eval_space_spaceproduct, CDP.SpaceCoproduct: eval_space_spacecoproduct, CDP.PowerSet: eval_space_powerset, CDP.LoadPoset: eval_poset_load, CDP.FinitePoset: eval_space_finite_poset, CDP.CodeSpecNoArgs: eval_space_code_spec, CDP.CodeSpec: eval_space_code_spec, CDP.MakeUpperSets: eval_space_makeuppersets, CDP.MakeLowerSets: eval_space_makelowersets, CDP.SpaceInterval: eval_space_interval, CDP.ProductWithLabels: eval_space_productwithlabels, CDP.SingleElementPoset: eval_space_single_element_poset, CDP.Nat: lambda r, context: Nat(), # @UnusedVariable CDP.Int: lambda r, context: Int(), # @UnusedVariable CDP.Rcomp: lambda r, context: Rcomp(), # @UnusedVariable CDP.AddBottom: eval_space_addbottom, } for klass, hook in cases.items(): if isinstance(r, klass): return hook(r, context) if True: # pragma: no cover msg = 'eval_space(): Cannot interpret as a space.' r = recursive_print(r) raise_desc(DPInternalError, msg, r=r)
def __init__(self, c): check_isinstance(c, int) if c == 0: raise ValueError(c) cod = dom = Nat() Map.__init__(self, dom, cod) self.c = c
def eval_lfunction_invmult_ops(fs, context): if len(fs) == 1: return fs[0] elif len(fs) > 2: mcdp_dev_warning('Maybe this should be smarter?') rest = eval_lfunction_invmult_ops(fs[1:], context) return eval_lfunction_invmult_ops([fs[0], rest], context) else: assert len(fs) == 2 Fs = tuple(map(context.get_ftype, fs)) if isinstance(Fs[0], Nat) and isinstance(Fs[1], Nat): dp = InvMult2Nat(Nat(), Fs) else: if isinstance(Fs[0], RcompUnits) and \ isinstance(Fs[1], RcompUnits): R = mult_table(Fs[0], Fs[1]) dp = InvMult2(R, Fs) elif isinstance(Fs[0], Rcomp) and isinstance(Fs[1], Rcomp): R = Rcomp() dp = InvMult2(R, Fs) else: msg = 'Could not create invmult for types {}.'.format(Fs) raise_desc(DPNotImplementedError, msg, Fs0=Fs[0], Fs1=Fs[1]) return create_operation_lf(context, dp=dp, functions=fs, name_prefix='_invmult', op_prefix='_ops', res_prefix='_result')
def test_antichain_size(): M = MCDPConstants.InvPlus2Nat_max_antichain_size + 1 F = Nat() Rs = (F, F) dp = InvPlus2Nat(F, Rs) assert_raises(NotSolvableNeedsApprox, dp.solve, M)
def __init__(self, n): self.n = n N = Nat() dom = PosetProduct((N, ) * n) cod = N Map.__init__(self, dom=dom, cod=cod) self.top = cod.get_top() self.n = n
def check_nat3(): s = """ mcdp { provides x = 1 } """ ndp = parse_ndp(s) assert_equal(Nat(), ndp.get_ftype('x'))
def check_nat2(): s = """ mcdp { requires x = 1 } """ ndp = parse_ndp(s) assert_equal(Nat(), ndp.get_rtype('x'))
class PlusValueNatMap(Map): def __init__(self, value): self.value = value self.N = Nat() self.N.belongs(value) Map.__init__(self, dom=self.N, cod=self.N) def _call(self, x): return Nat_add(x, self.value) def diagram_label(self): return self.__str__() def repr_map(self, letter): return plusvaluemap_repr(letter, self.N, self.value) def __str__(self): return '+ %s' % self.N.format(self.value)
def __init__(self, value): N = Nat() N.belongs(value) amap = MultValueNatMap(value) # if value = Top: # f |-> f * Top # if is_top(N, value): amap_dual = MultValueNatDPHelper2Map() elif N.equal(0, value): # r |-> Top amap_dual = ConstantPosetMap(N, N, N.get_top()) else: # f * c <= r # f <= r / c # r |-> floor(r/c) amap_dual = MultValueNatDPhelper(value) WrapAMap.__init__(self, amap, amap_dual)
def __init__(self): amap = SquareNatMap() N = Nat() R = Rcomp() maps = (PromoteToFloat(N, R), SqrtMap(R), FloorMap(R), CoerceToInt(R, N)) amap_dual = MapComposition(maps) WrapAMap.__init__(self, amap, amap_dual)
def inv_constant(a): if a.unit == Nat(): raise DPNotImplementedError('division by natural number') warnings.warn('Please think more about this. Now 1/N -> 1.0/N') unit = Rcomp() else: unit = inv_unit(a.unit) if a.value == 0: raise DPSemanticError('Division by zero') # TODO: what about integers? value = 1.0 / a.value return ValueWithUnits(value=value, unit=unit)
def CeilSqrtNatDP(): # promote to float # take sqrt # make ceil # coerce R = Rcomp() N = Nat() dps = ( PromoteToFloatDP(N, R), SqrtRDP(R), CeilDP(R, R), CoerceToIntDP(R, N), ) return wrap_series(N, dps)
def check_join_meet_1(): # test meet # ⟨f₁, f₂⟩ ⟼ { min(f₁, f₂) } # r ⟼ { ⟨r, ⊤⟩, ⟨⊤, r⟩ } N = Nat() dp = MeetNDP(2, N) lf = dp.solve_r(5) #print('lf: {}'.format(lf)) assert_belongs(lf, (10, 5)) assert_belongs(lf, (5, 10)) assert_does_not_belong(lf, (10, 10)) Rtop = N.get_top() lf2 = dp.solve_r(Rtop) #print('lf2: {}'.format(lf2)) assert_belongs(lf2, (10, 10)) assert_belongs(lf2, (Rtop, Rtop)) lf3 = dp.solve_r(0) #print('lf3: {}'.format(lf3)) assert_belongs(lf3, (0, 0)) assert_does_not_belong(lf3, (0, 1)) assert_does_not_belong(lf3, (1, 0)) # Join ("max") of n variables. # ⟨f₁, …, fₙ⟩ ⟼ { max(f₁, …, fₙ⟩ } # r ⟼ ⟨r, …, r⟩ dp = JoinNDP(3, N) ur = dp.solve((10, 3, 3)) assert_belongs(ur, 10) assert_does_not_belong(ur, 9) lf = dp.solve_r(10) assert_does_not_belong(lf, (0, 11, 0)) assert_belongs(lf, (0, 10, 0)) assert_belongs(lf, (0, 9, 0))
def check_lang88(): # TODO: rename """ Check that the codomain of ceil is Nat. """ # now with Rcomp s = """ mcdp { provides f [Rcomp] requires r >= ceil(provided f) } """ dp = parse_ndp(s).get_dp() print dp.repr_long() R = dp.get_res_space() assert R == Nat(), R
def opt_basic_2(): l1 = parse_poset('J').U(1.0) l2 = parse_poset('m x J').U((1.0, 1.0)) n1 = (1, ) n2 = (1, ) N = PosetProduct((Nat(), )) # create a joint one l1b = add_extra(l1, N, n1) l2b = add_extra(l2, N, n2) print l1b print l2b assert less_resources2(l1b, l2b) assert not less_resources2(l2b, l1b)
def plus_constants2(a, b): """ raises ConstantsNotCompatibleForAddition """ A = a.unit B = b.unit if isinstance(A, RcompUnits) and isinstance(B, RcompUnits): return plus_constants2_rcompunits(a, b) if isinstance(A, RcompUnits) and isinstance(B, (Rcomp, Nat)): try: b2A = b.cast_value(A) except NotLeq: msg = 'Cannot sum %s and %s.' % (A, B) raise_desc(ConstantsNotCompatibleForAddition, msg) b2 = ValueWithUnits(b2A, A) return plus_constants2_rcompunits(a, b2) if isinstance(B, RcompUnits) and isinstance(A, (Rcomp, Nat)): try: a2B = a.cast_value(B) except NotLeq: msg = 'Cannot sum %s and %s.' % (A, B) raise_desc(ConstantsNotCompatibleForAddition, msg) a2 = ValueWithUnits(a2B, B) return plus_constants2_rcompunits(a2, b) if isinstance(B, Rcomp) and isinstance(A, Rcomp): res = rcomp_add(a.value, b.value) return ValueWithUnits(value=res, unit=Rcomp()) if isinstance(B, Rcomp) and isinstance(A, Nat): a2v = a.cast_value(B) res = rcomp_add(a2v, b.value) return ValueWithUnits(value=res, unit=Rcomp()) if isinstance(A, Rcomp) and isinstance(B, Nat): b2v = b.cast_value(A) res = rcomp_add(a.value, b2v) return ValueWithUnits(value=res, unit=Rcomp()) if isinstance(B, Nat) and isinstance(A, Nat): res = Nat_add(a.value, b.value) return ValueWithUnits(value=res, unit=Nat()) msg = 'Cannot add %r and %r' % (a, b) raise DPNotImplementedError(msg)
def generic_mult_table(seq): """ A generic mult table that knows how to take care of Nat and Rcomp as well. """ seq = list(seq) for s in seq: check_isinstance(s, (Nat, Rcomp, RcompUnits)) # If there are some RcompUnits, then Nat and Rcomp # will be promoted to Rcomp dimensionless any_reals = any(isinstance(_, RcompUnits) for _ in seq) any_rcomp = any(isinstance(_, Rcomp) for _ in seq) if any_reals: # compute the promoted ones def get_promoted(s): if isinstance(s, (Rcomp, Nat)): return R_dimensionless else: return s # this is all RcompUnits promoted = map(get_promoted, seq) # now we can use mult_table return promoted, mult_table_seq(promoted) elif any_rcomp: # promote Nat to Rcomp def get_promoted(s): if isinstance(s, Nat): return Rcomp() else: assert isinstance(s, Rcomp) return s # this is all RcompUnits promoted = map(get_promoted, seq) # now we can use mult_table return promoted, Rcomp() else: # it's all Nats return seq, Nat()
def MinusValueNatDP2(): N = Nat() v = N.get_top() return MinusValueNatDP(v)
def test_ex_invmult_limit(): f = MCDPConstants.InvPlus2Nat_max_antichain_size + 1 F = Nat() Rs = (F, F) dp = InvMult2Nat(F, Rs) assert_raises(NotSolvableNeedsApprox, dp.solve, f)
def check_loop_result3(): parse_wrap(Syntax.primitivedp_expr, 'code mcdp_dp_tests.inv_mult_plots.CounterMap___(n=3)')[0] parse_wrap(Syntax.ndpt_simple_dp_model, """ dp { requires x [Nat] provides c [Nat] implemented-by code mcdp_dp_tests.inv_mult_plots.CounterMap___(n=3) } """)[0] assert_semantic_error(""" mcdp { s = instance dp { requires x [Nat] provides c [Nat] # semantic error: does not exist implemented-by code mcdp_dp_tests.inv_mult_plots.CounterMap___(n=3) } }""" ) assert_semantic_error(""" mcdp { s = instance dp { requires x [Nat] provides c [Nat] # semantic error: not a DP implemented-by code mcdp_dp_tests.inv_mult_plots.CounterMap(n=3) } }""" ) ndp = parse_ndp(""" mcdp { adp1 = dp { requires x [Nat] provides c [Nat] implemented-by code mcdp_dp_tests.inv_mult_plots.CounterDP(n=3) } s = instance adp1 s.c >= s.x }""" ) # UNat = UpperSets(Nat()) dp = ndp.get_dp() print dp res = dp.solve(()) print res.__repr__() One = PosetProduct(()) U1 = UpperSets(One) U1.check_equal(res, One.U(())) ndp = parse_ndp(""" mcdp { adp1 = dp { requires x [Nat] provides c [Nat] implemented-by code mcdp_dp_tests.inv_mult_plots.CounterDP(n=3) } adp2 = dp { requires x [Nat] provides c [Nat] implemented-by code mcdp_dp_tests.inv_mult_plots.CounterDP(n=2) } s = instance choose(a: adp1, b: adp2) s.c >= s.x requires x for s }""" ) N = Nat() UNat = UpperSets(N) dp = ndp.get_dp() print dp res = dp.solve(()) print res UNat.check_equal(res, N.U(2))
def eval_constant_space_custom_value(op, context): from .eval_space_imp import eval_space assert isinstance(op, CDP.SpaceCustomValue) space = eval_space(op.space, context) custom_string = op.custom_string # print('custom string %r' % (custom_string).__repr__()) if isinstance(space, FiniteCollectionAsSpace): if custom_string == '*': if len(space.elements) == 1: value = list(space.elements)[0] return ValueWithUnits(unit=space, value=value) else: msg = 'You can use "*" only if the space has one element.' raise_desc(DPSemanticError, msg, elements=space.elements) try: space.belongs(custom_string) mcdp_dev_warning('this does not seem to work...') except NotBelongs: msg = 'The value "%s" is not an element of this poset.' % custom_string msg += '\n\nThese are the valid values: ' + ", ".join( map(str, space.elements)) + '.' raise_desc(DPSemanticError, msg) return ValueWithUnits(unit=space, value=op.custom_string) if isinstance(space, Nat): if isinstance(custom_string, CDP.ValueExpr): value = int(custom_string.value) # XXX: warn if value != custom_string.value: msg = 'Invalid value %s' % value raise_desc(DPSemanticError, msg, value=value, value0=custom_string.value) elif isinstance(custom_string, str): value = int(custom_string) else: msg = 'Cannot interpret value.' raise_desc(DPInternalError, msg, value=value) return ValueWithUnits(unit=Nat(), value=value) if isinstance(space, Int): mcdp_dev_warning('Top?') if isinstance(custom_string, CDP.ValueExpr): value = int(custom_string.value) # XXX: warn if value != custom_string.value: msg = 'Invalid value %s' % value raise_desc(DPSemanticError, msg, value=value, value0=custom_string.value) elif isinstance(custom_string, str): value = int(custom_string) else: msg = 'Cannot interpret value.' raise_desc(DPInternalError, msg, value=value) return ValueWithUnits(unit=Int(), value=value) if isinstance(space, Rcomp): mcdp_dev_warning('Top?') if isinstance(custom_string, CDP.ValueExpr): value = float(custom_string.value) elif isinstance(custom_string, str): value = float(custom_string) else: msg = 'Cannot interpret value.' raise_desc(DPInternalError, msg, value=value) return ValueWithUnits(unit=Rcomp(), value=value) msg = 'Custom parsing not implemented for space.' raise_desc(DPInternalError, msg, space=space, custom_string=custom_string)
def eval_constant_NatConstant(op, context): # @UnusedVariable return ValueWithUnits(unit=Nat(), value=op.value)
def generate_dp(self, R): # @UnusedVariable return CeilToNatDP(Rcomp(), Nat())
def get_arguments_type(self): spec = OpSpecExactly(Nat()) return (spec, )
def __init__(self, value): self.value = value self.N = Nat() self.N.belongs(value) Map.__init__(self, dom=self.N, cod=self.N)
def __init__(self): dom = cod = Nat() Map.__init__(self, dom=dom, cod=cod)
def __init__(self, n): self.n = n Map.__init__(self, Nat(), Nat())