ltl2tgba.cc 4.55 KB
Newer Older
1
2
#include <iostream>
#include <cassert>
3
4
#include <fstream>
#include <string>
5
6
7
#include "ltlvisit/destroy.hh"
#include "ltlast/allnodes.hh"
#include "ltlparse/public.hh"
8
#include "tgbaalgos/ltl2tgba.hh"
9
#include "tgbaalgos/ltl2tgba_fm.hh"
10
#include "tgba/bddprint.hh"
11
#include "tgbaalgos/dotty.hh"
12
#include "tgbaalgos/lbtt.hh"
13
#include "tgba/tgbatba.hh"
14
15
16
17

void
syntax(char* prog)
{
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
18
  std::cerr << "Usage: "<< prog << " [OPTIONS...] formula" << std::endl
19
            << "       "<< prog << " -F [OPTIONS...] file" << std::endl
Alexandre Duret-Lutz's avatar
spacing    
Alexandre Duret-Lutz committed
20
	    << std::endl
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
21
	    << "Options:" << std::endl
22
	    << "  -a   display the accepting_conditions BDD, not the reachability graph"
23
	    << std::endl
24
	    << "  -A   same as -a, but as a set" << std::endl
25
	    << "  -d   turn on traces during parsing" << std::endl
26
	    << "  -D   degeneralize the automaton" << std::endl
27
28
29
            << "  -f   use Couvreur's FM algorithm for translation"
	    << std::endl
            << "  -F   read the formula from the file" << std::endl
30
	    << "  -r   display the relation BDD, not the reachability graph"
31
	    << std::endl
32
	    << "  -R   same as -r, but as a set" << std::endl
33
	    << "  -t   display reachable states in LBTT's format" << std::endl
Alexandre Duret-Lutz's avatar
spacing    
Alexandre Duret-Lutz committed
34
	    << "  -v   display the BDD variables used by the automaton"
35
	    << std::endl;
36
37
38
39
40
41
42
43
  exit(2);
}

int
main(int argc, char** argv)
{
  int exit_code = 0;

44
  bool debug_opt = false;
45
  bool degeneralize_opt = false;
46
47
  bool fm_opt = false;
  bool file_opt = false;
48
  int output = 0;
49
  int formula_index = 0;
50

51
  for (;;)
52
    {
53
      if (argc < formula_index + 2)
54
	syntax(argv[0]);
55
56
57

      ++formula_index;

58
59
60
61
62
63
64
65
66
      if (!strcmp(argv[formula_index], "-a"))
	{
	  output = 2;
	}
      else if (!strcmp(argv[formula_index], "-A"))
	{
	  output = 4;
	}
      else if (!strcmp(argv[formula_index], "-d"))
67
68
69
	{
	  debug_opt = true;
	}
70
71
72
73
      else if (!strcmp(argv[formula_index], "-D"))
	{
	  degeneralize_opt = true;
	}
74
75
76
77
78
79
80
81
      else if (!strcmp(argv[formula_index], "-f"))
	{
	  fm_opt = true;
	}
      else if (!strcmp(argv[formula_index], "-F"))
	{
	  file_opt = true;
	}
82
83
      else if (!strcmp(argv[formula_index], "-r"))
	{
84
85
86
87
88
	  output = 1;
	}
      else if (!strcmp(argv[formula_index], "-R"))
	{
	  output = 3;
89
	}
90
91
92
93
      else if (!strcmp(argv[formula_index], "-t"))
	{
	  output = 6;
	}
94
95
96
97
      else if (!strcmp(argv[formula_index], "-v"))
	{
	  output = 5;
	}
98
99
100
101
      else
	{
	  break;
	}
102
103
    }

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
  std::string input;

  if (file_opt)
    {
      std::ifstream fin(argv[formula_index]);
      if (! fin)
	{
	  std::cerr << "Cannot open " << argv[formula_index] << std::endl;
	  exit(2);
	}

      if (! std::getline(fin, input, '\0'))
	{
	  std::cerr << "Cannot read " << argv[formula_index] << std::endl;
	  exit(2);
	}
    }
  else
    {
      input = argv[formula_index];
    }

126
127
  spot::ltl::environment& env(spot::ltl::default_environment::instance());
  spot::ltl::parse_error_list pel;
128
  spot::ltl::formula* f = spot::ltl::parse(input, pel, env, debug_opt);
129

130
  exit_code = spot::ltl::format_parse_errors(std::cerr, input, pel);
131

132
  spot::bdd_dict* dict = new spot::bdd_dict();
133
134
  if (f)
    {
135
136
137
138
139
140
141
142
143
      spot::tgba_bdd_concrete* concrete = 0;
      spot::tgba* to_free = 0;
      spot::tgba* a = 0;

      if (fm_opt)
	to_free = a = spot::ltl_to_tgba_fm(f, dict);
      else
	to_free = a = concrete = spot::ltl_to_tgba(f, dict);

144
      spot::ltl::destroy(f);
145
146
147
148
149

      spot::tgba* degeneralized = 0;
      if (degeneralize_opt)
	a = degeneralized = new spot::tgba_tba_proxy(a);

150
151
152
153
154
155
      switch (output)
	{
	case 0:
	  spot::dotty_reachable(std::cout, a);
	  break;
	case 1:
156
157
158
	  if (concrete)
	    spot::bdd_print_dot(std::cout, concrete->get_dict(),
				concrete->get_core_data().relation);
159
160
	  break;
	case 2:
161
162
163
164
	  if (concrete)
	    spot::bdd_print_dot(std::cout, concrete->get_dict(),
				concrete->
				get_core_data().accepting_conditions);
165
166
	  break;
	case 3:
167
168
169
	  if (concrete)
	    spot::bdd_print_set(std::cout, concrete->get_dict(),
				concrete->get_core_data().relation);
170
171
	  break;
	case 4:
172
173
174
175
	  if (concrete)
	    spot::bdd_print_set(std::cout, concrete->get_dict(),
				concrete->
				get_core_data().accepting_conditions);
176
	  break;
177
	case 5:
178
	  a->get_dict()->dump(std::cout);
179
	  break;
180
181
182
	case 6:
	  spot::lbtt_reachable(std::cout, a);
	  break;
183
184
185
	default:
	  assert(!"unknown output option");
	}
186
187
188
189

      if (degeneralize_opt)
	delete degeneralized;

190
      delete to_free;
191
192
193
194
195
196
197
198
199
200
    }
  else
    {
      exit_code = 1;
    }

  assert(spot::ltl::atomic_prop::instance_count() == 0);
  assert(spot::ltl::unop::instance_count() == 0);
  assert(spot::ltl::binop::instance_count() == 0);
  assert(spot::ltl::multop::instance_count() == 0);
201
  delete dict;
202
203
  return exit_code;
}