예제 #1
0
def event(action_id:str, role_id:str = ENV_ROLE,
          timestamp: int = 0,
          params:Optional[Dict[str, Data]] = None,
          eventType: Optional[EventType] = None ) -> Event:
    if eventType is None:
        eventType = EventType.env_next if role_id == ENV_ROLE else EventType.party_next
    params = params or dict()
    return Event(action_id=castid(ActionId, action_id), role_id=castid(RoleId, role_id),
                 timestamp= timestamp,
                 actionparam_subst=cast(ActionParamSubst, params) if params else None,
                 actionparam_subst_list=list(params.values()) if params else None,
                 type=eventType)
def evalTrace(it: Union[Trace, CompleteTrace],
              prog: L4Contract,
              verbose: bool = True,
              debug: bool = False):
    env = ExecEnvNF(prog)
    if isinstance(it, CompleteTrace):
        for contract_param in it.contract_param_subst:
            # replacing hardcoded contrat param vals with passed in ones
            supplied_val = it.contract_param_subst[contract_param]
            paramdec = prog.contract_params[castid(ContractParamId,
                                                   contract_param)]
            assert supplied_val is not None
            if isinstance(paramdec.value_expr, Literal):
                paramdec.value_expr.lit = supplied_val
            else:
                paramdec.value_expr = L4ContractConstructor.mk_literal(
                    supplied_val)
        return env.evalTrace(trace=it.events,
                             finalSituationId=cast(SituationId,
                                                   it.final_situation),
                             final_var_vals=cast(Optional[GVarSubst],
                                                 it.final_values),
                             verbose=verbose,
                             debug=debug)
    else:
        return env.evalTrace(trace=it, verbose=verbose, debug=debug)
예제 #3
0
    def action2smtlib(self, a: Action):
        self.curaid = a.action_id
        self.commands_for_actions[a.action_id] = []
        self.push()
        self.actionParams2smtlib(a)

        # preconditions hold upon entering
        if len(a.preconditions) > 0:
            self.append("; PRE begin")
            for pre in a.preconditions:
                self.appendAssert(self.term2smtlibdef(pre))
            self.append("; PRE end")

        # assert that invariants hold when entering the state transform:
        for inv_assert in self.invariant_true_assertions:
            self.append(inv_assert)

        self.stateTransform2smtlib(a.state_transform)

        for invcheck in self.invariant_maintained_conjectures:
            # invcheck has the form ('=>', e1, e2)
            hypoth_for_printing = invcheck.args[1]
            self.appendProofOblig(
                invcheck, f"{self.curaid} INV CHECK:" +
                smtlib_expr_to_str(hypoth_for_printing))
        self.pop()
        self.curaid = castid(ActionId, "")
 def _get_val(s: str) -> Any:
     if s in prog.contract_params:
         return str(prog.contract_params[castid(ContractParamId,
                                                s)].value_expr)
     elif s in prog.contract_params_nonoperative:
         return str(prog.contract_params_nonoperative[s])
     elif s in prog.nlg_names:
         return str(prog.nlg_names[s])
     elif s in prog.nlg_definitions:
         return str(prog.nlg_definitions[s])
예제 #5
0
    def __init__(self, action_id: ActionId) -> None:
        self.action_id = action_id
        self.dest_situation_id: SituationId = castid(
            SituationId, "to be set after constructor")
        self.traversal_bounds: Any = None  # actually SExpr
        self.allowed_subjects: Any = None  # actually SExpr
        self.action_description: Optional[str] = None
        self.local_vars: Dict[LocalVarId, LocalVarDec] = dict()
        self.is_compound = False

        self.following_anon_situation: Optional[Situation] = None

        self.state_transform: Optional[StateTransform] = None
        self.preconditions: List[Term] = []
        self.postconditions: List[Term] = []
        self.prose_refs: List[str] = []

        self.param_sorts_by_name: ParamsDec = dict(
        )  # str param id -> str sort id
        self.param_names: List[ActionParamId] = []
        self.param_name_to_ind: Dict[ActionParamId, int] = dict()

        self.nlg = ""
        self.nlgsection = "root"
예제 #6
0
 def name(self) -> ContractParamId:
     # cast shouldn't be necessary
     return castid(ContractParamId, self.paramdec.name)
