bfssteps.cc 2.84 KB
Newer Older
1 2 3 4 5
// -*- coding: utf-8 -*-
// Copyright (C) 2014, 2015 Laboratoire de Recherche et Développement
// de l'Epita (LRDE)
// Copyright (C) 2004  Laboratoire d'Informatique de Paris 6 (LIP6),
// département Systèmes Répartis Coopératifs (SRC), Université Pierre
6 7 8 9 10 11
// 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
12
// the Free Software Foundation; either version 3 of the License, or
13 14 15 16 17 18 19 20
// (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
21
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
22

23 24 25
#include <deque>
#include <utility>
#include "tgba/tgba.hh"
26 27 28 29 30
#include "bfssteps.hh"

namespace spot
{

31
  bfs_steps::bfs_steps(const const_twa_ptr& a)
32 33 34 35 36 37 38 39
    : a_(a)
  {
  }

  bfs_steps::~bfs_steps()
  {
  }

40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
  void
  bfs_steps::finalize(const std::map<const state*, tgba_run::step,
                state_ptr_less_than>& father, const tgba_run::step& s,
                const state* start, tgba_run::steps& l)
  {
    tgba_run::steps p;
    tgba_run::step current = s;
    for (;;)
      {
        tgba_run::step tmp = current;
        tmp.s = tmp.s->clone();
        p.push_front(tmp);
        if (current.s == start)
          break;
        std::map<const state*, tgba_run::step,
            state_ptr_less_than>::const_iterator it = father.find(current.s);
Alexandre Duret-Lutz's avatar
Alexandre Duret-Lutz committed
56
        assert(it != father.end());
57 58 59 60 61
        current = it->second;
      }
    l.splice(l.end(), p);
  }

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
  const state*
  bfs_steps::search(const state* start, tgba_run::steps& l)
  {
    // Records backlinks to parent state during the BFS.
    // (This also stores the propositions of this link.)
    std::map<const state*, tgba_run::step,
      state_ptr_less_than> father;
    // BFS queue.
    std::deque<const state*> todo;
    // Initial state.
    todo.push_back(start);

    while (!todo.empty())
      {
	const state* src = todo.front();
	todo.pop_front();
78
	for (auto i: a_->succ(src))
79 80 81 82 83 84 85
	  {
	    const state* dest = filter(i->current_state());

	    if (!dest)
	      continue;

	    bdd cond = i->current_condition();
86
	    acc_cond::mark_t acc = i->current_acceptance_conditions();
87 88 89 90 91
	    tgba_run::step s = { src, cond, acc };

	    if (match(s, dest))
	      {
		// Found it!
92
                finalize(father, s, start, l);
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
		return dest;
	      }

	    // Common case: record backlinks and continue BFS
	    // for unvisited states.
	    if (father.find(dest) == father.end())
	      {
		todo.push_back(dest);
		father[dest] = s;
	      }
	  }
      }
    return 0;
  }

}