Add more formula families to genltl.
* src/ltltest/genltl.cc (fair_response, ltl_counter) (ltl_counter_carry): New functions, constructing function from gastin.03.cav and rozier.07.cav. The LTL counter will replace the scripts in src/tgbatest/ltlcounter/. (X_n): New helper function.
This commit is contained in:
parent
67ff9f203f
commit
625b9362c8
2 changed files with 318 additions and 30 deletions
10
ChangeLog
10
ChangeLog
|
|
@ -1,3 +1,13 @@
|
||||||
|
2011-06-06 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
|
Add more formula families to genltl.
|
||||||
|
|
||||||
|
* src/ltltest/genltl.cc (fair_response, ltl_counter)
|
||||||
|
(ltl_counter_carry): New functions, constructing function from
|
||||||
|
gastin.03.cav and rozier.07.cav. The LTL counter will replace the
|
||||||
|
scripts in src/tgbatest/ltlcounter/.
|
||||||
|
(X_n): New helper function.
|
||||||
|
|
||||||
2011-06-03 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
2011-06-03 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
Install a misc/_config.h to hide all the defines that clutter the
|
Install a misc/_config.h to hide all the defines that clutter the
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,23 @@ using namespace spot::ltl;
|
||||||
|
|
||||||
environment& env(default_environment::instance());
|
environment& env(default_environment::instance());
|
||||||
|
|
||||||
// The five first classes defined here come from the following paper:
|
#define G_(x) spot::ltl::unop::instance(spot::ltl::unop::G, (x))
|
||||||
|
#define F_(x) spot::ltl::unop::instance(spot::ltl::unop::F, (x))
|
||||||
|
#define X_(x) spot::ltl::unop::instance(spot::ltl::unop::X, (x))
|
||||||
|
#define Not_(x) spot::ltl::unop::instance(spot::ltl::unop::Not, (x))
|
||||||
|
#define Implies_(x, y) \
|
||||||
|
spot::ltl::binop::instance(spot::ltl::binop::Implies, (x), (y))
|
||||||
|
#define Equiv_(x, y) \
|
||||||
|
spot::ltl::binop::instance(spot::ltl::binop::Equiv, (x), (y))
|
||||||
|
#define And_(x, y) \
|
||||||
|
spot::ltl::multop::instance(spot::ltl::multop::And, (x), (y))
|
||||||
|
#define Or_(x, y) \
|
||||||
|
spot::ltl::multop::instance(spot::ltl::multop::Or, (x), (y))
|
||||||
|
#define U_(x, y) \
|
||||||
|
spot::ltl::binop::instance(spot::ltl::binop::U, (x), (y))
|
||||||
|
|
||||||
|
|
||||||
|
// The five first families defined here come from the following paper:
|
||||||
//
|
//
|
||||||
// @InProceedings{cichon.09.depcos,
|
// @InProceedings{cichon.09.depcos,
|
||||||
// author = {Jacek Cicho{\'n} and Adam Czubak and Andrzej Jasi{\'n}ski},
|
// author = {Jacek Cicho{\'n} and Adam Czubak and Andrzej Jasi{\'n}ski},
|
||||||
|
|
@ -46,7 +62,7 @@ environment& env(default_environment::instance());
|
||||||
// publisher = {IEEE Computer Society},
|
// publisher = {IEEE Computer Society},
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Classes 6-9 and 12-14 where used in
|
// Families 6-9 and 12-14 were used in:
|
||||||
//
|
//
|
||||||
// @InProceedings{geldenhuys.06.spin,
|
// @InProceedings{geldenhuys.06.spin,
|
||||||
// author = {Jaco Geldenhuys and Henri Hansen},
|
// author = {Jaco Geldenhuys and Henri Hansen},
|
||||||
|
|
@ -58,6 +74,36 @@ environment& env(default_environment::instance());
|
||||||
// volume = {3925},
|
// volume = {3925},
|
||||||
// publisher = {Springer}
|
// publisher = {Springer}
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// Family 16 comes from:
|
||||||
|
//
|
||||||
|
// @InProceedings{gastin.01.cav,
|
||||||
|
// author = {Paul Gastin and Denis Oddoux},
|
||||||
|
// title = {Fast {LTL} to {B\"u}chi Automata Translation},
|
||||||
|
// booktitle = {Proceedings of the 13th International Conference on
|
||||||
|
// Computer Aided Verification (CAV'01)},
|
||||||
|
// pages = {53--65},
|
||||||
|
// year = 2001,
|
||||||
|
// editor = {G. Berry and H. Comon and A. Finkel},
|
||||||
|
// volume = {2102},
|
||||||
|
// series = {Lecture Notes in Computer Science},
|
||||||
|
// address = {Paris, France},
|
||||||
|
// publisher = {Springer-Verlag}
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Families 17-20 come from:
|
||||||
|
//
|
||||||
|
// @InProceedings{rozier.07.spin,
|
||||||
|
// author = {Kristin Y. Rozier and Moshe Y. Vardi},
|
||||||
|
// title = {LTL Satisfiability Checking},
|
||||||
|
// booktitle = {Proceedings of the 12th International SPIN Workshop on
|
||||||
|
// Model Checking of Software (SPIN'07)},
|
||||||
|
// pages = {149--167},
|
||||||
|
// year = {2007},
|
||||||
|
// volume = {4595},
|
||||||
|
// series = {Lecture Notes in Computer Science},
|
||||||
|
// publisher = {Springer-Verlag}
|
||||||
|
// }
|
||||||
|
|
||||||
void
|
void
|
||||||
syntax(char* prog)
|
syntax(char* prog)
|
||||||
|
|
@ -69,7 +115,7 @@ syntax(char* prog)
|
||||||
<< "F specifies the familly of LTL formula to build" << std::endl
|
<< "F specifies the familly of LTL formula to build" << std::endl
|
||||||
<< "N is the size parameter of the familly" << std::endl
|
<< "N is the size parameter of the familly" << std::endl
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< "Classes available (F):" << std::endl
|
<< "Available families (F):" << std::endl
|
||||||
<< " 1: F(p1&F(p2&F(p3&...F(pn)))) & F(q1&F(q2&F(q3&...F(qn))))"
|
<< " 1: F(p1&F(p2&F(p3&...F(pn)))) & F(q1&F(q2&F(q3&...F(qn))))"
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " 2: F(p&X(p&X(p&...X(p)))) & F(q&X(q&X(q&...X(q))))" << std::endl
|
<< " 2: F(p&X(p&X(p&...X(p)))) & F(q&X(q&X(q&...X(q))))" << std::endl
|
||||||
|
|
@ -87,7 +133,12 @@ syntax(char* prog)
|
||||||
<< std::endl
|
<< std::endl
|
||||||
<< " 13: (F(p1)|G(p2))&(F(p2)|G(p3))&...&(F(pn)|G(p{n+1}))" << std::endl
|
<< " 13: (F(p1)|G(p2))&(F(p2)|G(p3))&...&(F(pn)|G(p{n+1}))" << std::endl
|
||||||
<< " 14: G(p1)|G(p2)|...|G(pn)" << std::endl
|
<< " 14: G(p1)|G(p2)|...|G(pn)" << std::endl
|
||||||
<< " 15: F(p1)&F(p2)&...&F(pn)" << std::endl;
|
<< " 15: F(p1)&F(p2)&...&F(pn)" << std::endl
|
||||||
|
<< " 16: !((GF(p1)&GF(p2)&...&GF(pn))->G(q -> F(r)))" << std::endl
|
||||||
|
<< " 17: LTLcounter(n)" << std::endl
|
||||||
|
<< " 18: LTLcounterLinear(n)" << std::endl
|
||||||
|
<< " 19: LTLcounterCarry(n)" << std::endl
|
||||||
|
<< " 20: LTLcounterCarryLinear(n)" << std::endl;
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -119,10 +170,10 @@ formula* E_n(std::string name, int n)
|
||||||
p << name << n;
|
p << name << n;
|
||||||
formula* f = env.require(p.str());
|
formula* f = env.require(p.str());
|
||||||
if (result)
|
if (result)
|
||||||
result = multop::instance(multop::And, f, result);
|
result = And_(f, result);
|
||||||
else
|
else
|
||||||
result = f;
|
result = f;
|
||||||
result = unop::instance(unop::F, result);
|
result = F_(result);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -138,9 +189,7 @@ formula* phi_n(std::string name, int n)
|
||||||
for (; n > 0; --n)
|
for (; n > 0; --n)
|
||||||
{
|
{
|
||||||
if (result)
|
if (result)
|
||||||
result =
|
result = And_(p->clone(), X_(result));
|
||||||
multop::instance(multop::And, p->clone(),
|
|
||||||
unop::instance(unop::X, result));
|
|
||||||
else
|
else
|
||||||
result = p;
|
result = p;
|
||||||
}
|
}
|
||||||
|
|
@ -164,8 +213,8 @@ formula* phi_prime_n(std::string name, int n)
|
||||||
{
|
{
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
p = unop::instance(unop::X, p->clone());
|
p = X_(p->clone());
|
||||||
result = multop::instance(multop::And, result, p);
|
result = And_(result, p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -177,7 +226,7 @@ formula* phi_prime_n(std::string name, int n)
|
||||||
|
|
||||||
formula* N_prime_n(std::string name, int n)
|
formula* N_prime_n(std::string name, int n)
|
||||||
{
|
{
|
||||||
return unop::instance(unop::F, phi_prime_n(name, n));
|
return F_(phi_prime_n(name, n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -196,9 +245,7 @@ formula* GF_n(std::string name, int n, bool conj = true)
|
||||||
{
|
{
|
||||||
std::ostringstream p;
|
std::ostringstream p;
|
||||||
p << name << i;
|
p << name << i;
|
||||||
formula* f = unop::instance(unop::G,
|
formula* f = G_(F_(env.require(p.str())));
|
||||||
unop::instance(unop::F,
|
|
||||||
env.require(p.str())));
|
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
result = multop::instance(op, f, result);
|
result = multop::instance(op, f, result);
|
||||||
|
|
@ -223,9 +270,7 @@ formula* FG_n(std::string name, int n, bool conj = false)
|
||||||
{
|
{
|
||||||
std::ostringstream p;
|
std::ostringstream p;
|
||||||
p << name << i;
|
p << name << i;
|
||||||
formula* f = unop::instance(unop::F,
|
formula* f = F_(G_(env.require(p.str())));
|
||||||
unop::instance(unop::G,
|
|
||||||
env.require(p.str())));
|
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
result = multop::instance(op, f, result);
|
result = multop::instance(op, f, result);
|
||||||
|
|
@ -281,21 +326,17 @@ formula* R_n(std::string name, int n)
|
||||||
|
|
||||||
for (int i = 1; i <= n; ++i)
|
for (int i = 1; i <= n; ++i)
|
||||||
{
|
{
|
||||||
formula* gf = unop::instance(unop::G,
|
formula* gf = G_(F_(pi));
|
||||||
unop::instance(unop::F,
|
|
||||||
pi));
|
|
||||||
std::ostringstream p;
|
std::ostringstream p;
|
||||||
p << name << i + 1;
|
p << name << i + 1;
|
||||||
pi = env.require(p.str());
|
pi = env.require(p.str());
|
||||||
|
|
||||||
formula* fg = unop::instance(unop::F,
|
formula* fg = G_(F_(pi->clone()));
|
||||||
unop::instance(unop::G,
|
|
||||||
pi->clone()));
|
|
||||||
|
|
||||||
formula* f = multop::instance(multop::Or, gf, fg);
|
formula* f = Or_(gf, fg);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
result = multop::instance(multop::And, f, result);
|
result = And_(f, result);
|
||||||
else
|
else
|
||||||
result = f;
|
result = f;
|
||||||
}
|
}
|
||||||
|
|
@ -321,18 +362,18 @@ formula* Q_n(std::string name, int n)
|
||||||
|
|
||||||
for (int i = 1; i <= n; ++i)
|
for (int i = 1; i <= n; ++i)
|
||||||
{
|
{
|
||||||
formula* f = unop::instance(unop::F, pi);
|
formula* f = F_(pi);
|
||||||
|
|
||||||
std::ostringstream p;
|
std::ostringstream p;
|
||||||
p << name << i + 1;
|
p << name << i + 1;
|
||||||
pi = env.require(p.str());
|
pi = env.require(p.str());
|
||||||
|
|
||||||
formula* g = unop::instance(unop::G, pi->clone());
|
formula* g = G_(pi->clone());
|
||||||
|
|
||||||
f = multop::instance(multop::Or, f, g);
|
f = Or_(f, g);
|
||||||
|
|
||||||
if (result)
|
if (result)
|
||||||
result = multop::instance(multop::And, f, result);
|
result = And_(f, result);
|
||||||
else
|
else
|
||||||
result = f;
|
result = f;
|
||||||
}
|
}
|
||||||
|
|
@ -366,6 +407,226 @@ formula* combunop_n(std::string name, int n,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// !((GF(p1)&GF(p2)&...&GF(pn))->G(q -> F(r)))
|
||||||
|
// From "Fast LTL to Büchi Automata Translation" [gastin.01.cav]
|
||||||
|
formula* fair_response(std::string p, std::string q, std::string r, int n)
|
||||||
|
{
|
||||||
|
formula* fair = GF_n("p", n);
|
||||||
|
formula* resp = G_(Implies_(env.require(q), F_(env.require(r))));
|
||||||
|
return Not_(Implies_(fair, resp));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Builds X(X(...X(p))) with n occurrences of X.
|
||||||
|
formula* X_n(formula* p, int n)
|
||||||
|
{
|
||||||
|
assert(n > 0);
|
||||||
|
formula* res = p;
|
||||||
|
while (n--)
|
||||||
|
res = X_(res);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on LTLcounter.pl from Kristin Rozier.
|
||||||
|
// http://shemesh.larc.nasa.gov/people/kyr/benchmarking_scripts/
|
||||||
|
|
||||||
|
formula* ltl_counter(std::string bit, std::string marker, int n, bool linear)
|
||||||
|
{
|
||||||
|
formula* b = env.require(bit);
|
||||||
|
formula* neg_b = Not_(b);
|
||||||
|
formula* m = env.require(marker);
|
||||||
|
formula* neg_m = Not_(m); // to destroy
|
||||||
|
|
||||||
|
multop::vec* res = new multop::vec(4);
|
||||||
|
|
||||||
|
// The marker starts with "1", followed by n-1 "0", then "1" again,
|
||||||
|
// n-1 "0", etc.
|
||||||
|
if (!linear)
|
||||||
|
{
|
||||||
|
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
|
||||||
|
multop::vec* v = new multop::vec(n);
|
||||||
|
for (int i = 0; i + 1 < n; ++i)
|
||||||
|
(*v)[i] = X_n(neg_m->clone(), i + 1);
|
||||||
|
(*v)[n - 1] = X_n(m->clone(), n);
|
||||||
|
(*res)[0] = And_(m->clone(),
|
||||||
|
G_(Implies_(m->clone(),
|
||||||
|
multop::instance(multop::And, v))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
|
||||||
|
formula* p = m->clone();
|
||||||
|
for (int i = n - 1; i > 0; --i)
|
||||||
|
p = And_(neg_m->clone(), X_(p));
|
||||||
|
(*res)[0] = And_(m->clone(),
|
||||||
|
G_(Implies_(m->clone(), X_(p))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// All bits are initially zero.
|
||||||
|
if (!linear)
|
||||||
|
{
|
||||||
|
// !b & X(!b) & XX(!b) [if n = 3]
|
||||||
|
multop::vec* v2 = new multop::vec(n);
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
(*v2)[i] = X_n(neg_b->clone(), i);
|
||||||
|
(*res)[1] = multop::instance(multop::And, v2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// !b & X(!b & X(!b)) [if n = 3]
|
||||||
|
formula* p = neg_b->clone();
|
||||||
|
for (int i = n - 1; i > 0; --i)
|
||||||
|
p = And_(neg_b->clone(), X_(p));
|
||||||
|
(*res)[1] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define AndX_(x, y) (linear ? X_(And_((x), (y))) : And_(X_(x), X_(y)))
|
||||||
|
|
||||||
|
// If the least significant bit is 0, it will be 1 at the next time,
|
||||||
|
// and other bits stay the same.
|
||||||
|
formula* Xnm1_b = X_n(b->clone(), n - 1);
|
||||||
|
formula* Xn_b = X_(Xnm1_b); // to destroy
|
||||||
|
(*res)[2] =
|
||||||
|
G_(Implies_(And_(m->clone(), neg_b->clone()),
|
||||||
|
AndX_(Xnm1_b->clone(), U_(And_(Not_(m->clone()),
|
||||||
|
Equiv_(b->clone(),
|
||||||
|
Xn_b->clone())),
|
||||||
|
m->clone()))));
|
||||||
|
|
||||||
|
// From the least significant bit to the first 0, all the bits
|
||||||
|
// are flipped on the next value. Remaining bits are identical.
|
||||||
|
formula* Xnm1_negb = X_n(neg_b, n - 1);
|
||||||
|
formula* Xn_negb = X_(Xnm1_negb); // to destroy
|
||||||
|
(*res)[3] =
|
||||||
|
G_(Implies_(And_(m->clone(), b->clone()),
|
||||||
|
AndX_(Xnm1_negb->clone(),
|
||||||
|
U_(And_(And_(b->clone(), neg_m->clone()),
|
||||||
|
Xn_negb->clone()),
|
||||||
|
Or_(m->clone(),
|
||||||
|
And_(And_(neg_m->clone(),
|
||||||
|
neg_b->clone()),
|
||||||
|
AndX_(Xnm1_b->clone(),
|
||||||
|
U_(And_(neg_m->clone(),
|
||||||
|
Equiv_(b->clone(),
|
||||||
|
Xn_b->clone())),
|
||||||
|
m->clone()))))))));
|
||||||
|
neg_m->destroy();
|
||||||
|
Xn_b->destroy();
|
||||||
|
Xn_negb->destroy();
|
||||||
|
|
||||||
|
return multop::instance(multop::And, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
formula* ltl_counter_carry(std::string bit, std::string marker,
|
||||||
|
std::string carry, int n, bool linear)
|
||||||
|
{
|
||||||
|
formula* b = env.require(bit);
|
||||||
|
formula* neg_b = Not_(b);
|
||||||
|
formula* m = env.require(marker);
|
||||||
|
formula* neg_m = Not_(m); // to destroy
|
||||||
|
formula* c = env.require(carry);
|
||||||
|
formula* neg_c = Not_(c); // to destroy
|
||||||
|
|
||||||
|
multop::vec* res = new multop::vec(6);
|
||||||
|
|
||||||
|
// The marker starts with "1", followed by n-1 "0", then "1" again,
|
||||||
|
// n-1 "0", etc.
|
||||||
|
if (!linear)
|
||||||
|
{
|
||||||
|
// G(m -> X(!m)&XX(!m)&XXX(m)) [if n = 3]
|
||||||
|
multop::vec* v = new multop::vec(n);
|
||||||
|
for (int i = 0; i + 1 < n; ++i)
|
||||||
|
(*v)[i] = X_n(neg_m->clone(), i + 1);
|
||||||
|
(*v)[n - 1] = X_n(m->clone(), n);
|
||||||
|
(*res)[0] = And_(m->clone(),
|
||||||
|
G_(Implies_(m->clone(),
|
||||||
|
multop::instance(multop::And, v))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// G(m -> X(!m & X(!m X(m)))) [if n = 3]
|
||||||
|
formula* p = m->clone();
|
||||||
|
for (int i = n - 1; i > 0; --i)
|
||||||
|
p = And_(neg_m->clone(), X_(p));
|
||||||
|
(*res)[0] = And_(m->clone(),
|
||||||
|
G_(Implies_(m->clone(), X_(p))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// All bits are initially zero.
|
||||||
|
if (!linear)
|
||||||
|
{
|
||||||
|
// !b & X(!b) & XX(!b) [if n = 3]
|
||||||
|
multop::vec* v2 = new multop::vec(n);
|
||||||
|
for (int i = 0; i < n; ++i)
|
||||||
|
(*v2)[i] = X_n(neg_b->clone(), i);
|
||||||
|
(*res)[1] = multop::instance(multop::And, v2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// !b & X(!b & X(!b)) [if n = 3]
|
||||||
|
formula* p = neg_b->clone();
|
||||||
|
for (int i = n - 1; i > 0; --i)
|
||||||
|
p = And_(neg_b->clone(), X_(p));
|
||||||
|
(*res)[1] = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
formula* Xn_b = X_n(b->clone(), n); // to destroy
|
||||||
|
formula* Xn_negb = X_n(neg_b, n); // to destroy
|
||||||
|
|
||||||
|
// If m is 1 and b is 0 then c is 0 and n steps later b is 1.
|
||||||
|
(*res)[2] = G_(Implies_(And_(m->clone(), neg_b->clone()),
|
||||||
|
And_(neg_c->clone(), Xn_b->clone())));
|
||||||
|
|
||||||
|
// If m is 1 and b is 1 then c is 1 and n steps later b is 0.
|
||||||
|
(*res)[3] = G_(Implies_(And_(m->clone(), b->clone()),
|
||||||
|
And_(c->clone(), Xn_negb->clone())));
|
||||||
|
|
||||||
|
if (!linear)
|
||||||
|
{
|
||||||
|
// If there's no carry, then all of the bits stay the same n steps later.
|
||||||
|
(*res)[4] = G_(Implies_(And_(neg_c->clone(), X_(neg_m->clone())),
|
||||||
|
And_(X_(Not_(c->clone())),
|
||||||
|
Equiv_(X_(b->clone()),
|
||||||
|
X_(Xn_b->clone())))));
|
||||||
|
|
||||||
|
// If there's a carry, then add one: flip the bits of b and
|
||||||
|
// adjust the carry.
|
||||||
|
(*res)[5] = G_(Implies_(c->clone(),
|
||||||
|
And_(Implies_(X_(neg_b->clone()),
|
||||||
|
And_(X_(neg_c->clone()),
|
||||||
|
X_(Xn_b->clone()))),
|
||||||
|
Implies_(X_(b->clone()),
|
||||||
|
And_(X_(c->clone()),
|
||||||
|
X_(Xn_negb->clone()))))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If there's no carry, then all of the bits stay the same n steps later.
|
||||||
|
(*res)[4] = G_(Implies_(And_(neg_c->clone(), X_(neg_m->clone())),
|
||||||
|
X_(And_(Not_(c->clone()),
|
||||||
|
Equiv_(b->clone(),
|
||||||
|
Xn_b->clone())))));
|
||||||
|
|
||||||
|
// If there's a carry, then add one: flip the bits of b and
|
||||||
|
// adjust the carry.
|
||||||
|
(*res)[5] = G_(Implies_(c->clone(),
|
||||||
|
X_(And_(Implies_(neg_b->clone(),
|
||||||
|
And_(neg_c->clone(),
|
||||||
|
Xn_b->clone())),
|
||||||
|
Implies_(b->clone(),
|
||||||
|
And_(c->clone(),
|
||||||
|
Xn_negb->clone()))))));
|
||||||
|
}
|
||||||
|
|
||||||
|
neg_m->destroy();
|
||||||
|
neg_c->destroy();
|
||||||
|
Xn_b->destroy();
|
||||||
|
Xn_negb->destroy();
|
||||||
|
|
||||||
|
return multop::instance(multop::And, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char** argv)
|
main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
|
@ -432,8 +693,25 @@ main(int argc, char** argv)
|
||||||
case 15:
|
case 15:
|
||||||
res = combunop_n("p", n, unop::F, true);
|
res = combunop_n("p", n, unop::F, true);
|
||||||
break;
|
break;
|
||||||
|
case 16:
|
||||||
|
res = fair_response("p", "q", "r", n);
|
||||||
|
break;
|
||||||
|
case 17:
|
||||||
|
res = ltl_counter("b", "m", n, false);
|
||||||
|
break;
|
||||||
|
case 18:
|
||||||
|
res = ltl_counter("b", "m", n, true);
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
res = ltl_counter_carry("b", "m", "c", n, false);
|
||||||
|
break;
|
||||||
|
case 20:
|
||||||
|
res = ltl_counter_carry("b", "m", "c", n, true);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unknown familly " << f << std::endl;
|
std::cerr << "Unknown familly " << f << std::endl;
|
||||||
|
exit(2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue