зеркало из https://github.com/microsoft/ivy.git
various fixes to fragment checker and interference checker
This commit is contained in:
Родитель
59f3e6cfa3
Коммит
5cc6756193
|
@ -1595,7 +1595,7 @@ def create_conj_actions(mod):
|
||||||
action_isos[action].add(ison)
|
action_isos[action].add(ison)
|
||||||
for ison,isol in mod.isolates.iteritems():
|
for ison,isol in mod.isolates.iteritems():
|
||||||
memo = set()
|
memo = set()
|
||||||
conjs = iso.get_isolate_conjs(mod,isol)
|
conjs = iso.get_isolate_conjs(mod,isol,verified=False)
|
||||||
exports = myexports[ison]
|
exports = myexports[ison]
|
||||||
roots = set(iu.reachable(exports,lambda x: cg[x]))
|
roots = set(iu.reachable(exports,lambda x: cg[x]))
|
||||||
for conj in conjs:
|
for conj in conjs:
|
||||||
|
@ -1606,7 +1606,7 @@ def create_conj_actions(mod):
|
||||||
memo.add(action)
|
memo.add(action)
|
||||||
if action in roots:
|
if action in roots:
|
||||||
for victim in exports:
|
for victim in exports:
|
||||||
if action in set(iu.reachable([victim],lambda x: cg[x])) and action != victim:
|
if victim in set(iu.reachable([action],lambda x: cg[x])) and action != victim:
|
||||||
raise IvyError(conj, "isolate {} depends on invariant {} which might not hold because action {} is called from within action {}, which invalidates the invariant.".format(ison,conj.label.rep,victim,action))
|
raise IvyError(conj, "isolate {} depends on invariant {} which might not hold because action {} is called from within action {}, which invalidates the invariant.".format(ison,conj.label.rep,victim,action))
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,7 @@ def map_fmla(lineno,fmla,pol):
|
||||||
if fmla in universally_quantified_variables:
|
if fmla in universally_quantified_variables:
|
||||||
if fmla not in strat_map:
|
if fmla not in strat_map:
|
||||||
res = UFNode()
|
res = UFNode()
|
||||||
|
res.var = fmla
|
||||||
strat_map[fmla] = res
|
strat_map[fmla] = res
|
||||||
return strat_map[fmla],set()
|
return strat_map[fmla],set()
|
||||||
node,vs = macro_var_map.get(fmla,None), macro_dep_map.get(fmla,set())
|
node,vs = macro_var_map.get(fmla,None), macro_dep_map.get(fmla,set())
|
||||||
|
@ -143,7 +144,7 @@ def map_fmla(lineno,fmla,pol):
|
||||||
anode = strat_map[(func,idx)]
|
anode = strat_map[(func,idx)]
|
||||||
if node is not None:
|
if node is not None:
|
||||||
unify(anode,node)
|
unify(anode,node)
|
||||||
arcs.extend((v,anode,fmla,lineno) for v in uvs[idx])
|
arcs.extend((v,anode,fmla,lineno,idx) for v in uvs[idx])
|
||||||
else:
|
else:
|
||||||
check_interpreted(fmla,nodes,uvs,lineno,pol)
|
check_interpreted(fmla,nodes,uvs,lineno,pol)
|
||||||
return None,all_uvs
|
return None,all_uvs
|
||||||
|
@ -284,10 +285,14 @@ def create_macro_maps(assumes,asserts,macros):
|
||||||
# equivalent to add `w -> v` to `macro_dep_map`. The following
|
# equivalent to add `w -> v` to `macro_dep_map`. The following
|
||||||
# procedure does this for a given formula.
|
# procedure does this for a given formula.
|
||||||
#
|
#
|
||||||
|
# skolem_map maps existential variables to the terms that bind them.
|
||||||
|
|
||||||
|
skolem_map = {}
|
||||||
|
|
||||||
def make_skolems(fmla,ast,pol,univs):
|
def make_skolems(fmla,ast,pol,univs):
|
||||||
global macro_dep_map
|
global macro_dep_map
|
||||||
global strat_map
|
global strat_map
|
||||||
|
global skolem_map
|
||||||
if isinstance(fmla,il.Not):
|
if isinstance(fmla,il.Not):
|
||||||
make_skolems(fmla.args[0],ast,not pol,univs)
|
make_skolems(fmla.args[0],ast,not pol,univs)
|
||||||
return
|
return
|
||||||
|
@ -302,6 +307,7 @@ def make_skolems(fmla,ast,pol,univs):
|
||||||
for u in univs:
|
for u in univs:
|
||||||
if u in fvs:
|
if u in fvs:
|
||||||
for e in il.quantifier_vars(fmla):
|
for e in il.quantifier_vars(fmla):
|
||||||
|
skolem_map[e] = (fmla,ast)
|
||||||
macro_dep_map[e].add(strat_map[u])
|
macro_dep_map[e].add(strat_map[u])
|
||||||
if is_e and not pol or is_a and pol:
|
if is_e and not pol or is_a and pol:
|
||||||
make_skolems(fmla.args[0],ast,pol,univs+list(il.quantifier_vars(fmla)))
|
make_skolems(fmla.args[0],ast,pol,univs+list(il.quantifier_vars(fmla)))
|
||||||
|
@ -391,10 +397,30 @@ def show_strat_graph(m,a):
|
||||||
def report_feu_error(text):
|
def report_feu_error(text):
|
||||||
raise iu.IvyError(None,"The verification condition is not in the fragment FAU.\n\n{}".format(text))
|
raise iu.IvyError(None,"The verification condition is not in the fragment FAU.\n\n{}".format(text))
|
||||||
|
|
||||||
|
def get_node_sort(n):
|
||||||
|
for t,m in strat_map.iteritems():
|
||||||
|
if m is n:
|
||||||
|
if isinstance(t,tuple):
|
||||||
|
return t[0].sort.dom[t[1]]
|
||||||
|
return t.sort
|
||||||
|
assert False
|
||||||
|
|
||||||
|
def report_arc(arc):
|
||||||
|
v,anode,fmla,lineno = arc[0:4]
|
||||||
|
res = '\n' + str(lineno) + str(fmla)
|
||||||
|
if len(arc) > 4:
|
||||||
|
idx = arc[4]
|
||||||
|
term = fmla.args[idx]
|
||||||
|
res += '\n (position {} is a function from '.format(idx) + str(get_node_sort(v)) + ' to ' + str(term.sort) + ')'
|
||||||
|
if term in skolem_map:
|
||||||
|
sm = skolem_map[term]
|
||||||
|
res += '\n ' + str(sm[1].lineno) + 'skolem function defined by:\n ' + str(sm[0])
|
||||||
|
return res
|
||||||
|
|
||||||
def report_cycle(cycle):
|
def report_cycle(cycle):
|
||||||
if cycle is not None:
|
if cycle is not None:
|
||||||
report_feu_error("The following terms may generate an infinite sequence of instantiations:\n"+
|
report_feu_error("The following terms may generate an infinite sequence of instantiations:\n"+
|
||||||
'\n'.join(' ' + str(arc[3]) + str(arc[2]) for arc in cycle))
|
'\n'.join(' ' + report_arc(arc) for arc in cycle))
|
||||||
|
|
||||||
def report_interp_over_var(fmla,lineno,node):
|
def report_interp_over_var(fmla,lineno,node):
|
||||||
""" Report a violation of FAU due to a universal variable
|
""" Report a violation of FAU due to a universal variable
|
||||||
|
|
|
@ -1311,7 +1311,7 @@ if not (iu.get_numeric_version() <= [1,1]):
|
||||||
return stmts[0]
|
return stmts[0]
|
||||||
else:
|
else:
|
||||||
res = Sequence(*stmts)
|
res = Sequence(*stmts)
|
||||||
res.lineno = get_lineno(p,n)
|
res.lineno = stmts[0].lineno # get_lineno(p,n)
|
||||||
return res
|
return res
|
||||||
def p_top_around_callatom_lcb_action_rcb(p):
|
def p_top_around_callatom_lcb_action_rcb(p):
|
||||||
'top : top AROUND atype optargs optreturns LCB actseq optsemi DOTDOTDOT actseq optsemi RCB'
|
'top : top AROUND atype optargs optreturns LCB actseq optsemi DOTDOTDOT actseq optsemi RCB'
|
||||||
|
@ -2043,7 +2043,7 @@ if not (iu.get_numeric_version() <= [1,5]):
|
||||||
def p_action_var_opttypedsym_assign_fmla(p):
|
def p_action_var_opttypedsym_assign_fmla(p):
|
||||||
'action : VAR opttypedsym optinit'
|
'action : VAR opttypedsym optinit'
|
||||||
p[0] = VarAction(p[2],p[3]) if p[3] is not None else VarAction(p[2])
|
p[0] = VarAction(p[2],p[3]) if p[3] is not None else VarAction(p[2])
|
||||||
p[0].lineno = get_lineno(p,2)
|
p[0].lineno = get_lineno(p,1)
|
||||||
|
|
||||||
def p_eqn_SYMBOL_EQ_SYMBOL(p):
|
def p_eqn_SYMBOL_EQ_SYMBOL(p):
|
||||||
'eqn : SYMBOL EQ SYMBOL'
|
'eqn : SYMBOL EQ SYMBOL'
|
||||||
|
|
|
@ -475,10 +475,10 @@ def cycle(arcs,first=lambda x:x[0],second=lambda x:x[1]):
|
||||||
if dfs(first(arc)):
|
if dfs(first(arc)):
|
||||||
end = second(path[0])
|
end = second(path[0])
|
||||||
fpath = []
|
fpath = []
|
||||||
for arc in reversed(path):
|
for arc in path:
|
||||||
fpath.append(arc)
|
fpath.append(arc)
|
||||||
if first(arc) == end:
|
if first(arc) == end:
|
||||||
return fpath
|
return reversed(fpath)
|
||||||
assert False
|
assert False
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче