Commit 8d3606ff authored by martinez's avatar martinez
Browse files

* src/tgbatest/ltl2tgba.cc: Add some option for the reduction of

automata.
* src/tgbatest/spotlbtt.test, src/tgbatest/Makefile.am: Add some
test for reduction of automata.
* src/tgbaalgos/reductgba_sim_del.cc, src/tgbaalgos/reductgba_sim.cc,
src/tgbaalgos/reductgba_sim.hh: Compute some simulation relation
to reduce a tgba.
* src/tgba/tgbareduc.cc, src/tgba/tgbareduc.hh: A implementation
of tgba for the reduction.
* src/tgbaalgos/Makefile.am, src/tgba/Makefile.am:
Add the reduction of automata.
* src/ltlvisit/syntimpl.cc, src/ltlvisit/basereduc.cc:
Lot of mistake are corrected.
* src/ltlvisit/syntimpl.hh, src/ltlvisit/reducform.cc,
src/ltlvisit/reducform.hh, src/ltltest/reduc.cc: Adjust.
* src/ltltest/equals.cc, src/ltltest/reduccmp.test,
src/ltltest/Makefile.am: Add a test for reduction.
parent 383f7e17
2004-06-15 Thomas Martinez <martinez@src.lip6.fr>
* src/tgbatest/ltl2tgba.cc: Add some option for the reduction of
automata.
* src/tgbatest/spotlbtt.test, src/tgbatest/Makefile.am: Add some
test for reduction of automata.
* src/tgbaalgos/reductgba_sim_del.cc, src/tgbaalgos/reductgba_sim.cc,
src/tgbaalgos/reductgba_sim.hh: Compute some simulation relation
to reduce a tgba.
* src/tgba/tgbareduc.cc, src/tgba/tgbareduc.hh: A implementation
of tgba for the reduction.
* src/tgbaalgos/Makefile.am, src/tgba/Makefile.am:
Add the reduction of automata.
* src/ltlvisit/syntimpl.cc, src/ltlvisit/basereduc.cc:
Lot of mistake are corrected.
* src/ltlvisit/syntimpl.hh, src/ltlvisit/reducform.cc,
src/ltlvisit/reducform.hh, src/ltltest/reduc.cc: Adjust.
* src/ltltest/equals.cc, src/ltltest/reduccmp.test,
src/ltltest/Makefile.am: Add a test for reduction.
2004-06-02 Alexandre Duret-Lutz <adl@src.lip6.fr> 2004-06-02 Alexandre Duret-Lutz <adl@src.lip6.fr>
* iface/gspn/common.cc, iface/gspn/common.hh: Remove the * iface/gspn/common.cc, iface/gspn/common.hh: Remove the
......
...@@ -35,6 +35,7 @@ check_PROGRAMS = \ ...@@ -35,6 +35,7 @@ check_PROGRAMS = \
lunabbrev \ lunabbrev \
nenoform \ nenoform \
reduc \ reduc \
reduccmp \
syntimpl \ syntimpl \
tostring \ tostring \
tunabbrev \ tunabbrev \
...@@ -49,6 +50,8 @@ lunabbrev_CPPFLAGS = $(AM_CPPFLAGS) -DLUNABBREV ...@@ -49,6 +50,8 @@ lunabbrev_CPPFLAGS = $(AM_CPPFLAGS) -DLUNABBREV
nenoform_SOURCES = equals.cc nenoform_SOURCES = equals.cc
nenoform_CPPFLAGS = $(AM_CPPFLAGS) -DNENOFORM nenoform_CPPFLAGS = $(AM_CPPFLAGS) -DNENOFORM
reduc_SOURCES = reduc.cc reduc_SOURCES = reduc.cc
reduccmp_SOURCES = equals.cc
reduccmp_CPPFLAGS = $(AM_CPPFLAGS) -DREDUC
syntimpl_SOURCES = syntimpl.cc syntimpl_SOURCES = syntimpl.cc
tostring_SOURCES = tostring.cc tostring_SOURCES = tostring.cc
tunabbrev_SOURCES = equals.cc tunabbrev_SOURCES = equals.cc
...@@ -70,6 +73,7 @@ TESTS = \ ...@@ -70,6 +73,7 @@ TESTS = \
nenoform.test \ nenoform.test \
tunenoform.test \ tunenoform.test \
syntimpl.test \ syntimpl.test \
reduc.test reduc.test \
reduccmp.test
CLEANFILES = stdout expect parse.dot result.data CLEANFILES = stdout expect parse.dot result.data
// Copyright (C) 2003 Laboratoire d'Informatique de Paris 6 (LIP6), // Copyright (C) 2003, 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
// dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre // dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre
// et Marie Curie. // et Marie Curie.
// //
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include "ltlvisit/nenoform.hh" #include "ltlvisit/nenoform.hh"
#include "ltlvisit/destroy.hh" #include "ltlvisit/destroy.hh"
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
#include "ltlvisit/reducform.hh"
#include "ltlvisit/tostring.hh"
void void
syntax(char* prog) syntax(char* prog)
...@@ -42,7 +44,6 @@ main(int argc, char** argv) ...@@ -42,7 +44,6 @@ main(int argc, char** argv)
if (argc != 3) if (argc != 3)
syntax(argv[0]); syntax(argv[0]);
spot::ltl::parse_error_list p1; spot::ltl::parse_error_list p1;
spot::ltl::formula* f1 = spot::ltl::parse(argv[1], p1); spot::ltl::formula* f1 = spot::ltl::parse(argv[1], p1);
...@@ -79,6 +80,16 @@ main(int argc, char** argv) ...@@ -79,6 +80,16 @@ main(int argc, char** argv)
spot::ltl::dump(std::cout, f1); spot::ltl::dump(std::cout, f1);
std::cout << std::endl; std::cout << std::endl;
#endif #endif
#ifdef REDUC
spot::ltl::formula* tmp;
tmp = f1;
f1 = spot::ltl::reduce(f1);
//std::string f2s = spot::ltl::to_string(f2);
//std::string f1s = spot::ltl::to_string(f1);
spot::ltl::destroy(tmp);
spot::ltl::dump(std::cout, f1);
//std::cout << f1s << " // " << f2s << std::endl;
#endif
int exit_code = f1 != f2; int exit_code = f1 != f2;
......
...@@ -133,12 +133,12 @@ main(int argc, char** argv) ...@@ -133,12 +133,12 @@ main(int argc, char** argv)
f2s = spot::ltl::to_string(f2); f2s = spot::ltl::to_string(f2);
} }
if (red && !f2) if ((red | !red) && !f2)
{ {
std::cout << length_f1_before << " " << length_f1_after std::cout << length_f1_before << " " << length_f1_after
<< " '" << f1s_before << "' reduce to '" << f1s_after << "'" << " '" << f1s_before << "' reduce to '" << f1s_after << "'"
<< std::endl; << std::endl;
} }
if (f2) if (f2)
{ {
...@@ -179,5 +179,6 @@ main(int argc, char** argv) ...@@ -179,5 +179,6 @@ main(int argc, char** argv)
assert(spot::ltl::binop::instance_count() == 0); assert(spot::ltl::binop::instance_count() == 0);
assert(spot::ltl::multop::instance_count() == 0); assert(spot::ltl::multop::instance_count() == 0);
return exit_code; //return exit_code;
return 0;
} }
#! /bin/sh
# Copyright (C) 2004 Laboratoire d'Informatique de Paris 6 (LIP6),
# dpartement Systmes Rpartis Coopratifs (SRC), Universit Pierre
# et Marie Curie.
#
# This file is part of Spot, a model checking library.
#
# Spot is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# Spot is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
# License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Spot; see the file COPYING. If not, write to the Free
# Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# Check for the equals visitor
. ./defs || exit 1
# Basics reduction
run 0 ./reduccmp 'X(true)' 'true'
run 0 ./reduccmp 'X(false)' 'false'
run 0 ./reduccmp 'F(true)' 'true'
run 0 ./reduccmp 'F(false)' 'false'
run 0 ./reduccmp 'G(true)' 'true'
run 0 ./reduccmp 'G(false)' 'false'
run 0 ./reduccmp 'XGF(f)' 'GF(f)'
run 0 ./reduccmp 'FX(a)' 'XF(a)'
run 0 ./reduccmp 'G(a R b)' 'G(b)'
run 0 ./reduccmp 'GX(a)' 'XG(a)'
run 0 ./reduccmp 'X(a) U X(b)' 'X(a U b)'
run 0 ./reduccmp 'X(a) R X(b)' 'X(a R b)'
run 0 ./reduccmp 'Xa & Xb' 'X(a & b)'
run 0 ./reduccmp '(a U b) & (c U b)' '(a & c) U b'
run 0 ./reduccmp '(a R b) & (a R c)' 'a R (b & c)'
run 0 ./reduccmp 'Xa | Xb' 'X(a | b)'
run 0 ./reduccmp '(a U b) | (a U c)' 'a U (b | c)'
run 0 ./reduccmp '(a R b) | (c R b)' '(a | c) R b'
run 0 ./reduccmp 'X(a & GFb)' 'Xa & GFb'
run 0 ./reduccmp 'X(a | GFb)' 'Xa | GFb'
run 0 ./reduccmp 'F(a & GFb)' 'Fa & GFb'
run 0 ./reduccmp 'G(a | GFb)' 'Ga | GFb'
run 0 ./reduccmp 'X(a & GFb & c)' 'X(a & c) & GFb'
run 0 ./reduccmp 'X(a | GFb | c)' 'X(a | c) | GFb'
run 0 ./reduccmp 'F(a & GFb & c)' 'F(a & c) & GFb'
run 0 ./reduccmp 'G(a | GFb | c)' 'G(a | c) | GFb'
# Eventuality and universality class reduction
run 0 ./reduccmp 'FFa' 'Fa'
run 0 ./reduccmp 'FGFa' 'GFa'
run 0 ./reduccmp 'b U Fa' 'Fa'
run 0 ./reduccmp 'b U GFa' 'GFa'
run 0 ./reduccmp 'Ga' 'Ga'
run 0 ./reduccmp 'GFGa' 'FGa'
run 0 ./reduccmp 'b R Ga' 'Ga'
run 0 ./reduccmp 'b R FGa' 'FGa'
# Syntactic reduction
run 0 ./reduccmp 'a & (b U a)' 'a'
run 0 ./reduccmp 'a | (b U a)' '(b U a)'
run 0 ./reduccmp 'a U (b U a)' '(b U a)'
...@@ -23,7 +23,9 @@ ...@@ -23,7 +23,9 @@
#include "ltlast/allnodes.hh" #include "ltlast/allnodes.hh"
#include <cassert> #include <cassert>
#include "ltlvisit/clone.hh"
#include "ltlvisit/destroy.hh" #include "ltlvisit/destroy.hh"
#include "ltlvisit/dump.hh"
namespace spot namespace spot
{ {
...@@ -85,6 +87,33 @@ namespace spot ...@@ -85,6 +87,33 @@ namespace spot
result_ = c; result_ = c;
} }
formula*
param_case(multop* mo, unop::type op, multop::type op_child)
{
formula* result;
multop::vec* res1 = new multop::vec;
multop::vec* resGF = new multop::vec;
unsigned mos = mo->size();
for (unsigned i = 0; i < mos; ++i)
if (is_GF(mo->nth(i)))
resGF->push_back(clone(mo->nth(i)));
else
res1->push_back(clone(mo->nth(i)));
destroy(mo);
multop::vec* res3 = new multop::vec;
if (res1->size())
res3->push_back(unop::instance(op,
multop::instance(op_child, res1)));
else
delete res1;
if (resGF->size())
res3->push_back(multop::instance(op_child, resGF));
else
delete resGF;
result = multop::instance(op_child, res3);
return result;
}
void void
visit(unop* uo) visit(unop* uo)
{ {
...@@ -112,30 +141,10 @@ namespace spot ...@@ -112,30 +141,10 @@ namespace spot
// X(f1 & GF(f2)) = X(f1) & GF(F2) // X(f1 & GF(f2)) = X(f1) & GF(F2)
// X(f1 | GF(f2)) = X(f1) | GF(F2) // X(f1 | GF(f2)) = X(f1) | GF(F2)
mo = dynamic_cast<multop*>(result_); mo = dynamic_cast<multop*>(result_);
if (mo && mo->size() == 2) if (mo)
{ {
// FIXME: This is incomplete. It should be done for result_ = param_case(mo, unop::X, mo->op());
// multops of any size. return;
if (is_GF(mo->nth(0)))
{
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(1))));
res->push_back(basic_reduce(mo->nth(0)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
if (is_GF(mo->nth(1)))
{
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(0))));
res->push_back(basic_reduce(mo->nth(1)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
} }
result_ = unop::instance(unop::X, result_); result_ = unop::instance(unop::X, result_);
...@@ -161,34 +170,12 @@ namespace spot ...@@ -161,34 +170,12 @@ namespace spot
// F(f1 & GF(f2)) = F(f1) & GF(F2) // F(f1 & GF(f2)) = F(f1) & GF(F2)
mo = dynamic_cast<multop*>(result_); mo = dynamic_cast<multop*>(result_);
if (mo && mo->op() == multop::And if (mo && mo->op() == multop::And)
// FIXME: This is incomplete. It should be done for
// "And"s of any size.
&& mo->size() == 2)
{ {
if (is_GF(mo->nth(0))) result_ = param_case(mo, unop::F, multop::And);
{ return;
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(1))));
res->push_back(basic_reduce(mo->nth(0)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
if (is_GF(mo->nth(1)))
{
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(0))));
res->push_back(basic_reduce(mo->nth(1)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
} }
result_ = unop::instance(unop::F, result_); result_ = unop::instance(unop::F, result_);
return; return;
...@@ -222,31 +209,10 @@ namespace spot ...@@ -222,31 +209,10 @@ namespace spot
// G(f1 | GF(f2)) = G(f1) | GF(F2) // G(f1 | GF(f2)) = G(f1) | GF(F2)
mo = dynamic_cast<multop*>(result_); mo = dynamic_cast<multop*>(result_);
if (mo && mo->op() == multop::Or if (mo && mo->op() == multop::Or)
// FIXME: This is incomplete. It should be done for
// "Or"s of any size.
&& mo->size() == 2)
{ {
if (is_GF(mo->nth(0))) result_ = param_case(mo, unop::G, multop::Or);
{ return;
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(1))));
res->push_back(basic_reduce(mo->nth(0)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
if (is_GF(mo->nth(1)))
{
multop::vec* res = new multop::vec;
res->push_back(unop::instance(unop::F,
basic_reduce(mo->nth(0))));
res->push_back(basic_reduce(mo->nth(1)));
result_ = multop::instance(mo->op(), res);
destroy(mo);
return;
}
} }
result_ = unop::instance(unop::G, result_); result_ = unop::instance(unop::G, result_);
...@@ -385,17 +351,17 @@ namespace spot ...@@ -385,17 +351,17 @@ namespace spot
if (uo && uo->op() == unop::X) if (uo && uo->op() == unop::X)
{ {
// Xa & Xb = X(a & b) // Xa & Xb = X(a & b)
tmpX->push_back(basic_reduce(uo->child())); tmpX->push_back(clone(uo->child()));
} }
else if (is_FG(*i)) else if (is_FG(*i))
{ {
// FG(a) & FG(b) = FG(a & b) // FG(a) & FG(b) = FG(a & b)
unop* uo2 = dynamic_cast<unop*>(uo->child()); unop* uo2 = dynamic_cast<unop*>(uo->child());
tmpFG->push_back(basic_reduce(uo2->child())); tmpFG->push_back(clone(uo2->child()));
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
} }
else if (bo) else if (bo)
...@@ -414,7 +380,7 @@ namespace spot ...@@ -414,7 +380,7 @@ namespace spot
&& ftmp == bo2->second()) && ftmp == bo2->second())
{ {
tmpUright tmpUright
->push_back(basic_reduce(bo2->first())); ->push_back(clone(bo2->first()));
if (j != i) if (j != i)
{ {
destroy(*j); destroy(*j);
...@@ -428,7 +394,7 @@ namespace spot ...@@ -428,7 +394,7 @@ namespace spot
instance(multop:: instance(multop::
And, And,
tmpUright), tmpUright),
basic_reduce(ftmp))); clone(ftmp)));
} }
else if (bo->op() == binop::R) else if (bo->op() == binop::R)
{ {
...@@ -444,7 +410,7 @@ namespace spot ...@@ -444,7 +410,7 @@ namespace spot
&& ftmp == bo2->first()) && ftmp == bo2->first())
{ {
tmpRright tmpRright
->push_back(basic_reduce(bo2->second())); ->push_back(clone(bo2->second()));
if (j != i) if (j != i)
{ {
destroy(*j); destroy(*j);
...@@ -454,19 +420,19 @@ namespace spot ...@@ -454,19 +420,19 @@ namespace spot
} }
tmpR tmpR
->push_back(binop::instance(binop::R, ->push_back(binop::instance(binop::R,
basic_reduce(ftmp), clone(ftmp),
multop:: multop::
instance(multop::And, instance(multop::And,
tmpRright))); tmpRright)));
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
destroy(*i); destroy(*i);
} }
...@@ -489,17 +455,17 @@ namespace spot ...@@ -489,17 +455,17 @@ namespace spot
if (uo && uo->op() == unop::X) if (uo && uo->op() == unop::X)
{ {
// Xa | Xb = X(a | b) // Xa | Xb = X(a | b)
tmpX->push_back(basic_reduce(uo->child())); tmpX->push_back(clone(uo->child()));
} }
else if (is_GF(*i)) else if (is_GF(*i))
{ {
// GF(a) | GF(b) = GF(a | b) // GF(a) | GF(b) = GF(a | b)
unop* uo2 = dynamic_cast<unop*>(uo->child()); unop* uo2 = dynamic_cast<unop*>(uo->child());
tmpGF->push_back(basic_reduce(uo2->child())); tmpGF->push_back(clone(uo2->child()));
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
} }
else if (bo) else if (bo)
...@@ -518,7 +484,7 @@ namespace spot ...@@ -518,7 +484,7 @@ namespace spot
&& ftmp == bo2->first()) && ftmp == bo2->first())
{ {
tmpUright tmpUright
->push_back(basic_reduce(bo2->second())); ->push_back(clone(bo2->second()));
if (j != i) if (j != i)
{ {
destroy(*j); destroy(*j);
...@@ -527,7 +493,7 @@ namespace spot ...@@ -527,7 +493,7 @@ namespace spot
} }
} }
tmpU->push_back(binop::instance(binop::U, tmpU->push_back(binop::instance(binop::U,
basic_reduce(ftmp), clone(ftmp),
multop:: multop::
instance(multop::Or, instance(multop::Or,
tmpUright))); tmpUright)));
...@@ -546,7 +512,7 @@ namespace spot ...@@ -546,7 +512,7 @@ namespace spot
&& ftmp == bo2->second()) && ftmp == bo2->second())
{ {
tmpRright tmpRright
->push_back(basic_reduce(bo->first())); ->push_back(clone(bo2->first()));
if (j != i) if (j != i)
{ {
destroy(*j); destroy(*j);
...@@ -559,16 +525,16 @@ namespace spot ...@@ -559,16 +525,16 @@ namespace spot
multop:: multop::
instance(multop::Or, instance(multop::Or,
tmpRright), tmpRright),
basic_reduce(ftmp))); clone(ftmp)));
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
} }
else else
{ {
tmpOther->push_back(basic_reduce(*i)); tmpOther->push_back(clone(*i));
} }
destroy(*i); destroy(*i);
} }
...@@ -582,23 +548,27 @@ namespace spot ...@@ -582,23 +548,27 @@ namespace spot
res->clear(); res->clear();
delete res; delete res;
if (tmpX->size())
if (tmpX && tmpX->size())