pulled out boilerplate into std

This commit is contained in:
Ken McMillan 2016-07-05 18:41:42 -07:00
Родитель 3d26332337
Коммит c72c8ccd18
3 изменённых файлов: 147 добавлений и 126 удалений

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

@ -12,6 +12,8 @@
## Forgot to include seq_nums object in iso_n
include std
################################################################################
#
# This is the abstract specification of the sharded hash table protocol. It defines
@ -26,65 +28,21 @@
#
################################################################################
########################################
# total order theory
module total_order(carrier) = {
relation (T:carrier < U:carrier)
# note: because < is polymorphic, we need to use the type here
axiom (T:carrier < U & U < V) -> (T < V)
axiom ~(T:carrier < U & U < T)
axiom T:carrier < U | T = U | U < T
# could add <= as derived relation here
}
module total_non_strict_order(carrier) = {
relation (T:carrier <= U:carrier)
# note: because <= is polymorphic, we need to use the type here
axiom (T:carrier <= U & U <= V) -> (T <= V)
axiom T:carrier <= T
axiom (T:carrier <= U & U <= T) -> T = U
axiom T:carrier <= U | U <= T
# could add <= as derived relation here
}
########################################
# Maps. This module provides a relational model of a map from a type
# dom to a type rng. Initially, everything is mapped to the element zero.
module map(dom,rng,zero) = {
relation map(X:dom,Y:rng)
init map(X,Y) <-> Y = zero
action set_(x:dom,y:rng) = {
local oldval:rng {
assume map(x,oldval)
};
map(x,Y) := Y = y
}
action set_closed_interval(lo:dom,hi:dom,val:rng) = {
# map(X,Y) := (Y = val) if lo <= X & X <= hi else map(X,Y)
map(X,Y) := (Y = val) & lo <= X & X <= hi
| map(X,Y) & ~(lo <= X & X <= hi)
}
action get(x:dom) returns (y:rng) = {
assume map(x,y)
}
conjecture map(K,L) & map(K,M) -> L = M
}
########################################
# type of local time
type ltime
instantiate total_order(ltime)
########################################
# type of hash table data
type data
########################################
# type of hash table keys
type key
instantiate total_non_strict_order(key)
@ -102,14 +60,17 @@ axiom 0 <= K:key
########################################
# type of message types
type mtype = {request_t, reply_t, delegate_t, ack_t}
########################################
# type of hash table ops
type otype = {read, write}
########################################
# id's of protocol agents
type id
########################################
@ -182,7 +143,6 @@ object reference = {
########################################
# memory events by local time
# TODO: can we export this read-only?
instantiate evs(T:ltime) : hashev
@ -294,67 +254,6 @@ module delegation_map_spec = {
}
################################################################################
#
# Ordered set representation
#
# This is intended to be implemented using the STL set template.
#
# Ordered sets assume the element type has a total non-strict order,
# with a least element 0. They provide insertion of elements (in log
# time), deletion of ranges (in n log(n) time) and finding greatest
# lower bounds (log n).
#
# For help with proofs, this module also provides an auxiliary map
# "succ" that gives the successor of every element in the set.
module ordered_set(key) = {
relation s(K:key)
init s(K) <-> K = 0
instantiate succ : map(key,key,0) # ghost
# insert one element
action insert(nkey:key) = {
s(nkey) := true;
# following is ghost code to update the successor relation
local v:key {
if some lub:key. ~(lub <= nkey) & s(lub) minimizing lub {
v := lub
}
else {
v := 0
};
call succ.set_(nkey,v)
};
if some glb:key. ~(nkey <= glb) & s(glb) maximizing glb {
local the_succ:key, succ_val:id {
the_succ := succ.get(glb) # lemma
};
call succ.set_(glb,nkey)
}
}
# erase elements in a closed interval
action erase(lo:key,hi:key) = {
s(K) := s(K) & ~(lo <= K & K <= hi)
}
# the the greatest element <= k
action get_glb(k:key) returns (res:key) = {
if some glb:key. glb <= k & s(glb) maximizing glb {
local the_succ:key, succ_val:id {
the_succ := succ.get(glb) # lemma
};
res := glb
}
}
conjecture s(K) & succ.map(K,L) & L ~= 0 -> ~(L <= K) & s(L)
conjecture s(K) & succ.map(K,L) & ~(M <= K) & (L = 0 | ~(L <= M)) -> ~s(M)
}
################################################################################
#
@ -379,7 +278,7 @@ module delegation_map() = {
};
call has.erase(lo,hi);
entries(lo) := dst;
call has.insert(lo) #ghost
call has.insert(lo)
}
}
@ -387,7 +286,12 @@ module delegation_map() = {
val := entries(has.get_glb(k))
}
# The value of every key between K and its successor is the same as K's value.
conjecture has.s(K) & has.succ.map(K,L) & K <= M & (L = 0 | ~(L <= M)) -> dma.map(me,M,entries(K))
# We always have an entry for key zero.
conjecture has.s(0)
}

133
examples/sht/std.ivy Normal file
Просмотреть файл

@ -0,0 +1,133 @@
#lang ivy1.5
# This is a start on a "standard library" for Ivy
################################################################################
# Total order theories
module total_order(carrier) = {
relation (T:carrier < U:carrier)
# note: because < is polymorphic, we need to use the type here
axiom (T:carrier < U & U < V) -> (T < V)
axiom ~(T:carrier < U & U < T)
axiom T:carrier < U | T = U | U < T
}
module total_non_strict_order(carrier) = {
relation (T:carrier <= U:carrier)
# note: because <= is polymorphic, we need to use the type here
axiom (T:carrier <= U & U <= V) -> (T <= V)
axiom T:carrier <= T
axiom (T:carrier <= U & U <= T) -> T = U
axiom T:carrier <= U | U <= T
}
################################################################################
#
# Maps.
#
# This module provides a relational model of a function from a type
# dom to a type rng. Initially, everything is mapped to the element zero.
#
# The key invariant of a map is that it is a function, i.e., for every
# X there exists a Y such that map(X,Y). The module does not state
# this invariant, however, since the quantifier alternation could
# destroy stratificaiton. Instead it provides a "lemma" that allows
# the user to instantiate Y for particular values of X.
#
# Parameters:
#
# dom The domain type
# rng The range type
# zero The initial value for every domain element
module map(dom,rng,zero) = {
relation map(X:dom,Y:rng)
init map(X,Y) <-> Y = zero
# set the value of x to y
action set_(x:dom,y:rng) = {
local oldval:rng {
assume map(x,oldval)
};
map(x,Y) := Y = y
}
# get the value of x
action get(x:dom) returns (y:rng) = {
assume map(x,y)
}
# prove there exists a value for x
action lemma(x:dom) = {
assume exists Y. map(x,Y)
}
conjecture map(K,L) & map(K,M) -> L = M
}
################################################################################
#
# Ordered set representation
#
# This is intended to be implemented using the STL set template.
#
# Ordered sets assume the element type has a total non-strict order,
# with a least element 0. They provide insertion of elements (in log
# time), deletion of ranges (in n log(n) time) and finding greatest
# lower bounds (log n).
#
# For help with proofs, this module also provides an auxiliary map
# "succ" that gives the successor of every element in the set. The
# "successor" of the maximal element in the set is 0.
module ordered_set(key) = {
relation s(K:key)
init s(K) <-> K = 0
instantiate succ : map(key,key,0) # ghost
# insert one element
action insert(nkey:key) = {
s(nkey) := true;
# following is ghost code to update the successor relation
local v:key {
if some lub:key. ~(lub <= nkey) & s(lub) minimizing lub {
v := lub
}
else {
v := 0
};
call succ.set_(nkey,v)
};
if some glb:key. ~(nkey <= glb) & s(glb) maximizing glb {
call succ.lemma(glb); # instantiate succ(glb)
call succ.set_(glb,nkey)
}
}
# erase elements in a closed interval
action erase(lo:key,hi:key) = {
s(K) := s(K) & ~(lo <= K & K <= hi)
}
# the the greatest element <= k
action get_glb(k:key) returns (res:key) = {
if some glb:key. glb <= k & s(glb) maximizing glb {
call succ.lemma(glb); # instantiate succ(glb)
res := glb
}
}
# Useful invariants of the "succ" relation. The successor of K is
# also in the set, and nothing between K and its successor is in
# the set. Here, if L = 0 it means K is the maximim element, so we
# have to treat this as a special case.
conjecture s(K) & succ.map(K,L) & L ~= 0 -> ~(L <= K) & s(L)
conjecture s(K) & succ.map(K,L) & ~(M <= K) & (L = 0 | ~(L <= M)) -> ~s(M)
}

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

@ -161,10 +161,6 @@ def get_strip_params(name,args,strip_map,strip_binding,ast):
raise iu.IvyError(ast,"cannot strip isolate parameters from {}".format(name))
for sp,ap in zip(strip_params,args):
if ap not in strip_binding or strip_binding[ap] != sp:
iu.dbg('ast')
iu.dbg('strip_binding')
iu.dbg('sp')
iu.dbg('ap')
raise iu.IvyError(ast,"cannot strip parameter {} from {}".format(ap,name))
return strip_params
@ -194,10 +190,6 @@ def strip_action(ast,strip_map,strip_binding):
new_sort = strip_sort(ast.rep.sort,strip_params)
new_args = args[len(strip_params):]
new_symbol = ivy_logic.Symbol(name,new_sort)
iu.dbg('new_sort')
iu.dbg('new_sort.dom')
iu.dbg('new_args')
iu.dbg('new_symbol')
return new_symbol(*new_args)
return ast.clone(args)
@ -217,7 +209,6 @@ def strip_labeled_fmla(lfmla,strip_map):
fmla = lfmla.formula
strip_binding = {}
get_strip_binding(fmla,strip_map,strip_binding)
iu.dbg('strip_binding')
fmla = strip_action(fmla,strip_map,strip_binding)
lbl = lfmla.label
if lbl:
@ -234,8 +225,6 @@ def strip_isolate(mod,isolate):
for atom in isolate.verified() + isolate.present():
name = atom.relname
if atom.args:
for a in atom.args:
print type(a)
if not all(isinstance(v,ivy_ast.App) and not v.args for v in atom.args):
raise iu.IvyError(atom,"bad isolate parameter")
for a in atom.args:
@ -245,10 +234,7 @@ def strip_isolate(mod,isolate):
# strip the actions
new_actions = {}
for name,action in mod.actions.iteritems():
iu.dbg('name')
iu.dbg('action')
strip_params = strip_map_lookup(name[4:] if name.startswith('ext:') else name,strip_map)
iu.dbg('strip_params')
if not(len(action.formal_params) >= len(strip_params)):
raise iu.IvyError(action,"cannot strip isolate parameters from {}".format(name))
strip_binding = dict(zip(action.formal_params,strip_params))
@ -256,7 +242,6 @@ def strip_isolate(mod,isolate):
new_action.formal_params = action.formal_params[len(strip_params):]
new_action.formal_returns = action.formal_returns
new_actions[name] = new_action
iu.dbg('new_action')
mod.actions.clear()
mod.actions.update(new_actions)
@ -273,7 +258,6 @@ def strip_isolate(mod,isolate):
new_sort = strip_sort(sym.sort,strip_params)
sym = ivy_logic.Symbol(name,new_sort)
new_symbols[name] = sym
iu.dbg('sym')
ivy_logic.sig.symbols.clear()
ivy_logic.sig.symbols.update(new_symbols)