// -*- coding: utf-8 -*- // Copyright (C) 2011, 2013, 2014, 2015 Laboratoire de Recherche et // Développement de l'Epita (LRDE). // Copyright (C) 2003, 2004, 2006 Laboratoire d'Informatique de Paris // 6 (LIP6), département Systèmes Répartis Coopératifs (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 3 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 this program. If not, see . #pragma once #include "tgba.hh" #include "misc/fixpool.hh" namespace spot { /// \ingroup tgba_on_the_fly_algorithms /// \brief A state for spot::tgba_product. /// /// This state is in fact a pair of state: the state from the left /// automaton and that of the right. class SPOT_API state_product final: public state { public: /// \brief Constructor /// \param left The state from the left automaton. /// \param right The state from the right automaton. /// \param pool The pool from which the state was allocated. /// These states are acquired by spot::state_product, and will /// be destroyed on destruction. state_product(state* left, state* right, fixed_size_pool* pool) : left_(left), right_(right), count_(1), pool_(pool) { } virtual void destroy() const; state* left() const { return left_; } state* right() const { return right_; } virtual int compare(const state* other) const; virtual size_t hash() const; virtual state_product* clone() const; private: state* left_; ///< State from the left automaton. state* right_; ///< State from the right automaton. mutable unsigned count_; fixed_size_pool* pool_; virtual ~state_product(); state_product(const state_product& o); // No implementation. }; /// \brief A lazy product. (States are computed on the fly.) class SPOT_API tgba_product: public tgba { public: /// \brief Constructor. /// \param left The left automata in the product. /// \param right The right automata in the product. /// Do not be fooled by these arguments: a product is commutative. tgba_product(const const_tgba_ptr& left, const const_tgba_ptr& right); virtual ~tgba_product(); virtual state* get_init_state() const; virtual tgba_succ_iterator* succ_iter(const state* state) const; virtual std::string format_state(const state* state) const; virtual std::string transition_annotation(const tgba_succ_iterator* t) const; virtual state* project_state(const state* s, const const_tgba_ptr& t) const; const acc_cond& left_acc() const; const acc_cond& right_acc() const; protected: virtual bdd compute_support_conditions(const state* state) const; protected: const_tgba_ptr left_; const_tgba_ptr right_; bool left_kripke_; fixed_size_pool pool_; private: // Disallow copy. tgba_product(const tgba_product&) SPOT_DELETED; tgba_product& operator=(const tgba_product&) SPOT_DELETED; }; /// \brief A lazy product with different initial states. class SPOT_API tgba_product_init final: public tgba_product { public: tgba_product_init(const const_tgba_ptr& left, const const_tgba_ptr& right, const state* left_init, const state* right_init); virtual state* get_init_state() const; protected: const state* left_init_; const state* right_init_; }; /// \brief on-the-fly TGBA product inline tgba_product_ptr otf_product(const const_tgba_ptr& left, const const_tgba_ptr& right) { return std::make_shared(left, right); } /// \brief on-the-fly TGBA product with forced initial states inline tgba_product_ptr otf_product_at(const const_tgba_ptr& left, const const_tgba_ptr& right, const state* left_init, const state* right_init) { return std::make_shared(left, right, left_init, right_init); } }