Beispiel #1
0
 def type(self, typedef):
     #        print "typedef {!r}".format(typedef)
     self.domain.sort_order.append(typedef.name)
     if isinstance(typedef, ivy_ast.GhostTypeDef):
         self.domain.ghost_sorts.add(typedef.name)
     if isinstance(typedef.value, ivy_ast.StructSort):
         sort = ivy_logic.ConstantSort(typedef.name)
         self.domain.sig.sorts[typedef.name] = sort
         # handle empty struct
         if typedef.name not in self.domain.sort_destructors:
             self.domain.sort_destructors[typedef.name] = []
         for a in typedef.value.args:
             p = a.clone([ivy_ast.Variable('V:dstr', sort.name)] + a.args)
             p.sort = a.sort
             with ASTContext(typedef):
                 with ASTContext(a):
                     self.destructor(p)
         return
     with ASTContext(typedef.value):
         sort = typedef.value.cmpl(typedef.name)
     self.domain.sig.sorts[typedef.name] = sort
     for c in sort.defines():  # register the type's constructors
         sym = Symbol(c, sort)
         self.domain.functions[sym] = 0
         self.domain.sig.symbols[c] = sym
         self.domain.sig.constructors.add(sym)
Beispiel #2
0
def sortify_with_inference(ast):
    #    print "compiling : {}".format(ast)
    with top_sort_as_default():
        res = ast.compile()
    with ASTContext(ast):
        res = sort_infer(res)
    return res
Beispiel #3
0
def compile_inline_call(self, args):
    params, returns = top_context.actions[self.rep]
    if len(returns) != 1:
        raise IvyError(self, "wrong number of return values")
        # TODO: right now we can't do anything with multiple returns
        sorts = [cmpl_sort(r.sort) for r in returns]
        ress = []
        for sort in sorts:
            res = ivy_logic.Symbol('loc:' + str(len(expr_context.local_syms)),
                                   sort)
            expr_context.local_syms.append(res)
            ress.append(res())
        expr_context.code.append(
            CallAction(*([ivy_ast.Atom(self.rep, args)] + ress)))
        return ivy_ast.Tuple(*ress)
    sort = cmpl_sort(returns[0].sort)
    res = ivy_logic.Symbol('loc:' + str(len(expr_context.local_syms)), sort)
    expr_context.local_syms.append(res)
    with ASTContext(self):
        if len(params) != len(args):
            raise iu.IvyError(
                self,
                "wrong number of input parameters (got {}, expecting {})".
                format(len(args), len(params)))
        args = [
            sort_infer_contravariant(a, cmpl_sort(p.sort))
            for a, p in zip(args, params)
        ]
    expr_context.code.append(CallAction(ivy_ast.Atom(self.rep, args), res))
    return res()
Beispiel #4
0
def compile_call(self):
    assert top_context
    ctx = ExprContext(lineno=self.lineno)
    name = self.args[0].rep
    if name not in top_context.actions:
        raise iu.IvyError(self, "call to unknown action: {}".format(name))
    with ctx:
        args = [a.cmpl() for a in self.args[0].args]
    params, returns = top_context.actions[name]
    if len(returns) != len(self.args) - 1:
        raise iu.IvyError(
            self,
            "wrong number of output parameters (got {}, expecting {})".format(
                len(self.args) - 1, len(returns)))
    if len(params) != len(args):
        raise iu.IvyError(
            self,
            "wrong number of input parameters (got {}, expecting {})".format(
                len(args), len(params)))
    with ASTContext(self):
        mas = [sort_infer(a, cmpl_sort(p.sort)) for a, p in zip(args, params)]


#        print self.args
    res = CallAction(*([ivy_ast.Atom(name, mas)] +
                       [a.cmpl() for a in self.args[1:]]))
    res.lineno = self.lineno
    ctx.code.append(res)
    res = ctx.extract()
    #    print "compiled call action: {}".format(res)
    return res
Beispiel #5
0
 def concept(self, c):
     rel = c.args[0]
     with ASTContext(c):
         add_symbol(rel.relname,
                    get_relation_sort(self.domain.sig, rel.args, c.args[1]))
     c = sortify_with_inference(c)
     self.domain.concept_spaces.append((c.args[0], c.args[1]))
