Fba
include deduction
t.
module set(t) = {
type this
relation mem(E:t,S:this)
axiom [comp] {
relation p(X:t)
property exists S. forall E. mem(E,S) <-> p(E)
}
axiom [exten] {
property forall E. mem(E,S) <-> mem(E,T)
property S:this = T
}
individual empty : this
axiom forall E. ~mem(E,empty)
individual full : this
axiom forall E. mem(E,full)
}
type node
instance nset : set(node)
instance nsetset : set(nset)
function slices(N:node) : nsetset
relation well(N:node)
quorum a bit here. That is, quorum(Q,I)
means that Q is a quorum of the projection onto I.
Also, here and in the sequel, we expand mem(x,union(s,t)) into
mem(x,s) | mem(x,t) and so forth. This way we don't have to deal with the
union and intersection function, which create funciton cycles. The necessary
rewriting to eliminate these would be painful in Ivy.
function quorum(Q:nset,I:nset) : bool
definition {
quorum(Q:nset,I:nset) =
forall P. nset.mem(P,Q) & well(P) ->
exists Sl. nsetset.mem(Sl,slices(P))
& forall X. nset.mem(X,Sl) & nset.mem(X,I) -> nset.mem(X,Q)
}
explicit property [quorum_fwd]
quorum(Q,I) -> forall N. (
nset.mem(N,Q) & well(N) ->
exists Sl. nsetset.mem(Sl,slices(N))
& forall X. nset.mem(X,Sl) & nset.mem(X,I) -> nset.mem(X,Q))
proof {
apply introImp
apply elimIffFwd with prem1 = prem
apply quorum
}
explicit property [quorum_rev]
(forall N.
nset.mem(N,Q) & well(N) ->
exists Sl. nsetset.mem(Sl,slices(N))
& forall X. nset.mem(X,Sl) & nset.mem(X,I) -> nset.mem(X,Q))
-> quorum(Q,I)
proof {
apply introImp
apply elimIffRev with prem1 = prem
apply quorum
}
node to nset, which creates a
function cycle. Notice these proofs are quite compact, but all
of the intuition is gone.
Also, notice the the comprehension axiom schema used only once. This
is the only instance of use of a higher-order formula. The use of
the nset.comp axiom below is equivalent to saying 'let S = inta - s'.
theorem [blocking_safe] {
individual inta : nset
property [intact_wb] forall X. nset.mem(X,inta) -> well(X)
property [q_avail] quorum(inta,nset.full)
individual s : nset
individual n : node
property nset.mem(n,inta)
property forall Sl. nsetset.mem(Sl,slices(n)) -> exists X. nset.mem(X,Sl) & nset.mem(X,s)
property exists X. nset.mem(X,s) & nset.mem(X,inta)
}
proof {
instantiate quorum_fwd with Q=inta, I=nset.full, N=n
}
theorem [cascade] {
individual inta : nset
property [q_inter] forall Q1,Q2. quorum(Q1,inta) & quorum(Q2,inta)
& (exists X. nset.mem(X,Q1) & nset.mem(X,inta))
& (exists X. nset.mem(X,Q2) & nset.mem(X,inta))
-> (exists X. nset.mem(X,Q1) & nset.mem(X,Q2) & nset.mem(X,inta))
individual u : nset
individual s : nset
property quorum(u,nset.full)
property exists X. nset.mem(X,u) & nset.mem(X,inta)
property forall X. nset.mem(X,u) -> nset.mem(X,s)
property
(forall X. nset.mem(X,inta) -> nset.mem(X,s))
| exists N. nset.mem(N,inta) & ~nset.mem(N,s) &
forall Sl. nsetset.mem(Sl,slices(N)) ->
exists X. nset.mem(X,Sl) & nset.mem(X,s) & nset.mem(X,inta)
}
proof {
instantiate nset.comp with p(E) = (nset.mem(E,inta) & ~nset.mem(E,s))
tactic skolemize
instance [qr1] quorum_rev with Q=u,I=inta
instance [qr2] quorum_rev<N2/N> with Q=_S,I=inta
tactic skolemize
instantiate with N=_N2
instantiate quorum_fwd with Q=u,I=nset.full,N=_N
}
theorem [union_quorum] {
individual i1 : nset
individual i2 : nset
property [intact_wb1] forall X. nset.mem(X,i1) -> well(X)
property [q_avail1] quorum(i1,nset.full)
property [q_inter1] forall Q1,Q2. quorum(Q1,i1) & quorum(Q2,i1)
& (exists X. nset.mem(X,Q1) & nset.mem(X,i1))
& (exists X. nset.mem(X,Q2) & nset.mem(X,i1))
-> (exists X. nset.mem(X,Q1) & nset.mem(X,Q2) & nset.mem(X,i1))
property [intact_wb2] forall X. nset.mem(X,i2) -> well(X)
property [q_avail2] quorum(i2,nset.full)
property [q_inter2] forall Q1,Q2. quorum(Q1,i2) & quorum(Q2,i2)
& (exists X. nset.mem(X,Q1) & nset.mem(X,i2))
& (exists X. nset.mem(X,Q2) & nset.mem(X,i2))
-> (exists X. nset.mem(X,Q1) & nset.mem(X,Q2) & nset.mem(X,i2))
individual u : nset
property forall X. nset.mem(X,u) <-> (nset.mem(X,i1) | nset.mem(X,i2))
property quorum(u,nset.full)
}
proof {
instantiate quorum_rev with Q=u, I=nset.full
tactic skolemize
instantiate [qf1] quorum_fwd with Q=i1,I=nset.full,N=_N
instantiate [qf2] quorum_fwd with Q=i2,I=nset.full,N=_N
}
theorem [union_quorum_intersection] {
individual i1 : nset
individual i2 : nset
property exists M4. nset.mem(M4,i1) & nset.mem(M4,i2)
property [intact_wb1] forall X. nset.mem(X,i1) -> well(X)
property [q_avail1] quorum(i1,nset.full)
property [q_inter1] forall Q1,Q2. quorum(Q1,i1) & quorum(Q2,i1)
& (exists X. nset.mem(X,Q1) & nset.mem(X,i1))
& (exists X. nset.mem(X,Q2) & nset.mem(X,i1))
-> (exists X. nset.mem(X,Q1) & nset.mem(X,Q2) & nset.mem(X,i1))
property [intact_wb2] forall X. nset.mem(X,i2) -> well(X)
property [q_avail2] quorum(i2,nset.full)
property [q_inter2] forall Q1,Q2. quorum(Q1,i2) & quorum(Q2,i2)
& (exists X. nset.mem(X,Q1) & nset.mem(X,i2))
& (exists X. nset.mem(X,Q2) & nset.mem(X,i2))
-> (exists X. nset.mem(X,Q1) & nset.mem(X,Q2) & nset.mem(X,i2))
individual u : nset
property forall X. nset.mem(X,u) <-> (nset.mem(X,i1) | nset.mem(X,i2))
individual q1 : nset
individual q2 : nset
property quorum(q1,u)
property quorum(q2,u)
property exists X. nset.mem(X,q1) & nset.mem(X,u)
property exists X. nset.mem(X,q2) & nset.mem(X,u)
property exists X. nset.mem(X,q1) & nset.mem(X,q2) & nset.mem(X,u)
}
proof {
instantiate [qr1] quorum_rev<N1/N> with Q=q1, I=i1
instantiate [qr2] quorum_rev<N2/N> with Q=q1, I=i2
instantiate [qr3] quorum_rev<N3/N> with Q=q2, I=i1
instantiate [qr4] quorum_rev<N4/N> with Q=q2, I=i2
instantiate quorum_rev with Q=i2, I=i1
tactic skolemize
instantiate [qf1] quorum_fwd with Q=q1,I=u,N=_N1
instantiate [qf2] quorum_fwd with Q=q1,I=u,N=_N2
instantiate [qf3] quorum_fwd with Q=q2,I=u,N=_N3
instantiate [qf4] quorum_fwd with Q=q2,I=u,N=_N4
instantiate quorum_fwd with Q=i2,I=nset.full,N=_N
}