This commit is contained in:
Ken McMillan 2016-12-25 13:00:25 -08:00
Родитель 88a1c32a92
Коммит 838f35fb43
3 изменённых файлов: 59 добавлений и 3 удалений

Просмотреть файл

@ -1,7 +1,7 @@
#
# Copyright (c) Microsoft Corporation. All Rights Reserved.
#
from ivy_logic import Variable,Constant,Atom,Literal,App,sig,And,Or,Not,Implies,EnumeratedSort,Ite,Definition, is_atom, equals, Equals, Symbol,ast_match_lists, is_in_logic, Exists, RelationSort, is_boolean
from ivy_logic import Variable,Constant,Atom,Literal,App,sig,And,Or,Not,Implies,EnumeratedSort,Ite,Definition, is_atom, equals, Equals, Symbol,ast_match_lists, is_in_logic, Exists, RelationSort, is_boolean, is_app, is_eq
from ivy_logic_utils import to_clauses, formula_to_clauses, substitute_constants_clause,\
substitute_clause, substitute_ast, used_symbols_clauses, used_symbols_ast, rename_clauses, subst_both_clauses,\
@ -209,6 +209,14 @@ class Action(AST):
if hasattr(self,'formal_returns'):
res.formal_returns = self.formal_returns
return res
def unroll_loops(self,card):
args = [a.unroll_loops(card) if isinstance(a,Action) else a for a in self.args]
res = self.clone(args)
if hasattr(self,'formal_params'):
res.formal_params = self.formal_params
if hasattr(self,'formal_returns'):
res.formal_returns = self.formal_returns
return res
def iter_calls(self):
for a in self.args:
if isinstance(a,Action):
@ -725,7 +733,7 @@ class WhileAction(Action):
def decompose(self,pre,post,fail=False):
return self.expand(ivy_module.module,[]).decompose(pre,post,fail)
def assert_to_assume(self):
return self.clone(self.args[:2])
return self.clone([self.args[0],self.args[1].assert_to_assume()])
def drop_invariants(self):
res = self.clone(self.args[:2])
if hasattr(self,'formal_params'):
@ -733,6 +741,25 @@ class WhileAction(Action):
if hasattr(self,'formal_returns'):
res.formal_returns = self.formal_returns
return res
def unroll_loops(self,card):
cond = self.args[0]
if is_app(cond) and cond.rep.name in ['<','>','<=','>=']:
idx_sort = cond.args[0].sort
elif isinstance(cond,Not) and is_eq(cond.args[0]):
idx_sort = cond.args[0].args[0].sort
else:
raise IvyError(self,'cannot determine an index sort for loop')
cardsort = card(idx_sort)
if cardsort is None:
raise IvyError(self,'cannot determine an iteration bound for loop over {}'.format(idx_sort))
res = AssumeAction(Not(cond))
for idx in range(cardsort):
res = IfAction(cond,Sequence(self.args[1],res))
if hasattr(self,'formal_params'):
res.formal_params = self.formal_params
if hasattr(self,'formal_returns'):
res.formal_returns = self.formal_returns
return res

Просмотреть файл

@ -640,6 +640,9 @@ def emit_action_gen(header,impl,name,action,classname):
caname = varname(name)
if name in im.module.before_export:
action = im.module.before_export[name]
def card(sort):
return sort_card(sort)
action = action.unroll_loops(card)
upd = action.update(im.module,None)
pre = tr.reverse_image(ilu.true_clauses(),ilu.true_clauses(),upd)
pre_clauses = ilu.trim_clauses(pre)

26
test/unroll1.ivy Normal file
Просмотреть файл

@ -0,0 +1,26 @@
#lang ivy1.6
type t
relation p(X:t)
individual idx : t
action a(max:t)
object spec = {
before a {
idx := 0;
while idx < max {
assert p(idx);
idx := idx + 1
}
}
}
interpret t -> bv[2]
export a
isolate iso = this