Beispiel #6
0
def compile_assign(self):
    code = []
    local_syms = []
    with ExprContext(code, local_syms):
        if isinstance(self.args[0], ivy_ast.Tuple):
            args = [sortify_with_inference(a) for a in self.args]
            if not isinstance(args[1], ivy_ast.Tuple) or len(
                    args[0].args) != len(args[1].args):
                raise IvyError(self, "wrong number of values in assignment")
            for lhs, rhs in zip(args[0].args, args[1].args):
                code.append(AssignAction(lhs, rhs))
        else:
            with top_sort_as_default():
                args = [a.compile() for a in self.args]
            if isinstance(args[1], ivy_ast.Tuple):
                raise IvyError(self, "wrong number of values in assignment")
            with ASTContext(self):
                teq = sort_infer(Equals(*args))
            args = list(teq.args)
            code.append(AssignAction(*args))
        for c in code:
            c.lineno = self.lineno
        if len(code) == 1:
            return code[0]
        res = LocalAction(*(local_syms + [Sequence(*code)]))
        res.lineno = self.lineno
        return res
Beispiel #7
0
def compile_app(self):
    args = [a.compile() for a in self.args]
    # handle action calls in rhs of assignment
    if expr_context and top_context and self.rep in top_context.actions:
        params, returns = top_context.actions[self.rep]
        if len(returns) != 1:
            raise IvyError(self, "wrong number of return values")
            # TODO: right now we can't do anything with multiple returns
            sorts = [cmpl_sort(r.sort) for r in returns]
            ress = []
            for sort in sorts:
                res = ivy_logic.Symbol(
                    'loc:' + str(len(expr_context.local_syms)), sort)
                expr_context.local_syms.append(res)
                ress.append(res())
            expr_context.code.append(
                CallAction(*([ivy_ast.Atom(self.rep, args)] + ress)))
            return ivy_ast.Tuple(*ress)
        sort = cmpl_sort(returns[0].sort)
        res = ivy_logic.Symbol('loc:' + str(len(expr_context.local_syms)),
                               sort)
        expr_context.local_syms.append(res)
        with ASTContext(self):
            if len(params) != len(args):
                raise iu.IvyError(
                    self,
                    "wrong number of input parameters (got {}, expecting {})".
                    format(len(args), len(params)))
            args = [
                sort_infer(a, cmpl_sort(p.sort)) for a, p in zip(args, params)
            ]
        expr_context.code.append(CallAction(ivy_ast.Atom(self.rep, args), res))
        return res()
    return (ivy_logic.Equals if self.rep == '=' else
            ivy_logic.find_polymorphic_symbol(self.rep))(*args)
Beispiel #8
0
 def progress(self, df):
     rel = df.args[0]
     with ASTContext(rel):
         sym = add_symbol(
             rel.relname,
             get_relation_sort(self.domain.sig, rel.args, df.args[1]))
     df = sortify_with_inference(df)
     self.domain.progress.append(df)
Beispiel #9
0
 def __call__(self, ivy):
     for decl in ivy.decls:
         with ASTContext(decl):
             n = decl.name()
             #                print "decl: {} : {}".format(n,decl.lineno if hasattr(decl,'lineno') else None)
             if n == 'assert': n = '_assert'  # reserved in python!
             if hasattr(self, n):
                 for x in decl.args:
                     getattr(self, n)(x)
Beispiel #10
0
 def derived(self, df):
     try:
         rel = df.args[0]
         with ASTContext(rel):
             sym = add_symbol(
                 rel.relname,
                 get_relation_sort(self.domain.sig, rel.args, df.args[1]))
         df = sortify_with_inference(df)
         self.domain.all_relations.append((sym, len(rel.args)))
         self.domain.relations[sym] = len(rel.args)
         self.domain.concepts.append(df)
         self.domain.updates.append(DerivedUpdate(df))
     except ValueError:
         raise IvyError(df, "definition of derived relation must be a cube")
