def check_lang_connections2(): """ This is considered connected. """ ndp = assert_parsable_to_connected_ndp(""" mcdp { requires b [s] b >= 10 s }""") dp = ndp.get_dp() I = dp.get_imp_space() F = dp.get_fun_space() R = dp.get_res_space() M = dp.get_imp_space() print("F: %s" % F) print("R: %s" % R) print("I: %s" % I) print("M: %s" % M) UR = UpperSets(R) ur = dp.solve(()) print('ur: %s' % ur) UR.check_equal(ur, R.U(10.0))
def check_lang_connections1(): """ This is considered connected. """ ndp = assert_parsable_to_connected_ndp(""" mcdp { provides a [g] a <= 10 g }""") dp = ndp.get_dp() I = dp.get_imp_space() R = dp.get_res_space() M = dp.get_imp_space() print("I: %s" % I) print("M: %s" % M) print("R: %s" % R) UR = UpperSets(R) empty = R.Us(set()) ur1 = dp.solve(5.0) ur2 = dp.solve(14.0) print('ur1: %s' % ur1) print('ur2: %s' % ur2) UR.check_equal(empty, ur2)
def solve_f_iterate(dp0, f1, R, S, trace): """ Returns the next iteration si \in UR Min ( h(f1, r20) \cup !r20 ) """ UR = UpperSets(R) if do_extra_checks(): UR.belongs(S) R2 = R[1] converged = set() # subset of solutions for which they converged nextit = set() # find the set of all r2s for ra in S.minimals: hr = dp0.solve_trace((f1, ra[1]), trace) for rb in hr.minimals: valid = R.leq(ra, rb) if valid: nextit.add(rb) feasible = R2.leq(rb[1], ra[1]) if feasible: converged.add(rb) nextit = R.Us(poset_minima(nextit, R.leq)) converged = R.Us(poset_minima(converged, R.leq)) return nextit, converged
def solve_meat_solve_ftor(trace, ndp, dp, fg, intervals, max_steps, exp_advanced): R = dp.get_res_space() UR = UpperSets(R) # if intervals: # res = solver_iterative(dp, fg, trace) # else: if True: # if not _exp_advanced: res = dp.solve_trace(fg, trace) rnames = ndp.get_rnames() x = ", ".join(rnames) # todo: add better formatting if res.minimals: trace.log('Minimal resources needed: %s = %s' % (x, UR.format(res))) else: trace.log('This problem is unfeasible.') # else: # try: # trace = generic_solve(dp, f=fg, max_steps=max_steps) # trace.log('Iteration result: %s' % trace.result) # ss = trace.get_s_sequence() # S = trace.S # trace.log('Fixed-point iteration converged to: %s' # % S.format(ss[-1])) # R = trace.dp.get_res_space() # UR = UpperSets(R) # sr = trace.get_r_sequence() # rnames = ndp.get_rnames() # x = ", ".join(rnames) # trace.log('Minimal resources needed: %s = %s' # % (x, UR.format(sr[-1]))) # except: # raise return res, trace
def solve_stats(ndp): res = {} query = { "endurance": "1.5 hour", "velocity": "1 m/s", "extra_power": " 1 W", "extra_payload": "100 g", "num_missions": "100 []", } context = Context() f = convert_string_query(ndp=ndp, query=query, context=context) dp0 = ndp.get_dp() dpL, dpU = get_dp_bounds(dp0, nl=1, nu=1) F = dp0.get_fun_space() F.belongs(f) from mcdp import logger traceL = Tracer(logger=logger) resL = dpL.solve_trace(f, traceL) traceU = Tracer(logger=logger) resU = dpU.solve_trace(f, traceU) R = dp0.get_res_space() UR = UpperSets(R) print('resultsL: %s' % UR.format(resL)) print('resultsU: %s' % UR.format(resU)) res['traceL'] = traceL res['traceU'] = traceU res['resL'] = resL res['resU'] = resU res['nsteps'] = 100 return res
def solve_trace(self, func, trace): if func in self._solve_cache: # trace.log('using cache for %s' % str(func)) return trace.result(self._solve_cache[func]) trace.values(type='series') with trace.child('dp1') as t: u1 = self.dp1.solve_trace(func, t) if do_extra_checks(): R1 = self.dp1.get_res_space() tr1 = UpperSets(R1) tr1.belongs(u1) mcdp_dev_warning('rewrite this keeping structure') mins = set([]) for u in u1.minimals: with trace.child('dp2') as t: v = self.dp2.solve_trace(u, t) mins.update(v.minimals) R = self.get_res_space() minimals = poset_minima(mins, R.leq) us = UpperSet(minimals, R) self._solve_cache[func] = us return trace.result(us)
def check_evaluate(id_dp, dp): """ Test for PrimitiveDP:evaluate() """ print('Testing %s: %s' % (id_dp, dp)) F = dp.get_fun_space() R = dp.get_res_space() UR = UpperSets(R) LF = LowerSets(F) M = dp.get_imp_space() # We get a random m m0 = M.witness() try: lf, ur = dp.evaluate(m0) except NotSolvableNeedsApprox: return UR.belongs(ur) LF.belongs(lf) if not lf.maximals or not ur.minimals: msg = 'The point m0 gave empty lf, ur.' raise_desc(Exception, msg, lf=lf, ur=ur, m0=M.format(m0), M=M, dp=dp.repr_long()) # take one possible feasible pair _f = list(lf.maximals)[0] _r = list(ur.minimals)[0]
def solve_meat_solve(trace, ndp, dp, fg, intervals, max_steps, exp_advanced): R = dp.get_res_space() UR = UpperSets(R) # if intervals: # res = solver_iterative(dp, fg, trace) # else: if True: # if not _exp_advanced: res = dp.solve_trace(fg, trace) rnames = ndp.get_rnames() x = ", ".join(rnames) # todo: add better formatting trace.log("Minimal resources needed: %s = %s" % (x, UR.format(res))) # else: # try: # trace = generic_solve(dp, f=fg, max_steps=max_steps) # trace.log('Iteration result: %s' % trace.result) # ss = trace.get_s_sequence() # S = trace.S # trace.log('Fixed-point iteration converged to: %s' # % S.format(ss[-1])) # R = trace.dp.get_res_space() # UR = UpperSets(R) # sr = trace.get_r_sequence() # rnames = ndp.get_rnames() # x = ", ".join(rnames) # trace.log('Minimal resources needed: %s = %s' # % (x, UR.format(sr[-1]))) # except: # raise return res, trace
def compute_num_resources_need_connecting(self): n = 0 for r, lb in self.lower_bounds.items(): R = self.context.get_rtype(r) UR = UpperSets(R) if not UR.equal(lb, UR.get_bottom()): n += 1 return n
def process(self, request, string, nl, nu): l = self.get_library(request) parsed = l.parse_constant(string) space = parsed.unit value = parsed.value model_name = self.get_model_name(request) library = self.get_current_library_name(request) ndp, dp = self._get_ndp_dp(library, model_name) F = dp.get_fun_space() UR = UpperSets(dp.get_res_space()) tu = get_types_universe() tu.check_leq(parsed.unit, F) f = express_value_in_isomorphic_space(parsed.unit, parsed.value, F) print('query: %s ...' % F.format(f)) from mocdp import logger tracer = Tracer(logger=logger) dpl, dpu = get_dp_bounds(dp, nl, nu) intervals = False max_steps = 10000 result_l, _trace = solve_meat_solve(tracer, ndp, dpl, f, intervals, max_steps, False) result_u, trace = solve_meat_solve(tracer, ndp, dpu, f, intervals, max_steps, False) key = (string, nl, nu) res = dict(result_l=result_l, result_u=result_u, dpl=dpl, dpu=dpu) self.solutions[key] = res res = {} e = cgi.escape res['output_space'] = e(space.__repr__() + '\n' + str(type(space))) res['output_raw'] = e(value.__repr__() + '\n' + str(type(value))) res['output_formatted'] = e(space.format(value)) res['output_result'] = 'Lower: %s\nUpper: %s' % (UR.format(result_l), UR.format(result_u)) res['output_trace'] = str(trace) encoded = "nl=%s&nu=%s&string=%s" % (nl, nu, string) res['output_image'] = 'display.png?' + encoded res['ok'] = True return res
def solveU(self, ufunc): if do_extra_checks(): UF = UpperSets(self.get_fun_space()) UF.belongs(ufunc) res = set([]) for m in ufunc.minimals: u = self.solve(m) res.update(u.minimals) ressp = self.get_res_space() minima = poset_minima(res, ressp.leq) return ressp.Us(minima)
def eval_constant_uppersetfromcollection(op, context): x = eval_constant(op.value, context) v = x.value u = x.unit S = u.S minimals = poset_minima(v.elements, S.leq) value = UpperSet(minimals, S) unit = UpperSets(S) if do_extra_checks(): unit.belongs(value) vu = ValueWithUnits(value, unit) return vu
def check_approximation5(): ndp = parse_ndp(""" approx(mass,0%,0g,Top kg) mcdp { provides in [g] requires mass [g] mass >= in }""") dp = ndp.get_dp() R = dp.get_res_space() F = dp.get_fun_space() UR = UpperSets(R) res = dp.solve(F.get_top()) UR.check_equal(res, R.U(R.get_top()))
def check_anyof1(): ndp = parse_ndp(""" mcdp { requires x [g x g] x >= any-of({<0g,1g>, <1g, 0g>}) } """) dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) res = dp.solve(()) UR.check_equal(res, UpperSet([(0.0,1.0),(1.0,0.0)], R))
def check_anyof1(): ndp = parse_ndp(""" mcdp { requires x [g x g] x >= any-of({<0g,1g>, <1g, 0g>}) } """) dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) res = dp.solve(()) UR.check_equal(res, UpperSet([(0.0, 1.0), (1.0, 0.0)], R))
def check_anyof2(): ndp = parse_ndp(""" mcdp { provides x [g x g] x <= any-of({<0g,1g>, <1g, 0g>}) } """) dp = ndp.get_dp() R = dp.get_res_space() F = dp.get_fun_space() UR = UpperSets(R) res = dp.solve((0.5, 0.5)) l = LowerSet(P=F, maximals=[(0.0, 1.0), (1.0, 0.0)]) l.belongs((0.0, 0.5)) l.belongs((0.5, 0.0)) UR.check_equal(res, UpperSet([], R)) res = dp.solve((0.0, 0.5)) UR.check_equal(res, UpperSet([()], R)) res = dp.solve((0.5, 0.0)) UR.check_equal(res, UpperSet([()], R))
def check_uncertainty2(): ndp = parse_ndp(""" mcdp { provides f1 [N] f1 <= Uncertain(1 N, 2 N) } """) dp = ndp.get_dp() dpl, dpu = get_dp_bounds(dp, 1, 1) R = dp.get_res_space() UR = UpperSets(R) f0 = 0.0 # N sl = dpl.solve(f0) su = dpu.solve(f0) UR.check_leq(sl, su) print sl print su f0 = 1.5 # N sl = dpl.solve(f0) su = dpu.solve(f0) UR.check_leq(sl, su) print sl print su feasible = UpperSet(set([()]), R) infeasible = UpperSet(set([]), R) sl_expected = feasible su_expected = infeasible print sl_expected print su_expected UR.check_equal(sl, sl_expected) UR.check_equal(su, su_expected)
def check_uncertainty1(): ndp = parse_ndp(""" mcdp { requires r1 [USD] r1 >= Uncertain(1 USD, 2USD) } """) dp = ndp.get_dp() dpl, dpu = get_dp_bounds(dp, 1, 1) UR = UpperSets(dp.get_res_space()) f = () sl = dpl.solve(f) su = dpu.solve(f) UR.check_leq(sl, su)
def check_uncertainty3(): s = """ mcdp { provides capacity [J] requires mass [kg] required mass * Uncertain(2 J/kg, 3 J/kg) >= provided capacity } """ ndp = parse_ndp(s) dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) dpl, dpu = get_dp_bounds(dp, 100, 100) f0 = 1.0 # J sl = dpl.solve(f0) su = dpu.solve(f0) print sl print su UR.check_leq(sl, su) real_lb = UpperSet(set([0.333333]), R) real_ub = UpperSet(set([0.500000]), R) # now dpl will provide a lower bound from below UR.check_leq(sl, real_lb) # and dpu will provide the upper bound from above UR.check_leq(real_ub, su)
def get_common(ua, ub): Pa = ua.P Pb = ub.P if not isinstance(Pa, PosetProduct) or not isinstance(Pb, PosetProduct): raise NotImplementedError((Pa, Pb)) # first, it might be that they have different spaces # let's find out how to match them tu = get_types_universe() # for each i in Pa, we will match it to the first matches1 = [] for i, P in enumerate(Pa.subs): for j, Q in enumerate(Pb.subs): if ('B', j) in matches1: continue if tu.leq(P, Q): matches1.append(('B', j)) break else: matches1.append(('A', i)) matches2 = [] for j, Q in enumerate(Pb.subs): if ('B', j) in matches1: # used by somebody matches2.append(('B', j)) else: for i, P in enumerate(Pa.subs): if matches1[i] is not None: continue if tu.leq(Q, P): matches2.append(('A', i)) break else: matches2.append(('B', j)) print('matches1: %s' % matches1) print('matches2: %s' % matches2) used = sorted(set(matches1 + matches2)) def get_P(_): (which, index) = _ if which == 'A': return Pa.subs[index] if which == 'B': return Pb.subs[index] assert False Ps = PosetProduct(tuple(map(get_P, used))) print('used: %s' % used) print('Ps: %s' % Ps) # now we need to complete the first Ps_a = get(matches1, used, Ps, get_P, Pa, ua) Ps_b = get(matches2, used, Ps, get_P, Pb, ub) print('Ps_a: %s' % Ps_a) print('Ps_b: %s' % Ps_b) S = UpperSets(Ps) return S, Ps_a, Ps_b
def generic_report(r, dp, trace, annotation=None, axis0=(0, 0, 0, 0)): R = dp.get_res_space() UR = UpperSets(R) plotters = get_all_available_plotters() with r.subsection('S', caption='S') as rr: space = trace.S sequence = trace.get_s_sequence() generic_try_plotters(rr, plotters, space, sequence, axis0=axis0, annotation=annotation) with r.subsection('R', caption='R') as rr: space = UR sequence = trace.get_r_sequence() generic_try_plotters(rr, plotters, space, sequence, axis0=axis0, annotation=annotation)
def check_solve_f_chain(id_dp, dp): with primitive_dp_test(id_dp, dp): from mcdp_posets.utils import poset_check_chain F = dp.get_fun_space() f_chain = F.get_test_chain(n=8) poset_check_chain(F, f_chain) try: trchain = map(dp.solve, f_chain) except NotSolvableNeedsApprox: return try_with_approximations(id_dp, dp, check_solve_f_chain) R = dp.get_res_space() UR = UpperSets(R) try: poset_check_chain(UR, trchain) except ValueError as e: msg = 'The map solve() for %r is not monotone.' % id_dp raise_wrapped(Exception, e, msg, f_chain=f_chain, trchain=trchain, compact=True)
def solve_all(self, f1, trace): """ Returns an upperset in UR. You want to project it to R1 to use as the output. """ dp0 = self.dp1 R = dp0.get_res_space() R1 = R[0] UR = UpperSets(R) # we consider a set of iterates # we start from the bottom trace.log('Iterating in UR = %s' % UR.__str__()) s0 = R.Us(R.get_minimal_elements()) S = [ KleeneIteration(s=s0, s_converged=R.Us(set()), r=upperset_project(s0, 0), r_converged=R1.Us(set())) ] for i in range(1, 1000000): # XXX with trace.iteration(i) as t: si_prev = S[-1].s si_next, converged = solve_f_iterate(dp0, f1, R, si_prev, t) iteration = KleeneIteration(s=si_next, s_converged=converged, r=upperset_project(si_next, 0), r_converged=upperset_project( converged, 0)) S.append(iteration) t.log('R = %s' % UR.format(si_next)) if do_extra_checks(): try: UR.check_leq(si_prev, si_next) except NotLeq as e: msg = 'Loop iteration invariant not satisfied.' raise_wrapped(Exception, e, msg, si_prev=si_prev, si_next=si_next, dp=self.dp1) t.values(state=S[-1]) if UR.leq(si_next, si_prev): t.log('Breaking because converged (iteration %s) ' % i) #t.log(' solution is %s' % (UR.format(sip))) # todo: add reason why interrupted break trace.values(type='loop2', UR=UR, R=R, dp=self, iterations=S) res_all = S[-1].s res_r1 = upperset_project(res_all, 0) result = dict(res_all=res_all, res_r1=res_r1) return result
def check_lang_connections3(): """ This is considered connected. """ ndp = assert_parsable_to_connected_ndp(""" mcdp { provides f1 [g] provides f2 [s] requires r1 [s] f1 <= 1 g f2 <= 2 s r1 >= 2 s }""") dp = ndp.get_dp() I = dp.get_imp_space() F = dp.get_fun_space() R = dp.get_res_space() M = dp.get_imp_space() print("F: %s" % F) print("R: %s" % R) print("I: %s" % I) print("M: %s" % M) UR = UpperSets(R) ur = dp.solve((0.5, 0.4)) print('ur: %s' % ur) UR.check_equal(ur, R.U(2.0)) f_infeasible = (1.1, 1.0) ur = dp.solve(f_infeasible) print('ur: %s' % ur) empty = R.Us(set()) UR.check_equal(ur, empty) imps = dp.get_implementations_f_r(f=(0.4, 0.4), r=2.0) print('imps: %s' % imps)
def less_resources2(ua, ub): """ ua must be <= ub """ Pa = ua.P Pb = ub.P if not isinstance(Pa, PosetProduct) or not isinstance(Pb, PosetProduct): raise NotImplementedError((Pa, Pb)) tu = get_types_universe() matches = [] for i, P in enumerate(Pa.subs): for j, Q in enumerate(Pb.subs): if j in matches: continue if tu.leq(P, Q): matches.append(j) break else: # msg = 'Could not find match.' return False # now we have found an embedding # first we create a projection for Pb m1 = MuxMap(F=Pb, coords=matches) ub2 = upperset_project_map(ub, m1) Pb2 = ub2.P UPb2 = UpperSets(Pb2) # now we create the embedding A_to_B, _ = tu.get_embedding(Pa, Pb2) ua2 = upperset_project_map(ua, A_to_B) print('Pa: %s' % Pa) print('Pb2: %s' % Pb2) print('ua2: %s' % ua2) print('ub2: %s' % ub2) return UPb2.leq(ua2, ub2)
def check_solve_top_bottom(id_dp, dp): print('Testing %s: %s' % (id_dp, dp)) F = dp.get_fun_space() R = dp.get_res_space() UR = UpperSets(R) print('F: %s' % F) print('R: %s' % R) I = dp.get_imp_space() M = dp.get_imp_space() print('I: %s' % I) print('M: %s' % M) try: f_top = F.get_top() f_bot = F.get_bottom() except NotBounded: return print('⊥ = %s' % F.format(f_bot)) print('⊤ = %s' % F.format(f_top)) try: ur0 = dp.solve(f_bot) ur1 = dp.solve(f_top) except NotSolvableNeedsApprox: return print('f(%s) = %s' % (f_bot, ur0)) print('f(%s) = %s' % (f_top, ur1)) print('Checking that the order is respected') try: UR.check_leq(ur0, ur1) except NotLeq as e: msg = 'Not true that f(⊥) ≼ f(⊤).' raise_wrapped(Exception, e, msg, ur0=ur0,ur1=ur1) # get implementations for ur0 for r in ur0.minimals: ms = dp.get_implementations_f_r(f_bot, r) for m in ms: M.belongs(m)
def check_solve_top_bottom(id_dp, dp): print('Testing %s: %s' % (id_dp, dp)) F = dp.get_fun_space() R = dp.get_res_space() UR = UpperSets(R) print('F: %s' % F) print('R: %s' % R) I = dp.get_imp_space() M = dp.get_imp_space() print('I: %s' % I) print('M: %s' % M) try: f_top = F.get_top() f_bot = F.get_bottom() except NotBounded: return print('⊥ = %s' % F.format(f_bot)) print('⊤ = %s' % F.format(f_top)) try: ur0 = dp.solve(f_bot) ur1 = dp.solve(f_top) except NotSolvableNeedsApprox: return print('f(%s) = %s' % (f_bot, ur0)) print('f(%s) = %s' % (f_top, ur1)) print('Checking that the order is respected') try: UR.check_leq(ur0, ur1) except NotLeq as e: msg = 'Not true that f(⊥) ≼ f(⊤).' raise_wrapped(Exception, e, msg, ur0=ur0, ur1=ur1) # get implementations for ur0 for r in ur0.minimals: ms = dp.get_implementations_f_r(f_bot, r) for m in ms: M.belongs(m)
def check_uncertainty5(): s = """ mcdp { provides capacity [Wh] requires mass [kg] required mass * Uncertain(100 Wh/kg, 120 Wh/kg) >= provided capacity }""" ndp = parse_ndp(s) dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) dpl, dpu = get_dp_bounds(dp, 1000, 1000) f0 = 1.0 # J sl = dpl.solve(f0) su = dpu.solve(f0) UR.check_leq(sl, su)
def check_lang_singlespace3(): ndp1 = parse_ndp(""" mcdp { provides power [ S(electric_power) x W ] requires heat [ S(heat) x W ] efficiency = 0.9 [] r_heat = take(required heat, 1) f_power = take(provided power, 1) r_heat >= f_power / efficiency } """) ndp2 = parse_ndp(""" mcdp { provides power [ S(electric_power) x W ] requires heat [ S(heat) x W ] efficiency = 0.9 [] f_power = take(provided power, 1) heat >= <S(heat):*, f_power / efficiency> } """) dp1 = ndp1.get_dp() dp2 = ndp2.get_dp() R = dp1.get_res_space() print type(R), R UR = UpperSets(R) res1 = dp1.solve(('electric_power', 10.0)) res2 = dp2.solve(('electric_power', 10.0)) print UR.format(res1) print UR.format(res2)
def new_uncertainty_semantics01(): s = """ mcdp { a = instance mcdp { provides f = between 1W and 2W } provides f using a } """ ndp = parse_ndp(s) dp = ndp.get_dp() dpl, dpu = get_dp_bounds(dp, 1, 1) rl = dpl.solve(1.5) ru = dpu.solve(1.5) feasible = lambda l: len(l.minimals) > 0 UR = UpperSets(dp.get_res_space()) UR.check_leq(rl, ru) assert feasible(rl) assert not feasible(ru)
def check_join_not_existence(): """ A test for finite posets where the join might not exist. """ from mcdp_library.library import MCDPLibrary l = MCDPLibrary() add_def_poset(l, 'P', """ finite_poset { a <= b <= c A <= B <= C } """) # parse_wrap(Syntax.LOAD, '`') # parse_wrap(Syntax.posetname, 'P') # print Syntax.load_poset # parse_wrap(Syntax.load_poset, '`P') # parse_wrap(Syntax.space_operand, '`P') # parse_wrap(Syntax.fun_statement, "provides x [`P]") ndp = l.parse_ndp(""" mcdp { provides x [`P] provides y [`P] requires z [`P] z >= x z >= y } """, context=Context()) dp = ndp.get_dp() res1 = dp.solve(('a', 'b')) P = l.load_poset('P') UR = UpperSets(P) UR.check_equal(res1, UpperSet(['b'], P)) res2 = dp.solve(('a', 'A')) UR.check_equal(res2, UpperSet([], P))
def check_uncertainty5(): s = """ mcdp { provides capacity [Wh] requires mass [kg] required mass * Uncertain(100 Wh/kg, 120 Wh/kg) >= provided capacity }""" ndp = parse_ndp(s) dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) dpl, dpu = get_dp_bounds(dp, 1000, 1000) f0 = 1.0 # J sl = dpl.solve(f0) su = dpu.solve(f0) UR.check_leq(sl, su) print sl print su
def check_coproducts1(): parse_wrap_check('choose(a:a, b:b)', Syntax.ndpt_dp_rvalue) s = """ mcdp { provides energy [J] requires budget [$] a = mcdp { provides energy [J] requires budget [$] budget >= 5 $ energy <= 10 J } b = mcdp { provides energy [J] requires budget [$] budget >= 5 $ energy <= 50 J } c = instance choose(optionA:a, optionB:b) energy <= c.energy budget >= c.budget } """ ndp = parse_ndp(s) dp = ndp.get_dp() R = dp.get_res_space() I = dp.get_imp_space() print('R: %s' % R) print('I: %s' % I) UR = UpperSets(R) res = dp.solve(0.0) print UR.format(res) imps = dp.get_implementations_f_r(f=0.0, r=R.get_top()) print imps
def test_conversion(id_ndp, ndp): if '_inf' in id_ndp: # plusinvnat3b_inf print( 'Assuming that the suffix "_inf" in %r means that this will not converge' % (id_ndp)) print('Skipping this test') return try: ndp.check_fully_connected() except NotConnected: print('Skipping test_conversion because %r not connected.' % id_ndp) return dp = ndp.get_dp() F = dp.get_fun_space() R = dp.get_res_space() fs = F.get_minimal_elements() max_elements = 5 if len(fs) >= max_elements: fs = list(fs)[:max_elements] UR = UpperSets(R) for f in fs: try: res = dp.solve(f) print('%s -> %s' % (F.format(f), UR.format(res))) for r in res.minimals: imps = dp.get_implementations_f_r(f, r) print(imps) except NotSolvableNeedsApprox: break
def test_conversion(id_ndp, ndp): if '_inf' in id_ndp: # plusinvnat3b_inf print('Assuming that the suffix "_inf" in %r means that this will not converge' % (id_ndp)) print('Skipping this test') return try: ndp.check_fully_connected() except NotConnected: print('Skipping test_conversion because %r not connected.' % id_ndp) return dp = ndp.get_dp() F = dp.get_fun_space() R = dp.get_res_space() fs = F.get_minimal_elements() max_elements = 5 if len(fs) >= max_elements: fs = list(fs)[:max_elements] UR = UpperSets(R) for f in fs: try: res = dp.solve(f) print('%s -> %s' % (F.format(f), UR.format(res))) for r in res.minimals: imps = dp.get_implementations_f_r(f, r) print(imps) except NotSolvableNeedsApprox: break
def solve_stats(ndp): res = {} query = { "endurance": "1.5 hour", "velocity": "1 m/s", "extra_power": " 1 W", "extra_payload": "100 g", "num_missions": "100 []", } context = Context() f = convert_string_query(ndp=ndp, query=query, context=context) dp0 = ndp.get_dp() dpL, dpU = get_dp_bounds(dp0, nl=1, nu=1) F = dp0.get_fun_space() F.belongs(f) from mocdp import logger traceL = Tracer(logger=logger) resL = dpL.solve_trace(f, traceL) traceU = Tracer(logger=logger) resU = dpU.solve_trace(f, traceU) R = dp0.get_res_space() UR = UpperSets(R) print('resultsL: %s' % UR.format(resL)) print('resultsU: %s' % UR.format(resU)) res['traceL'] = traceL res['traceU'] = traceU res['resL'] = resL res['resU'] = resU res['nsteps'] = 100 return res
def solve_stats(ndp, n, algo): res = {} query = { "travel_distance": " 2 km", "carry_payload": "100 g", "num_missions": "100 []", } context = Context() f = convert_string_query(ndp=ndp, query=query, context=context) dp0 = ndp.get_dp() dpL, dpU = get_dp_bounds(dp0, nl=n, nu=n) F = dp0.get_fun_space() F.belongs(f) logger = None InvMult2.ALGO = algo traceL = Tracer(logger=logger) resL = dpL.solve_trace(f, traceL) traceU = Tracer(logger=logger) resU = dpU.solve_trace(f, traceU) R = dp0.get_res_space() UR = UpperSets(R) print('resultsL: %s' % UR.format(resL)) print('resultsU: %s' % UR.format(resU)) res['traceL'] = traceL res['traceU'] = traceU res['resL'] = resL res['resU'] = resU res['n'] = n res['query'] = query return res
def check_power8(): # TODO: move to ther files ndp = parse_ndp(""" mcdp { requires a [dimensionless] requires b [dimensionless] provides c [dimensionless] a + b >= c } """) dp = ndp.get_dp() print(dp.repr_long()) nl = 5 nu = 5 dpL, dpU = get_dp_bounds(dp, nl, nu) print(dpL.repr_long()) print(dpU.repr_long()) f = 10.0 UR = UpperSets(dp.get_res_space()) Rl = dpL.solve(f) Ru = dpU.solve(f) assert_equal(len(Rl.minimals), nl) assert_equal(len(Ru.minimals), nu) print('Rl: %s' % UR.format(Rl)) print('Ru: %s' % UR.format(Ru)) UR.check_leq(Rl, Ru) import numpy as np for x in np.linspace(0, f, 100): y = f - x p = (x, y) Rl.belongs(p)
def check_approximation4(): ndp = parse_ndp(""" approx(mass,0%,0g,Top kg) mcdp { provides in [g] requires mass [g] mass >= in }""") dp = ndp.get_dp() R = dp.get_res_space() UR = UpperSets(R) UR.check_equal(dp.solve(55.0), R.U(55.0)) UR.check_equal(dp.solve(55.01), R.U(55.01))
def solve_all(self, f1, trace): """ Returns an upperset in UR. You want to project it to R1 to use as the output. """ dp0 = self.dp1 R = dp0.get_res_space() R1 = R[0] UR = UpperSets(R) # we consider a set of iterates # we start from the bottom trace.log('Iterating in UR = %s' % UR.__str__()) s0 = R.Us(R.get_minimal_elements()) S = [KleeneIteration(s=s0, s_converged=R.Us(set()), r=upperset_project(s0, 0), r_converged=R1.Us(set()))] for i in range(1, 1000000): # XXX with trace.iteration(i) as t: si_prev = S[-1].s si_next, converged = solve_f_iterate(dp0, f1, R, si_prev, t) iteration = KleeneIteration(s=si_next, s_converged=converged, r=upperset_project(si_next, 0), r_converged=upperset_project(converged, 0)) S.append(iteration) t.log('R = %s' % UR.format(si_next)) if do_extra_checks(): try: UR.check_leq(si_prev, si_next) except NotLeq as e: msg = 'Loop iteration invariant not satisfied.' raise_wrapped(Exception, e, msg, si_prev=si_prev, si_next=si_next, dp=self.dp1) t.values(state=S[-1]) if UR.leq(si_next, si_prev): t.log('Breaking because converged (iteration %s) ' % i) #t.log(' solution is %s' % (UR.format(sip))) # todo: add reason why interrupted break trace.values(type='loop2', UR=UR, R=R, dp=self, iterations=S) res_all = S[-1].s res_r1 = upperset_project(res_all, 0) result = dict(res_all=res_all, res_r1=res_r1) return result
def eval_solve_f(op, context): check_isinstance(op, CDP.SolveModel) from .eval_ndp_imp import eval_ndp ndp = eval_ndp(op.model, context) dp = ndp.get_dp() f0 = eval_constant(op.f, context) F = dp.get_fun_space() R = dp.get_res_space() tu = get_types_universe() try: tu.check_leq(f0.unit, F) except NotLeq as e: msg = 'Input not correct.' raise_wrapped(DPSemanticError, e, msg, compact=True) f = f0.cast_value(F) res = dp.solve(f) UR = UpperSets(R) return ValueWithUnits(res, UR)
def new_uncertainty01use(): s = """mcdp { requires r1 = 10 kg ± 50 g } """ ndp = parse_ndp(s) dp = ndp.get_dp() dpl, dpu = get_dp_bounds(dp, 1, 1) rl = dpl.solve(()) ru = dpu.solve(()) R = dp.get_res_space() UR = UpperSets(R) UR.check_equal(rl, UpperSet([9.95], R)) UR.check_equal(ru, UpperSet([10.05], R))
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 friendly_solve(ndp, query, result_like='dict(str:str)', upper=None, lower=None): """ query = dict(power=(100,"W")) result_like = dict(power="W") s = solve """ #print('friendly_solve(upper=%s, lower=%s)' % (upper, lower)) # TODO: replace with convert_string_query(ndp, query, context): fnames = ndp.get_fnames() rnames = ndp.get_rnames() if not len(rnames) >= 1: raise NotImplementedError() value = [] for fname in fnames: if not fname in query: msg = 'Missing function' raise_desc(ValueError, msg, fname=fname, query=query, fnames=fnames) F = ndp.get_ftype(fname) q, qs = query[fname] s = '%s %s' % (q, qs) try: val = interpret_params_1string(s, F=F) except NotLeq as e: raise_wrapped(ValueError, e, 'wrong type', fname=fname) value.append(val) if len(fnames) == 1: value = value[0] else: value = tuple(value) if hasattr(ndp, '_cache_dp0'): dp0 = ndp._cache_dp0 else: dp0 = ndp.get_dp() ndp._cache_dp0 = dp0 if upper is not None: _, dp = get_dp_bounds(dp0, nl=1, nu=upper) elif lower is not None: dp, _ = get_dp_bounds(dp0, nl=lower, nu=1) else: dp = dp0 F = dp.get_fun_space() F.belongs(value) from mocdp import logger trace = Tracer(logger=logger) res = dp.solve_trace(value, trace) R = dp.get_res_space() UR = UpperSets(R) print('value: %s' % F.format(value)) print('results: %s' % UR.format(res)) ares = [] implementations = [] for r in res.minimals: rnames = ndp.get_rnames() fr = dict() for rname, sunit in result_like.items(): if not rname in rnames: msg = 'Could not find resource %r.' % rname raise_desc(ValueError, msg, rnames=rnames) i = rnames.index(rname) unit = interpret_string_as_space(sunit) Ri = ndp.get_rtype(rname) if len(rnames) > 1: ri = r[i] else: assert i == 0 ri = r v = express_value_in_isomorphic_space(S1=Ri, s1=ri, S2=unit) fr[rname] = v ares.append(fr) ms = dp.get_implementations_f_r(value, r) implementations.append(ms) return ares, implementations
def dual01_chain(id_dp, dp): try: with primitive_dp_test(id_dp, dp): print('Starting testing with %r' % id_dp) # get a chain of resources F = dp.get_fun_space() R = dp.get_res_space() # try to solve try: dp.solve(F.witness()) dp.solve_r(R.witness()) except NotSolvableNeedsApprox: print('NotSolvableNeedsApprox - doing lower bound ') n = 5 dpL, dpU = get_dp_bounds(dp, nl=n, nu=n) dual01_chain(id_dp+'_L%s'%n, dpL) dual01_chain(id_dp+'_U%s'%n, dpU) return LF = LowerSets(F) UR = UpperSets(R) rchain = R.get_test_chain(n=8) poset_check_chain(R, rchain) try: lfchain = list(map(dp.solve_r, rchain)) for lf in lfchain: LF.belongs(lf) except NotSolvableNeedsApprox as e: print('skipping because %s' % e) return try: poset_check_chain(LF, list(reversed(lfchain))) except ValueError as e: msg = 'The results of solve_r() are not a chain.' raise_wrapped(Exception, e, msg, chain=rchain, lfchain=lfchain) # now, for each functionality f, # we know that the corresponding resource should be feasible for lf, r in zip(lfchain, rchain): print('') print('r: %s' % R.format(r)) print('lf = h*(r) = %s' % LF.format(lf)) for f in lf.maximals: print(' f = %s' % F.format(f)) f_ur = dp.solve(f) print(' f_ur = h(f) = %s' % UR.format(f_ur)) try: f_ur.belongs(r) except NotBelongs as e: try: Rcomp.tolerate_numerical_errors = True f_ur.belongs(r) logger.info('In this case, there was a numerical error') logger.info('Rcomp.tolerate_numerical_errors = True solved the problem') except: msg = '' raise_wrapped(AssertionError, e, msg, lf=lf, r=r, f_ur=f_ur, r_repr=r.__repr__(), f_ur_minimals=f_ur.minimals.__repr__()) finally: Rcomp.tolerate_numerical_errors = False