various fixes to fragment checker and interference checker

This commit is contained in:
Ken McMillan 2018-10-31 12:24:51 -07:00
Родитель 59f3e6cfa3
Коммит 5cc6756193
4 изменённых файлов: 34 добавлений и 8 удалений

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

@ -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