Beispiel #11
0
def compile_local(self):
    sig = ivy_logic.sig.copy()
    with sig:
        ls = self.args[0:-1]
        if len(ls) == 1 and isinstance(ls[0], AssignAction):
            v = ls[0]
            lhs = v.args[0]
            rhs = v.args[1]
            # temporarily rename lhs symbol in case it clashes with an existing symbol
            #            tmp_lhs = lhs.prefix('__var_tmp:')
            tmp_lhs = lhs
            code = []
            local_syms = []
            with ExprContext(code, local_syms):
                with alpha_sort_as_default():
                    sym = compile_const(tmp_lhs, sig)
                    ctmp_lhs = tmp_lhs.compile()
                    crhs = rhs.compile()
            with ASTContext(self):
                teq = sort_infer(Equals(ctmp_lhs, crhs))
            clhs, crhs = list(teq.args)
            #            clhs = clhs.drop_prefix('__var_tmp:')
            asgn = v.clone([clhs, crhs])
            ivy_logic.remove_symbol(sym)
            if clhs.rep.name in sig.symbols:
                del sig.symbols[clhs.rep.name]  # shadow the existing symbol
            ivy_logic.add_symbol(clhs.rep.name, clhs.rep.sort)
            body = sortify(self.args[-1])
            lines = body.args if isinstance(body, Sequence) else [body]
            body = Sequence(*([asgn] + lines))
            code.append(LocalAction(clhs.rep, body))
            for c in code:
                c.lineno = self.lineno
            if len(code) == 1:
                return code[0]
            res = LocalAction(*(local_syms + [Sequence(*code)]))
            res.lineno = self.lineno
            return res
        cls = [compile_const(v, sig) for v in ls]
        body = sortify(self.args[-1])
        res = LocalAction(*(cls + [body]))
        res.lineno = self.lineno
        return res
Beispiel #12
0
def compile_action_def(a, sig):
    sig = sig.copy()
    if not hasattr(a.args[1], 'lineno'):
        print a
    assert hasattr(a.args[1], 'lineno')
    with sig:
        with ASTContext(a.args[1]):
            params = a.args[0].args
            pformals = [v.to_const('prm:') for v in params]
            if params:
                subst = dict((x.rep, y) for x, y in zip(params, pformals))
                a = ivy_ast.substitute_ast(a, subst)
                assert hasattr(a.args[1], 'lineno')
    #            a = ivy_ast.subst_prefix_atoms_ast(a,subst,None,None)
    #            print "after: %s" % (a)
    # convert object paramaters to arguments (object-orientation!)
            formals = [
                compile_const(v, sig) for v in pformals + a.formal_params
            ]
            returns = [compile_const(v, sig) for v in a.formal_returns]
            #        print returns
            res = sortify(a.args[1])
            assert hasattr(res, 'lineno'), res
            for suba in res.iter_subactions():
                if isinstance(suba, CallAction):
                    if any(
                            lu.used_variables_ast(a)
                            for a in suba.args[0].args):
                        iu.dbg('a.args[0]')
                        iu.dbg('a.formal_params')
                        iu.dbg('suba.lineno')
                        iu.dbg('suba')
                        raise iu.IvyError(suba,
                                          "call may not have free variables")
            res.formal_params = formals
            res.formal_returns = returns
            res.label = a.args[0].relname
            return res
Beispiel #13
0
 def _assert(self, a):
     with ASTContext(a):
         self.mod.assertions.append(
             type(a)(a.args[0], sortify_with_inference(a.args[1])))
Beispiel #14
0
def thing(self):
    with ASTContext(self):
        return self.cmpl()
Beispiel #15
0
 def relation(self, rel):
     with ASTContext(rel):
         sym = add_symbol(rel.relname,
                          get_relation_sort(self.domain.sig, rel.args))
     self.domain.all_relations.append((sym, len(rel.args)))
     self.domain.relations[sym] = len(rel.args)
Beispiel #16
0
def compile_const(v, sig):
    with ASTContext(v):
        rng = find_sort(v.sort) if hasattr(
            v, 'sort') else ivy_logic.default_sort()
        return add_symbol(v.rep, get_function_sort(sig, v.args, rng))
