def methoddecl(d): global context dm,im = context.dm,context.im symbol,args,returns,requires,modifies,ensures,decreases,stmts = d.args nmap = dict() inps = [make_arg(a,symbol,nmap) for a in args] outs = [make_arg(a,symbol,nmap) for a in returns] if returns else [] # do the copying for call-by-value ma = [ip.App('__arg'+str(i)) for i in range(0,len(inps))] pa = [ip.App(a.rep) for a in inps] pad = [ip.App(make_dummy('cbv:',a).rep) for a in inps] mb = [ip.AssignAction(a,b) for a,b in zip(pad,ma)] mr = [ip.App('__arg'+str(i)) for i in range(len(inps),len(inps)+len(outs))] pr = [ip.App(a.rep) for a in outs] prd = [ip.App(make_dummy('cbv:',a).rep) for a in outs] ca = ip.CallAction(ip.Atom(symbol.rep,[])) mb += [ip.LetAction(*([ip.Atom('=',[x,y]) for x,y in zip(pa+pr,pad+prd)] + [ca]))] mb += [ip.AssignAction(b,a) for a,b in zip(prd,mr)] ls = [s.rep for s in (pad+prd)] mb = ip.LocalAction(*(ls+[ip.Sequence(*mb)])) # rename all the parameters ds = d.subst_symbols(nmap) symbol,args,returns,requires,modifies,ensures,decreases,stmts = ds.args # translate the spec modifies = ([ip.Atom(s.rep,[]) for s in modifies] + pr) if modifies != None else pr # output an action with MethodContext(symbol.rep, modifies, returns): body = block(stmts) decl = ip.ActionDecl(ip.ActionDef(symbol.rep,body)) im.declare(decl) # output a macro for call-by value df = ip.Definition(ip.Atom('cbv:'+symbol.rep,ma+mr),mb) im.declare(ip.MacroDecl(df)) im.macros[df.defines()] = df # output a specification # if ensures or modifies or requires: # requires = lut.rename_ast(requires,dict((inp.rep,tr.old(inp.rep)) for inp in inps)) ensures = ensures.to_ivy() if ensures else ip.And() requires = requires.to_ivy() if requires else ip.And() spec = ip.RME(requires,modifies,ensures) thing = ip.Implies(ip.Atom(symbol.rep,[]),spec) decl = ip.AssertDecl(thing) if hasattr(d,'lineno'): thing.lineno = d.lineno im.declare(decl)
def call(c): sym = c.args[0] args = [a.to_ivy() for a in c.args[1:]] ret_type = expect_return_vals(sym,1,c) retval = make_temp(ret_type[0]) atom = ip.Atom('cbv:'+sym.rep, args + [retval]) expr_context.code.append(ip.InstantiateAction(atom)) return retval
def whilestmt(s): global context dm,im = context.dm,context.im cond,mods,inv,body = s.args lineno = s.lineno cond,inv = cond.to_ivy(),(inv.to_ivy() if inv else ip.And()) body = ip.Sequence(ip.AssumeAction(cond),block(body)) mods = get_while_modset(mods) name = method_context.rn('while') body_name = name + '_body' act_decl = ip.ActionDecl(ip.ActionDef(body_name,body)) im.declare(act_decl) # df = ip.Or(ip.entry(),ip.Atom(body_name,[ip.Atom(name,[])])) df = ip.Atom(body_name,[ip.Atom(name,[])]) state_decl = ip.StateDecl(ip.StateDef(name,df)) im.declare(state_decl) ass_decl = ip.AssertDecl(ip.Implies(ip.Atom(name,[]),ip.RME(inv,mods,inv))) ass_decl.args[0].lineno = lineno im.declare(ass_decl) return ip.Sequence(ip.CallAction(ip.Atom(name,[])),ip.AssumeAction(ip.Not(cond)))
def vardecl(d): global context dm,im = context.dm,context.im for a in d.args: t = a._type if t.rep == 'bool': decl = ip.RelationDecl(ip.Atom(a.rep,[])) elif t.rep == 'object': decl = ip.ConstantDecl(ip.App(a.rep)) else: thing = ip.App(a.rep) thing.sort = t.rep decl = ip.ConstantDecl(thing) im.declare(decl)
def make_app(symbol,*args): if hasattr(symbol,'_type') and symbol._type.rep == 'bool': return ip.Atom(symbol.rep,args) return ip.App(symbol.rep,*args)
def get_while_modset(mods): if mods: return [ip.Atom(s.to_ivy([]).rep,[]) for s in mods] elif method_context.modifies: return method_context.modifies + [ip.Atom(y.rep,[]) for x,y in scope_context.locals.iteritems()] return None