def p_decl_definition(p: Any) -> None: 'decl : onetwostate DEFINITION id LPAREN params RPAREN definition_body' twostate = p[1] body = p[7] if isinstance(body, syntax.BlockStatement): if twostate == 'onestate': utils.print_error( p.slice[7], "syntax error: imperative body of definition cannot be declared 'onestate'" ) return twostate_bool = True else: twostate_bool = twostate == 'twostate' if not twostate_bool and isinstance(body, tuple): mods, _ = body if len(mods) != 0: utils.print_error( p.slice[7], "syntax error: 'onestate' definition cannot have a modifies clause" ) return p[0] = syntax.DefinitionDecl(p[3], public=False, twostate=twostate_bool, name=p[3].value, params=p[5], body=p[7])
def p_decl_transition(p: Any) -> None: 'decl : TRANSITION id LPAREN params RPAREN definition_body' id_tok: Token = p[2] body: Union[Tuple[List[syntax.ModifiesClause], syntax.Expr], syntax.BlockStatement] = p[6] body_span = body[1].span if isinstance(body, tuple) else body.span p[0] = syntax.DefinitionDecl(is_public_transition=True, num_states=2, name=id_tok.value, params=p[4], body=p[6], span=loc_join(p.slice[1], body_span))
def p_decl_transition(p: Any) -> None: 'decl : TRANSITION id LPAREN params RPAREN definition_body' p[0] = syntax.DefinitionDecl(p[2], public=True, twostate=True, name=p[2].value, params=p[4], body=p[6])
def relaxed_program(prog: syntax.Program) -> syntax.Program: new_decls: List[syntax.Decl] = [d for d in prog.sorts()] actives: Dict[syntax.SortDecl, syntax.RelationDecl] = {} for sort in prog.sorts(): name = prog.scope.fresh('active_' + sort.name) r = syntax.RelationDecl(name, arity=[syntax.UninterpretedSort(sort.name)], mutable=True, derived=None, annotations=[]) actives[sort] = r new_decls.append(r) # active relations initial conditions: always true for sort in prog.sorts(): name = prog.scope.fresh(sort.name[0].upper()) expr = syntax.Forall([syntax.SortedVar(name, None)], syntax.Apply(actives[sort].name, [syntax.Id(name)])) new_decls.append(syntax.InitDecl(name=None, expr=expr)) for d in prog.decls: if isinstance(d, syntax.SortDecl): pass # already included above elif isinstance(d, syntax.RelationDecl): if d.derived_axiom is not None: expr = syntax.relativize_quantifiers(actives, d.derived_axiom) new_decls.append(syntax.RelationDecl(d.name, d.arity, d.mutable, expr, d.annotations)) else: new_decls.append(d) elif isinstance(d, syntax.ConstantDecl): new_decls.append(d) elif isinstance(d, syntax.FunctionDecl): new_decls.append(d) elif isinstance(d, syntax.AxiomDecl): new_decls.append(d) elif isinstance(d, syntax.InitDecl): new_decls.append(d) elif isinstance(d, syntax.DefinitionDecl): assert not isinstance(d.body, syntax.BlockStatement), \ "relax does not support transitions written in imperative syntax" mods, expr = d.body expr = syntax.relativize_quantifiers(actives, expr) if d.is_public_transition: guard = syntax.relativization_guard_for_binder(actives, d.binder) expr = syntax.And(guard, expr) new_decls.append(syntax.DefinitionDecl(d.is_public_transition, d.num_states, d.name, params=d.binder.vs, body=(mods, expr))) elif isinstance(d, syntax.InvariantDecl): expr = syntax.relativize_quantifiers(actives, d.expr) new_decls.append(syntax.InvariantDecl(d.name, expr=expr, is_safety=d.is_safety, is_sketch=d.is_sketch)) else: assert False, d new_decls.append(relaxation_action_def(prog, actives=actives, fresh=True)) res = syntax.Program(new_decls) res.resolve() # #sorrynotsorry return res
def p_decl_transition(p: Any) -> None: 'decl : TRANSITION id LPAREN params RPAREN definition_body' id_tok: Token = p[2] mods: Tuple[syntax.ModifiesClause, ...] expr: syntax.Expr mods, expr = p[6] p[0] = syntax.DefinitionDecl(is_public_transition=True, num_states=2, name=id_tok.value, params=p[4], mods=mods, expr=expr, span=loc_join(p.slice[1], expr.span))
def p_decl_definition(p: Any) -> None: 'decl : kstate DEFINITION id LPAREN params RPAREN definition_body' k_tok, num_states = p[1] mods: Tuple[syntax.ModifiesClause, ...] expr: syntax.Expr mods, expr = p[7] if num_states != 2 and mods: utils.print_error(mods[0].span, "syntax error: modifies clause only allowed on twostate definitions or transitions") return p[0] = syntax.DefinitionDecl(is_public_transition=False, num_states=num_states, name=p[3].value, params=p[5], mods=mods, expr=expr, span=loc_join(k_tok, loc_join(p.slice[2], expr.span)))
def p_decl_definition(p: Any) -> None: 'decl : kstate DEFINITION id LPAREN params RPAREN definition_body' k_tok, num_states = p[1] body: Union[Tuple[List[syntax.ModifiesClause], syntax.Expr], syntax.BlockStatement] = p[7] body_span = body[1].span if isinstance(body, tuple) else body.span if isinstance(body, syntax.BlockStatement): if num_states == 1: utils.print_error(body.span, "syntax error: imperative body of definition cannot be declared 'onestate'") return if num_states != 2 and isinstance(body, tuple): mods, _ = body if mods: utils.print_error(mods[0].span, "syntax error: modifies clause only allowed on twostate definitions or transitions") return p[0] = syntax.DefinitionDecl(is_public_transition=False, num_states=num_states, name=p[3].value, params=p[5], body=body, span=loc_join(k_tok, loc_join(p.slice[2], body_span)))
def relativize_decl(d: syntax.DefinitionDecl, actives: Dict[syntax.SortDecl, syntax.RelationDecl], scope: syntax.Scope, inline_relax_actives: bool) -> syntax.DefinitionDecl: mods, expr = d.mods, d.expr expr = syntax.relativize_quantifiers(actives, expr) if d.is_public_transition: guard = syntax.relativization_guard_for_binder(actives, d.binder) expr = syntax.And(guard, expr) if inline_relax_actives: new_mods, new_conjs = relax_actives_action_chunk(scope, actives) mods += new_mods expr = syntax.And(expr, *new_conjs) relativized_def = syntax.DefinitionDecl(d.is_public_transition, d.num_states, d.name, params=d.binder.vs, mods=mods, expr=expr) return relativized_def
def relaxation_action_def(prog: syntax.Program, actives: Optional[Dict[syntax.SortDecl, syntax.RelationDecl]]=None, fresh: bool=True) \ -> syntax.DefinitionDecl: decrease_name = (prog.scope.fresh('decrease_domain') if fresh else 'decrease_domain') mods = [] conjs: List[Expr] = [] if actives is None: actives = active_rel_by_sort(prog) # a conjunct allowing each domain to decrease for sort in prog.sorts(): name = prog.scope.fresh(sort.name[0].upper()) ap = syntax.Apply(actives[sort].name, [syntax.Id(None, name)]) expr = syntax.Forall([syntax.SortedVar(None, name, None)], syntax.Implies(ap, syntax.Old(ap))) conjs.append(expr) mods.append(syntax.ModifiesClause(None, actives[sort].name)) # constants are active for const in prog.constants(): conjs.append(syntax.Apply(actives[syntax.get_decl_from_sort(const.sort)].name, [syntax.Id(None, const.name)])) # functions map active to active for func in prog.functions(): names: List[str] = [] func_conjs = [] for arg_sort in func.arity: arg_sort_decl = syntax.get_decl_from_sort(arg_sort) name = prog.scope.fresh(arg_sort_decl.name[0].upper(), also_avoid=names) names.append(name) func_conjs.append(syntax.Apply(actives[arg_sort_decl].name, [syntax.Id(None, name)])) ap_func = syntax.Old(syntax.Apply(func.name, [syntax.Id(None, name) for name in names])) active_func = syntax.Apply(actives[syntax.get_decl_from_sort(func.sort)].name, [ap_func]) conjs.append(syntax.Forall([syntax.SortedVar(None, name, None) for name in names], syntax.Implies(syntax.And(*func_conjs), active_func))) # (relativized) axioms hold after relaxation for axiom in prog.axioms(): if not syntax.is_universal(axiom.expr): conjs.append(syntax.relativize_quantifiers(actives, axiom.expr)) # derived relations have the same interpretation on the active domain for rel in prog.derived_relations(): names = [] rel_conjs = [] for arg_sort in rel.arity: arg_sort_decl = syntax.get_decl_from_sort(arg_sort) name = prog.scope.fresh(arg_sort_decl.name[0].upper(), also_avoid=names) names.append(name) rel_conjs.append(syntax.Apply(actives[arg_sort_decl].name, [syntax.Id(None, name)])) ap_rel = syntax.Apply(rel.name, [syntax.Id(None, name) for name in names]) conjs.append(syntax.Forall([syntax.SortedVar(None, name, None) for name in names], syntax.Implies(syntax.And(*rel_conjs), syntax.Iff(ap_rel, syntax.Old(ap_rel))))) return syntax.DefinitionDecl(None, public=True, twostate=True, name=decrease_name, params=[], body=(mods, syntax.And(*conjs)))
def relaxation_action_def(prog: syntax.Program, actives: Optional[Dict[syntax.SortDecl, syntax.RelationDecl]] = None, fresh: bool = True) -> syntax.DefinitionDecl: decrease_name = (prog.scope.fresh('decrease_domain') if fresh else 'decrease_domain') mods: Tuple[syntax.ModifiesClause, ...] = () conjs: List[Expr] = [] if actives is None: actives = active_rel_by_sort(prog) # a conjunct allowing each domain to decrease new_mods, new_conjs = relax_actives_action_chunk(prog.scope, actives) mods += new_mods conjs += new_conjs # constants are active for const in prog.constants(): conjs.append( syntax.New( syntax.Apply( actives[syntax.get_decl_from_sort(const.sort)].name, (syntax.Id(const.name), )))) # functions map active to active for func in prog.functions(): names: List[str] = [] func_conjs = [] for arg_sort in func.arity: arg_sort_decl = syntax.get_decl_from_sort(arg_sort) name = prog.scope.fresh(arg_sort_decl.name[0].upper(), also_avoid=names) names.append(name) func_conjs.append( syntax.New( syntax.Apply(actives[arg_sort_decl].name, (syntax.Id(name), )))) ap_func = syntax.Apply(func.name, tuple(syntax.Id(name) for name in names)) name = prog.scope.fresh('y', also_avoid=names) active_func = syntax.Let( syntax.SortedVar(name, func.sort), ap_func, syntax.New( syntax.Apply( actives[syntax.get_decl_from_sort(func.sort)].name, (syntax.Id(name), )))) conjs.append( syntax.Forall( tuple(syntax.SortedVar(name, None) for name in names), syntax.Implies(syntax.And(*func_conjs), active_func))) # (relativized) axioms hold after relaxation for axiom in prog.axioms(): if not syntax.is_universal(axiom.expr): conjs.append(syntax.relativize_quantifiers(actives, axiom.expr)) # derived relations have the same interpretation on the active domain for rel in prog.derived_relations(): names = [] rel_conjs = [] for arg_sort in rel.arity: arg_sort_decl = syntax.get_decl_from_sort(arg_sort) name = prog.scope.fresh(arg_sort_decl.name[0].upper(), also_avoid=names) names.append(name) rel_conjs.append( syntax.Apply(actives[arg_sort_decl].name, (syntax.Id(name), ))) ap_rel = syntax.Apply(rel.name, tuple(syntax.Id(name) for name in names)) conjs.append( syntax.Forall( tuple(syntax.SortedVar(name, None) for name in names), syntax.Implies(syntax.And(*rel_conjs), syntax.Iff(syntax.New(ap_rel), ap_rel)))) return syntax.DefinitionDecl(is_public_transition=True, num_states=2, name=decrease_name, params=(), mods=mods, expr=syntax.And(*conjs))