Beispiel #17
0
def create_isolate(iso, mod=None, **kwargs):

    mod = mod or im.module

    # treat initializers as exports
    after_inits = mod.mixins["init"]
    del mod.mixins["init"]
    mod.exports.extend(
        ivy_ast.ExportDef(ivy_ast.Atom(a.mixer()), ivy_ast.Atom(''))
        for a in after_inits)

    # check all mixin declarations

    for name, mixins in mod.mixins.iteritems():
        for mixin in mixins:
            with ASTContext(mixins):
                action1, action2 = (lookup_action(mixin, mod, a.relname)
                                    for a in mixin.args)

    # check all the delagate declarations

    for dl in mod.delegates:
        lookup_action(dl.args[0], mod, dl.delegated())
        if dl.delegee() and dl.delegee() not in mod.hierarchy:
            raise iu.IvyError(dl.args[1],
                              "{} is not a module instance".format(name))

    # check all the export declarations
    for exp in mod.exports:
        expname = exp.args[0].rep
        if expname not in mod.actions:
            raise iu.IvyError(exp, "undefined action: {}".format(expname))

    # create the import actions, if requested

    extra_with = []
    extra_strip = {}
    if create_imports.get():
        newimps = []
        for imp in mod.imports:
            if imp.args[1].rep == '':
                impname = imp.args[0].rep
                if impname not in mod.actions:
                    raise iu.IvyError(imp,
                                      "undefined action: {}".format(impname))
                action = mod.actions[impname]
                if not (type(action) == ia.Sequence and not action.args):
                    raise iu.IvyError(
                        imp,
                        "cannot import implemented action: {}".format(impname))
                extname = 'imp__' + impname
                call = ia.CallAction(
                    *([ivy_ast.Atom(extname, action.formal_params)] +
                      action.formal_returns))
                call.formal_params = action.formal_params
                call.formal_returns = action.formal_returns
                call.lineno = action.lineno
                mod.actions[impname] = call
                mod.actions[extname] = action
                newimps.append(
                    ivy_ast.ImportDef(ivy_ast.Atom(extname), imp.args[1]))
                extra_with.append(ivy_ast.Atom(impname))
                #                    extra_with.append(ivy_ast.Atom(extname))
                if iso and iso in mod.isolates:
                    ps = mod.isolates[iso].params()
                    extra_strip[impname] = [a.rep for a in ps]
                    extra_strip[extname] = [a.rep for a in ps]
            else:
                newimps.append(imp)
        mod.imports = newimps

    mixers = set()
    for ms in mod.mixins.values():
        for m in ms:
            mixers.add(m.mixer())

    # Determine the mixin order (as a side effect on module.mixins)

    get_mixin_order(iso, mod)

    # Construct an isolate

    if iso:
        isolate_component(mod,
                          iso,
                          extra_with=extra_with,
                          extra_strip=extra_strip)
    else:
        if mod.isolates and cone_of_influence.get():
            raise iu.IvyError(None, 'no isolate specified on command line')
        # apply all the mixins in no particular order
        for name, mixins in mod.mixins.iteritems():
            for mixin in mixins:
                action1, action2 = (lookup_action(mixin, mod, a.relname)
                                    for a in mixin.args)
                mixed = ia.apply_mixin(mixin, action1, action2)
                mod.actions[mixin.args[1].relname] = mixed
        # find the globally exported actions (all if none specified, for compat)
        if mod.exports:
            mod.public_actions.clear()
            for e in mod.exports:
                if not e.scope():  # global export
                    mod.public_actions.add(e.exported())
        else:
            for a in mod.actions:
                mod.public_actions.add(a)

    # Create one big external action if requested

    for name in mod.public_actions:
        mod.actions[name].label = name
    ext = kwargs['ext'] if 'ext' in kwargs else ext_action.get()
    if ext is not None:
        ext_acts = [mod.actions[x] for x in sorted(mod.public_actions)]
        ext_act = ia.EnvAction(*ext_acts)
        mod.public_actions.add(ext)
        mod.actions[ext] = ext_act

    # Check native interpretations of symbols

    slv.check_compat()

    # Make concept spaces from the conjecture

    for i, cax in enumerate(mod.labeled_conjs):
        fmla = cax.formula
        csname = 'conjecture:' + str(i)
        variables = list(lu.used_variables_ast(fmla))
        sort = ivy_logic.RelationSort([v.sort for v in variables])
        sym = ivy_logic.Symbol(csname, sort)
        space = ics.NamedSpace(ivy_logic.Literal(0, fmla))
        mod.concept_spaces.append((sym(*variables), space))

    ith.check_theory()

    # get rid of useless actions

    cone = get_mod_cone(mod)
    if cone_of_influence.get():
        for a in list(mod.actions):
            if a not in cone:
                del mod.actions[a]
    else:
        for a in list(mod.actions):
            if a not in cone and not a.startswith('ext:') and a not in mixers:
                ea = 'ext:' + a
                if ea in mod.actions and ea not in cone:
                    if ia.has_code(mod.actions[a]):
                        iu.warn(mod.actions[a],
                                "action {} is never called".format(a))

    fix_initializers(mod, after_inits)

    # show the compiled code if requested

    if show_compiled.get():
        ivy_printer.print_module(mod)
