def test_one_player_rps(): from magnum.examples.rock_paper_scissors import rps as g from magnum.examples.rock_paper_scissors import context from stl.boolean_eval import pointwise_sat res = encode_and_run(g) phi = g.spec_as_stl(discretize=False) dt = g.model.dt assert pointwise_sat(phi, dt=dt)(res.solution) not_rock = stl.parse('~(X(xRock))').inline_context(context) not_paper = stl.parse('~(X(xPaper))').inline_context(context) not_scissors = stl.parse('~(X(xScissors))').inline_context(context) g = bind(g).specs.learned.set(not_rock) res = encode_and_run(g) phi = g.spec_as_stl(discretize=False) dt = g.model.dt assert pointwise_sat(phi, dt=dt)(res.solution) g = bind(g).specs.learned.set(not_rock & not_paper) res = encode_and_run(g) phi = g.spec_as_stl(discretize=False) dt = g.model.dt assert pointwise_sat(phi, dt=dt)(res.solution) g = bind(g).specs.learned.set(not_rock & not_paper & not_scissors) res = encode_and_run(g) phi = g.spec_as_stl(discretize=False) assert res.solution is None
def test_encode_refuted_rec_sync(): from magnum.examples.feasible_example2 import feasible_example as g from magnum.solvers import smt from magnum.solvers import milp from stl.boolean_eval import pointwise_sat dt = g.model.dt refuted = {'u': traces.TimeSeries([(0, 0.5)])} phi = encode_refuted_rec(refuted, 0.1, g.times, dt=dt) g = bind(g).specs.learned.set(phi) res = smt.encode_and_run(g) assert pointwise_sat(phi, dt=dt)(res.solution) res = milp.encode_and_run(g) assert pointwise_sat(phi, dt=dt)(res.solution) refuted = {'u': traces.TimeSeries([(0, 1), (0.4, 1), (1, 0)])} phi = encode_refuted_rec(refuted, 0.1, g.times, dt=dt) g = bind(g).specs.learned.set(phi) res = smt.encode_and_run(g) assert pointwise_sat(phi, dt=dt)(res.solution) res = milp.encode_and_run(g) assert pointwise_sat(phi, dt=dt)(res.solution)
def dict2pdfa(mapping, start: PA.State): """Convert nested dictionary into a PDFA. - mapping is a nested dictionary of the form: mapping = { <State>: (<Label>, { <Action>: { <State>: <Probability> } } } """ label_map = fn.walk_values(ig(0), mapping) transition_map = fn.walk_values(ig(1), mapping) outputs = set(bind(mapping).Values()[0].collect()) inputs = set(bind(mapping).Values()[1].Keys().collect()) return PA.pdfa( start=start, label=label_map.get, inputs=inputs, outputs=outputs, **_encode_two_player_game(transition_map) )
def create_scenario(g, i): def relabel(x): return x if i == 0 or x in g.model.vars.input else f"{x}#{i}" relabel_phi = stl.ast.lineq_lens.terms.Each().id.modify(relabel) g = bind(g).specs.Each().modify(relabel_phi) g = bind(g).model.vars.Each().Each().modify(relabel) return g
def test_type_custom_class_immutable(): class C(object): def __init__(self, a): self._a = a @property def a(self): return self._a with pytest.raises(AttributeError): bind(C(9)).a.set(7)
def __and__(self, g): if self.model != g.model: # TODO: # 1. Check that the dynamics are compatible. # 2. If so, merge states etc. raise NotImplementedError g2 = bind(self).specs.obj.modify(lambda x: x & g.specs.obj) g2 = bind(self).specs.init.modify(lambda x: x & g.specs.init) g2 = bind(self).specs.learned.modify(lambda x: x & g.specs.learned) return g2
def invert(self): # Swap Spec g = bind(self).specs.obj.set(~self.specs.obj) # Swap Inputs g = bind(g).model.vars.env.set(self.model.vars.input) g = bind(g).model.vars.input.set(self.model.vars.env) # Swap Dynamics g = bind(g).model.dyn.B.set(self.model.dyn.C) g = bind(g).model.dyn.C.set(self.model.dyn.B) return g
def _distribute_next(phi, i=0): if isinstance(phi, (LinEq, AtomicPred)): return stl.utils.next(phi, i=i) elif isinstance(phi, Next): return _distribute_next(phi.arg, i=i + 1) children = tuple(_distribute_next(c, i) for c in phi.children) if isinstance(phi, (And, Or)): return bind(phi).args.set(children) elif isinstance(phi, (Neg, Next)): return bind(phi).arg.set(children[0])
def fromChild0(self,childId,newChildType): # only called from loop nCT,curCh,nW = gotNewType(self.members[childId].curType,self.kidsType(childId)) if not curCh: return False ctCh,self.curType = T.tupleFixUp(L.bind(self.curType).tMindx[childId].set(nCT)) assert not nW self.up.receive(self.myChildId,self.curType) # check shadowing!! FIXME return True
def pTrT(self, pt, rt): assert pt.tMfamily == T.mfTuple and len(pt.tMindx) == 2 if pt.tMindx[0] == T.mvtEmpty: return T.mvtAny, T.mvtEmpty # fail self.rt = H.intersection2(pt.tMindx[1], rt) self.pt = L.bind(pt).tMindx[1].set(self.rt) ch, self.pt = T.tupleFixUp(self.pt) return self.pt, self.rt
def fromClosR0(self,iden,newType): # newType is closR's current val (or better) newCur,curCh,nW = gotNewType(newType,self.extIds[iden].mtval) if not curCh: return False # current value not changed self.extIds[iden] = L.bind(self.extIds[iden]).mtval.set(newCur) self.gotAllEIs = all ((eiv.mtval.tMsubset != None) for eiv in self.extIds.values()) assert not nW return True
def updateAnId(self,name,newType): if newType==T.mvtAny: return newCur, curCh, newWrong = gotNewType(newType,self.myIds[name].mtval) if curCh: # different from curType self.myIds[name] = L.bind(self.myIds[name]).mtval.set(newCur) for r in self.myIds[name].registry: # tell uses and closures about change r.receive(name,newCur)
def visit_terms(self, _, children): if isinstance(children[0], list): term, _1, sgn, _2, terms = children[0] terms = bind(terms)[0].coeff * sgn return [term] + terms else: return children
def test_type_custom_class_frozen_dataclass(): @dataclasses.dataclass(frozen=True) class C: a: int b: str assert bind(C(1, "hello")).a.set(2) == C(2, "hello")
def _discretize(phi, dt): if isinstance(phi, (LinEq, AtomicPred, _Top, _Bot)): return phi children = tuple(_discretize(arg, dt) for arg in phi.children) if isinstance(phi, (And, Or)): return bind(phi).args.set(children) elif isinstance(phi, (Neg, Next)): return bind(phi).arg.set(children[0]) # Only remaining cases are G and F psi = children[0] l, u = round(phi.interval.lower / dt), round(phi.interval.upper / dt) psis = (next(psi, i) for i in range(l, u + 1)) opf = andf if isinstance(phi, G) else orf return opf(*psis)
def test_lens_descriptor_zoom(): class MyClass(object): def __init__(self, items): self._private_items = items def __eq__(self, other): return self._private_items == other._private_items def __repr__(self): return "M({!r})".format(self._private_items) first = lens._private_items[0] data = (MyClass([1, 2, 3]), ) assert bind(data)[0].first.get() == 1 assert bind(data)[0].first.set(4) == (MyClass([4, 2, 3]), )
def ast_lens(phi, bind=True, *, pred=lambda _: False, focus_lens=lambda _: [lens], getter=False): child_lenses = _ast_lens(phi, pred=pred, focus_lens=focus_lens) phi = lenses.bind(phi) if bind else lens return (phi.Tuple if getter else phi.Fork)(*child_lenses)
def __get__(self, instance: Context | None, owner: Type[Context] | None) -> Node: path: PathType if instance is None: path = tuple() else: path = instance._path atoms = set(lenses.bind(self.condition.walk()).Each().Instance(_Atom).collect()) v = {a.id: _Atom(path + a.path, a.domain) for a in atoms} return self.condition[v]
def test_type_custom_class_copy_and_mutate(): class C(object): def __init__(self, a, b): self.a = a self.b = b def __eq__(self, other): return self.a == other.a and self.b == other.b assert bind(C(C(0, 1), C(2, 3))).a.b.set(4) == C(C(0, 4), C(2, 3))
def pTrT(self, pt, rt): assert pt.tMfamily == T.mfTuple and len(pt.tMindx) == 2 if pt.tMindx[1].tMsubset == rt.tMsubset == None: return pt, rt assert pt.tMindx[1].tMfamily == T.mfType and len( pt.tMindx[1].tMsubset) == 1 reqT = pt.tMindx[1].tMsubset[0] irt = H.intersectionList([pt.tMindx[0], reqT, rt]) # irt must have the value ?!? return T.tupleFixUp( L.bind(pt).tMindx[0].set(irt))[1], T.fixIfTuple(irt)
def path(self): c = C(1, List(C(2), C(3, List(C(4, List(C(5))), C(6))), C(7))) t = path_lens_pred(c, _.c, _.a, _ == 5).x mod = lambda a: (a + 10 if isinstance(a, int) else bind(a).a.modify(_ + 20)) m = t.modify(lambda a: map(mod, a)) target = C(21, List(C(2), C(23, List(C(24, List(C(15))), C(6))), C(7))) m.should.equal(target) m2 = t.get() t.set(map(mod, m2)).should.equal(target)
def pTrT(self, pt, rt): assert pt.tMfamily == T.mfTuple and len(pt.tMindx) == 2 if pt.tMindx[1].tMsubset == None: return pt, rt assert pt.tMindx[1].tMfamily == T.mfType and len( pt.tMindx[1].tMsubset) == 1 reqT = pt.tMindx[1].tMsubset[0] updown = H.isA(pt.tMindx[0], reqT) if updown == None: assert pt.tMindx[0].tMsubset == None r = L.bind(pt).tMindx[0].set(reqT) else: if pt.tMindx[0].tMsubset == None: r = L.bind(pt).tMindx[0].set(reqT) else: up, down = updown val = up(pt.tMindx[0].tMsubset[0]) r = L.bind(pt).tMindx[0].set(T.typeWithVal(reqT, val)) r = T.tupleFixUp(r)[1] return r, r.tMindx[0]
def tupleFixUp(t): # t:MtVal if t==mvtEmpty: return False,t assert t.tMfamily.famObj == P.mTuple subs = tuple(fixIfTuple(t.tMindx[i]) for i in range(len(t.tMindx))) if t.tMsubset!=None: tupv = t.tMsubset[0] # only single elt subsets allowed if all(subs[i].tMsubset!=None and subs[i].tMsubset[0]==tupv[i] for i in range(len(subs))): return False,t assert all(subs[i].tMsubset==None or subs[i].tMsubset[0]==tupv[i]\ for i in range(len(subs))) return True,L.bind(t).tMindx.set(tuple( typeWithVal(subs[i],tupv[i]) for i in range(len(subs)))) # Only handle case where tMsubset has 1 element FIXME # t.tMindx is an MVal for List(Type). for tt in subs: if tt.tMsubset==None: return False,t #if all (tt.tMsubset!=None for tt in subs): newtMsubset = (tuple(tt.tMsubset[0] for tt in subs),) return True,L.bind(t).tMsubset.set(newtMsubset) # MtVal(t.tMfamily,t.tMindx,newtMsubset)
def update_board(s: State, b=EMPTY_BOARD): with NamedTemporaryFile("w") as f: f.write(to_sense_stim(s)) f.flush() out = subprocess.check_output(f"aigsim -m sense.aig {f.name}", shell=True) colorize = unpack_sense_stim_result(out) cursor = colorize(POS) board = bind(b)[flat_index(s.x, s.y)].set(cursor) return board
def directed_hausdorff(recs1, recs2, *, metric=dist_rec_bounds): responses = _compute_responses(recs1, recs2) values = bind(responses).Values() d = Interval(max(values[0].collect()), max(values[1].collect())) # TODO: can this be tightened? potential_moves = {r for r in recs1 if responses[r] & d} def is_required(r2): return any(responses[r1] & metric(r1, r2) for r1 in potential_moves) required_responses = {r2 for r2 in recs2 if is_required(r2)} return d, (potential_moves, required_responses)
def _discretize(phi, dt, horizon): if isinstance(phi, (LinEq, AtomicPred, _Top, _Bot)): return phi if not isinstance(phi, (F, G, Until)): children = tuple(_discretize(arg, dt, horizon) for arg in phi.children) if isinstance(phi, (And, Or)): return bind(phi).args.set(children) elif isinstance(phi, (Neg, Next)): return bind(phi).arg.set(children[0]) raise NotImplementedError elif isinstance(phi, Until): raise NotImplementedError # Only remaining cases are G and F upper = min(phi.interval.upper, horizon) l, u = round(phi.interval.lower / dt), round(upper / dt) psis = (next(_discretize(phi.arg, dt, horizon - i), i) for i in range(l, u + 1)) opf = andf if isinstance(phi, G) else orf return opf(*psis)
def pTrT(self, pt, rt): assert pt.tMfamily == T.mfTuple and len(pt.tMindx) == 2 cases = pt.tMindx[1].tMsubset[0] p4c = pt.tMindx[0] if p4c.tMsubset == None and rt.tMsubset == None: return pt, rt pts = [None] * len(cases) rts = [None] * len(cases) for i in range(len(cases)): cr = I.ClosureRun( None, cases[i]) # I don't think callEt param is used???? didSomething, pts[i], rts[i] = cr.changePR(p4c, rt) # Now we have possible params and results, we put together # The parameters we are consistent with is the Union of pts, results is Union of rts return L.bind(pt).tMindx[0].set(H.intersectionList(pts)), H.unionList( rts) # tupleFixUp?FIXME
def test_type_custom_class_lens_setattr(): class C(object): def __init__(self, a): self._a = a @property def a(self): return self._a def __eq__(self, other): return self.a == other.a def _lens_setattr(self, key, value): if key == "a": return C(value) assert bind(C(C(9))).a.a.set(4) == C(C(4))
def mpc(orig: Game, *, use_smt=False,): prev_games = [(0, orig.scope, orig)] while True: max_age = max(map(lens[0].get(), prev_games)) age, _, g = prev_games[0] g = g >> max_age - age for age, _, g2 in prev_games[1:]: g &= g2 >> max_age - age res = solve(g, use_smt=use_smt) msg = yield bind(res).solution.modify(time_shift(max_age)) new_init = measurement_to_stl(msg.measurement) next_game = orig.reinit(new_init) next_game = next_game.new_obj(msg.obj) # Stale old games + Remove out of scope games + add new game. prev_games = [(t+1, s, g) for t, s, g in prev_games if t < s] prev_games.append((0, next_game.scope, next_game))
def _encode_two_player_game(mapping): """Convert transition probabilities from state to two player game transition and distribution. mapping: State => (Action => (State => Prob)) where (=>) denotes a Dictionary map. """ e_size = 0 # Environment Alphabet Size. def reindex(state2prob): """Enumerates states and transforms the mapping: State => Prob to a mapping: Index => (State, Prob) """ nonlocal e_size e_size = max(e_size, len(state2prob)) return {i: (s, p) for i, (s, p) in enumerate(state2prob.items())} # State => (Action => (EnvironmentAction => (State, Prob))) mapping = bind(mapping).Values().Values().modify(reindex) def transition(state, composite_action): sys, env = composite_action dist = mapping[state][sys] if env not in dist: # Probability 0 event. return state return dist[env][0] def env_dist(state, sys): return {e: p for e, (_, p) in mapping[state][sys].items()} return { "env_inputs": range(e_size), "transition": transition, "env_dist": env_dist, }
def new_horizon(self, H): g = bind(self).specs.obj.modify(lambda x: stl.alw(x, lo=0, hi=H)) return g
def __rshift__(self, t): return bind(self).specs.Each().call('__rshift__', t=t)
def learn(self, phi): return bind(self).specs.learned.modify(lambda x: x & phi)
def test_ZoomTraversal_set(): l = b.GetitemLens(0) & b.ZoomTraversal() data = [bind([1, 2, 3])[1]] assert l.set(data, 7) == [[1, 7, 3]]
def reinit(self, phi): return bind(self).specs.init.set(phi)
def new_obj(self, phi): return bind(self).specs.obj.set(phi)