Beispiel #1
0
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])
Beispiel #2
0
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))
Beispiel #3
0
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])
Beispiel #4
0
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
Beispiel #5
0
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))
Beispiel #6
0
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)))
Beispiel #7
0
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
Beispiel #9
0
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))