Beispiel #18
0
def create_isolate(iso,mod = None,**kwargs):

        mod = mod or im.module

        # check all mixin declarations

        for name,mixins in mod.mixins.iteritems():
            for mixin in mixins:
                with ASTContext(mixins):
                    action1,action2 = (lookup_action(mixin,mod,a.relname) for a in mixin.args)

        # check all the delagate declarations

        for dl in mod.delegates:
            lookup_action(dl.args[0],mod,dl.delegated())
            if dl.delegee() and dl.delegee() not in mod.hierarchy:
                raise iu.IvyError(dl.args[1],"{} is not a module instance".format(name))

        # Determine the mixin order (as a side effect on module.mixins)

        get_mixin_order(iso,mod)

        # Construct an isolate

        if iso:
            isolate_component(mod,iso)
        else:
            if mod.isolates:
                raise iu.IvyError(None,'no isolate specified on command line')
            # apply all the mixins in no particular order
            for name,mixins in mod.mixins.iteritems():
                for mixin in mixins:
                    action1,action2 = (lookup_action(mixin,mod,a.relname) for a in mixin.args)
                    mixed = ia.apply_mixin(mixin,action1,action2)
                    mod.actions[mixin.args[1].relname] = mixed
            # find the globally exported actions (all if none specified, for compat)
            if mod.exports:
                mod.public_actions.clear()
                for e in mod.exports:
                    if not e.scope(): # global export
                        mod.public_actions.add(e.exported())
            else:
                for a in mod.actions:
                    mod.public_actions.add(a)

        # Create one big external action if requested


        ext = kwargs['ext'] if 'ext' in kwargs else ext_action.get()
        if ext is not None:
            ext_acts = [mod.actions[x] for x in sorted(mod.public_actions)]
            ext_act = ia.EnvAction(*ext_acts)
            mod.public_actions.add(ext);
            mod.actions[ext] = ext_act;

        # Check native interpretations of symbols

        slv.check_compat()

        # Make concept spaces from the conjecture

        for i,cax in enumerate(mod.labeled_conjs):
            fmla = cax.formula
            csname = 'conjecture:'+ str(i)
            variables = list(lu.used_variables_ast(fmla))
            sort = ivy_logic.RelationSort([v.sort for v in variables])
            sym = ivy_logic.Symbol(csname,sort)
            space = ics.NamedSpace(ivy_logic.Literal(0,fmla))
            mod.concept_spaces.append((sym(*variables),space))

        ith.check_theory()

        if show_compiled.get():
            for x,y in mod.actions.iteritems():
                print iu.pretty("action {} = {}".format(x,y))
Beispiel #19
0
 def scenario(self, scen):
     for (s, lineno) in scen.places():
         with ASTContext(scen):
             sym = add_symbol(s, ivy_logic.RelationSort([]))
             self.domain.all_relations.append((sym, 0))
             self.domain.relations[sym] = 0