* src/ltlast/atomic_prop.hh, src/ltlast/binop.hh, src/ltlast/bunop.hh, src/ltlast/constant.hh, src/ltlast/unop.hh: Here. * src/misc/common.hh: Disable final for swig3.0.
242 lines
6.6 KiB
C++
242 lines
6.6 KiB
C++
// -*- coding: utf-8 -*-
|
|
// Copyright (C) 2009, 2010, 2011, 2012, 2013, 2014 Laboratoire de
|
|
// Recherche et Développement de l'Epita (LRDE).
|
|
// Copyright (C) 2003, 2004 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 <http://www.gnu.org/licenses/>.
|
|
|
|
/// \file ltlast/binop.hh
|
|
/// \brief LTL binary operators
|
|
///
|
|
/// This does not include \c AND and \c OR operators. These are
|
|
/// considered to be multi-operand operators (see spot::ltl::multop).
|
|
#ifndef SPOT_LTLAST_BINOP_HH
|
|
# define SPOT_LTLAST_BINOP_HH
|
|
|
|
#include "formula.hh"
|
|
#include <map>
|
|
#include <iosfwd>
|
|
#include <tuple>
|
|
|
|
namespace spot
|
|
{
|
|
namespace ltl
|
|
{
|
|
|
|
/// \ingroup ltl_ast
|
|
/// \brief Binary operator.
|
|
class SPOT_API binop final: public formula
|
|
{
|
|
public:
|
|
/// Different kinds of binary opertaors
|
|
///
|
|
/// And and Or are not here. Because they
|
|
/// are often nested we represent them as multops.
|
|
enum type { Xor,
|
|
Implies,
|
|
Equiv,
|
|
U, ///< until
|
|
R, ///< release (dual of until)
|
|
W, ///< weak until
|
|
M, ///< strong release (dual of weak until)
|
|
EConcat, ///< Existential Concatenation
|
|
EConcatMarked, ///< Existential Concatenation, Marked
|
|
UConcat ///< Universal Concatenation
|
|
};
|
|
|
|
/// \brief Build a unary operator with operation \a op and
|
|
/// children \a first and \a second.
|
|
///
|
|
/// Some reordering will be performed on arguments of commutative
|
|
/// operators (Xor and Equiv) to ensure that for instance (a <=> b)
|
|
/// is the same formula as (b <=> a).
|
|
///
|
|
/// Furthermore, the following trivial simplifications are
|
|
/// performed (the left formula is rewritten as the right
|
|
/// formula):
|
|
/// - (1 => Exp) = Exp
|
|
/// - (0 => Exp) = 1
|
|
/// - (Exp => 1) = 1
|
|
/// - (Exp => 0) = !Exp
|
|
/// - (Exp => Exp) = 1
|
|
/// - (1 ^ Exp) = !Exp
|
|
/// - (0 ^ Exp) = Exp
|
|
/// - (Exp ^ Exp) = 0
|
|
/// - (0 <=> Exp) = !Exp
|
|
/// - (1 <=> Exp) = Exp
|
|
/// - (Exp <=> Exp) = Exp
|
|
/// - (Exp U 1) = 1
|
|
/// - (Exp U 0) = 0
|
|
/// - (0 U Exp) = Exp
|
|
/// - (Exp U Exp) = Exp
|
|
/// - (Exp W 1) = 1
|
|
/// - (0 W Exp) = Exp
|
|
/// - (1 W Exp) = 1
|
|
/// - (Exp W Exp) = Exp
|
|
/// - (Exp R 1) = 1
|
|
/// - (Exp R 0) = 0
|
|
/// - (1 R Exp) = Exp
|
|
/// - (Exp R Exp) = Exp
|
|
/// - (Exp M 0) = 0
|
|
/// - (1 M Exp) = Exp
|
|
/// - (0 M Exp) = 0
|
|
/// - (Exp M Exp) = Exp
|
|
/// - 0 <>-> Exp = 0
|
|
/// - 1 <>-> Exp = Exp
|
|
/// - [*0] <>-> Exp = 0
|
|
/// - Exp <>-> 0 = 0
|
|
/// - boolExp <>-> Exp = boolExp & Exp
|
|
/// - 0 []-> Exp = 1
|
|
/// - 1 []-> Exp = Exp
|
|
/// - [*0] []-> Exp = 1
|
|
/// - Exp []-> 1 = 1
|
|
/// - boolExp <>-> Exp = !boolExp | Exp
|
|
static const formula* instance(type op,
|
|
const formula* first,
|
|
const formula* second);
|
|
|
|
virtual void accept(visitor& v) const override;
|
|
|
|
/// Get the first operand.
|
|
const formula* first() const
|
|
{
|
|
return first_;
|
|
}
|
|
|
|
/// Get the second operand.
|
|
const formula* second() const
|
|
{
|
|
return second_;
|
|
}
|
|
|
|
/// Get the type of this operator.
|
|
type op() const
|
|
{
|
|
return op_;
|
|
}
|
|
|
|
/// Get the type of this operator, as a string.
|
|
const char* op_name() const;
|
|
|
|
/// Return a canonic representation of the atomic proposition
|
|
virtual std::string dump() const override;
|
|
|
|
/// Number of instantiated binary operators. For debugging.
|
|
static unsigned instance_count();
|
|
|
|
/// Dump all instances. For debugging.
|
|
static std::ostream& dump_instances(std::ostream& os);
|
|
|
|
protected:
|
|
typedef std::tuple<type, const formula*, const formula*> key;
|
|
typedef std::map<key, const binop*> map;
|
|
static map instances;
|
|
|
|
binop(type op, const formula* first, const formula* second);
|
|
virtual ~binop();
|
|
|
|
private:
|
|
type op_;
|
|
const formula* first_;
|
|
const formula* second_;
|
|
};
|
|
|
|
/// \brief Cast \a f into a binop
|
|
///
|
|
/// Cast \a f into a binop iff it is a binop instance. Return 0
|
|
/// otherwise. This is faster than \c dynamic_cast.
|
|
inline
|
|
const binop*
|
|
is_binop(const formula* f)
|
|
{
|
|
if (f->kind() != formula::BinOp)
|
|
return 0;
|
|
return static_cast<const binop*>(f);
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it has type \a op.
|
|
///
|
|
/// Cast \a f into a binop iff it is a unop instance with operator \a op.
|
|
/// Returns 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_binop(const formula* f, binop::type op)
|
|
{
|
|
if (const binop* bo = is_binop(f))
|
|
if (bo->op() == op)
|
|
return bo;
|
|
return 0;
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it has type \a op1 or \a op2.
|
|
///
|
|
/// Cast \a f into a binop iff it is a unop instance with operator \a op1 or
|
|
/// \a op2. Returns 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_binop(const formula* f, binop::type op1, binop::type op2)
|
|
{
|
|
if (const binop* bo = is_binop(f))
|
|
if (bo->op() == op1 || bo->op() == op2)
|
|
return bo;
|
|
return 0;
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it is a U.
|
|
///
|
|
/// Return 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_U(const formula* f)
|
|
{
|
|
return is_binop(f, binop::U);
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it is a M.
|
|
///
|
|
/// Return 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_M(const formula* f)
|
|
{
|
|
return is_binop(f, binop::M);
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it is a R.
|
|
///
|
|
/// Return 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_R(const formula* f)
|
|
{
|
|
return is_binop(f, binop::R);
|
|
}
|
|
|
|
/// \brief Cast \a f into a binop if it is a W.
|
|
///
|
|
/// Return 0 otherwise.
|
|
inline
|
|
const binop*
|
|
is_W(const formula* f)
|
|
{
|
|
return is_binop(f, binop::W);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif // SPOT_LTLAST_BINOP_HH
|