예제 #7
0
    def evalTrace(self,
                  trace: Trace,
                  finalSituationId: Optional[SituationId] = None,
                  final_var_vals: Optional[GVarSubst] = None,
                  verbose=False,
                  debug=False):
        prog = self.top
        self.evalContractParamDecs(prog.contract_params)
        self.evalStateVarDecs(prog.state_var_decs)
        for i in range(len(trace)):
            # print("Environ", self.environ_tostr())
            eventi = trace[i]
            self.cur_event = eventi
            cur_action_id = self.cur_event.action_id
            cur_event_delta = self.cur_event_delta()
            cur_event_datetime = self.delta2datetime(cur_event_delta)
            cur_action = self.top.action(cur_action_id)

            for gvarid in self.gvarvals:
                if isprimed(gvarid):
                    self.gvarvals[unprimed(gvarid)] = self.gvarvals[gvarid]
            self.gvarvals = {
                id: self.gvarvals[id]
                for id in self.gvarvals if not isprimed(id)
            }
            # print("last_situation_entrance_delta", self.last_situation_entrance_delta)

            if self.last_situation_entrance_delta is not None and self.last_situation_entrance_delta > cur_event_delta:
                self.evalError(
                    f"Event timestamps must be non-decreasing, but last event timestamp "
                    f"{self.last_situation_entrance_delta} is greater than current event timestamp {cur_event_delta}"
                )

            if not cur_action:
                self.evalError(f"Don't recongize action id {cur_action_id}")

            if not self.top.situation_mentions_action_in_nextaction_rule(
                    self.last_or_current_situation_id, cur_action_id):
                self.evalError(
                    f"Action type indicated using a next-rule, but current situation {self.last_or_current_situation_id} "
                    f"has no such rule for action {cur_action_id}.")
            self.evaluation_is_in_situation = True
            nextrule_assessment = self.assess_event_legal_wrt_nextrules(
                eventi, verbose=verbose)
            self.evaluation_is_in_situation = False

            actionstr = event_to_action_str(eventi)
            srcid = self.last_or_current_situation_id
            if isinstance(nextrule_assessment, EventOk):
                self.evaluation_is_in_action = True
                self.apply_action(cur_action, verbose)
                self.evaluation_is_in_action = False
                if verbose:
                    print(
                        f"[{cur_event_datetime}] {srcid} --{actionstr}--> {self.last_or_current_situation_id}\n"
                    )
            elif isinstance(nextrule_assessment, BreachResult):
                if verbose:
                    print("Breach result:", nextrule_assessment)
                breach_situation_id = breachSituationId(
                    *nextrule_assessment.role_ids)
                self.apply_action(cur_action,
                                  verbose,
                                  to_breach_situation_id=breach_situation_id)

                if verbose:
                    print(
                        f"[{cur_event_datetime}] {srcid} --{actionstr}--> {breach_situation_id}"
                    )

                # if i != len(trace) - 1:
                #     print("Trace prefix results in a breach, but there are more events after.")
                assert i == len(
                    trace
                ) - 1, "Trace prefix results in a breach, but there are more events after."
                break
            else:
                assert False, "Can't get here?"
            if debug:
                # code, IPython, pdb are other options
                import ipdb  # type: ignore
                ipdb.set_trace()  # type: ignore
                # other things tried:
                # code.InteractiveConsole(locals=locals()).interact()
                # IPython.embed()

        for gvarid in self.gvarvals:
            if isprimed(gvarid):
                self.gvarvals[unprimed(gvarid)] = self.gvarvals[gvarid]
        self.gvarvals = {
            id: self.gvarvals[id]
            for id in self.gvarvals if not isprimed(id)
        }

        if final_var_vals:
            for varid, expected_val in final_var_vals.items():
                if varid in self.gvarvals:
                    actual_val = self.gvarvals[castid(StateVarId, varid)]
                elif varid in self.writeouts:
                    actual_val = self.writeouts[varid]
                else:
                    self.evalError(
                        f"Var {varid} in Trace object is neither a state variable nor a writeout local variable"
                    )
                assert actual_val == expected_val, f"Expected state variable {gvarid} to have value {expected_val} at end of trace, but had value {actual_val}."

        if finalSituationId:
            assert self.last_or_current_situation_id == finalSituationId, f"Trace expected to end in situation {finalSituationId} but ended in situation {self.last_or_current_situation_id}"
예제 #8
0
 def param_sort(self, ind_or_name: Union[str, int]) -> Sort:
     if isinstance(ind_or_name, str):
         return self.param_sorts_by_name[castid(ActionParamId, ind_or_name)]
     if isinstance(ind_or_name, int):
         return self.param_sorts_by_name[self.param_names[ind_or_name]]
 def actid2link(actid: str) -> html_tag:
     act = prog.action(castid(ActionId, actid))
     return a(act.nlg, href=f"#{actid}")
 def sitid2link(sitid: str) -> html_tag:
     sit = prog.situation(castid(SituationId, sitid))
     return a(sit.nlg, href=f"#{sitid}")