LCOV - code coverage report
Current view: top level - data/include/mcrl2/data - optimized_boolean_operators.h (source / functions) Hit Total Coverage
Test: mcrl2_coverage.info.cleaned Lines: 105 109 96.3 %
Date: 2024-04-21 03:44:01 Functions: 28 30 93.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Author(s): Wieger Wesselink
       2             : // Copyright: see the accompanying file COPYING or copy at
       3             : // https://github.com/mCRL2org/mCRL2/blob/master/COPYING
       4             : //
       5             : // Distributed under the Boost Software License, Version 1.0.
       6             : // (See accompanying file LICENSE_1_0.txt or copy at
       7             : // http://www.boost.org/LICENSE_1_0.txt)
       8             : //
       9             : /// \file mcrl2/data/optimized_boolean_operators.h
      10             : /// \brief add your file description here.
      11             : 
      12             : #ifndef MCRL2_DATA_OPTIMIZED_BOOLEAN_OPERATORS_H
      13             : #define MCRL2_DATA_OPTIMIZED_BOOLEAN_OPERATORS_H
      14             : 
      15             : #include "mcrl2/core/term_traits.h"
      16             : #include "mcrl2/data/detail/data_sequence_algorithm.h"
      17             : 
      18             : namespace mcrl2
      19             : {
      20             : 
      21             : namespace data
      22             : {
      23             : 
      24             : namespace detail
      25             : {
      26             : /// \return The value <tt>!arg</tt>
      27             : template <typename TermTraits>
      28             : inline
      29         568 : void optimized_not(typename TermTraits::term_type& result, 
      30             :                    const typename TermTraits::term_type& arg, 
      31             :                    TermTraits)
      32             : {
      33             :   typedef TermTraits tr;
      34             : 
      35         568 :   if (tr::is_true(arg))
      36             :   {
      37          42 :     result=tr::false_();
      38             :   }
      39         526 :   else if (tr::is_false(arg))
      40             :   {
      41         101 :     result=tr::true_();
      42             :   }
      43         425 :   else if (tr::is_not(arg))
      44             :   {
      45         152 :     result=tr::not_arg(arg);
      46             :   }
      47             :   else
      48             :   {
      49         273 :     tr::make_not_(result, arg);
      50             :   }
      51         568 : }
      52             : 
      53             : /// \brief Make a conjunction and optimize it if possible.
      54             : /// \param left A term
      55             : /// \param right A term
      56             : /// \return The value <tt>left && right</tt>
      57             : template <typename TermTraits>
      58             : inline
      59        9838 : void optimized_and(typename TermTraits::term_type& result, 
      60             :                    const typename TermTraits::term_type& left, 
      61             :                    const typename TermTraits::term_type& right, 
      62             :                    TermTraits)
      63             : {
      64             :   typedef TermTraits tr;
      65             : 
      66        9838 :   if (tr::is_true(left))
      67             :   {
      68        1936 :     result=right;
      69             :   }
      70        7902 :   else if (tr::is_false(left))
      71             :   {
      72        2346 :     result=tr::false_();
      73             :   }
      74        5556 :   else if (tr::is_true(right))
      75             :   {
      76         746 :     result=left;
      77             :   }
      78        4810 :   else if (tr::is_false(right))
      79             :   {
      80        1818 :     result=tr::false_();
      81             :   }
      82        2992 :   else if (left == right)
      83             :   {
      84          18 :     result=left;
      85             :   }
      86             :   else
      87             :   {
      88        2974 :     tr::make_and_(result, left, right);
      89             :   }
      90        9838 : }
      91             : 
      92             : /* template <typename TermTraits>
      93             : inline
      94             : typename TermTraits::term_type optimized_and(const typename TermTraits::term_type& left, const typename TermTraits::term_type& right, TermTraits)
      95             : {
      96             :   typedef TermTraits tr;
      97             : 
      98             :   if (tr::is_true(left))
      99             :   {
     100             :     return right;
     101             :   }
     102             :   else if (tr::is_false(left))
     103             :   {
     104             :     return tr::false_();
     105             :   }
     106             :   else if (tr::is_true(right))
     107             :   {
     108             :     return left;
     109             :   }
     110             :   else if (tr::is_false(right))
     111             :   {
     112             :     return tr::false_();
     113             :   }
     114             :   else if (left == right)
     115             :   {
     116             :     return left;
     117             :   }
     118             :   else
     119             :   {
     120             :     return tr::and_(left, right);
     121             :   }
     122             : } */
     123             : 
     124             : 
     125             : 
     126             : /// \brief Make a disjunction
     127             : /// \param left A term
     128             : /// \param right A term
     129             : /// \return The value <tt>left || right</tt>
     130             : template <typename TermTraits>
     131             : inline
     132        4610 : void optimized_or(typename TermTraits::term_type& result, 
     133             :                   const typename TermTraits::term_type& left, 
     134             :                   const typename TermTraits::term_type& right, TermTraits)
     135             : {
     136             :   typedef TermTraits tr;
     137             : 
     138        4610 :   if (tr::is_true(left))
     139             :   {
     140          37 :     result=tr::true_();
     141             :   }
     142        4573 :   else if (tr::is_false(left))
     143             :   {
     144         637 :     result=right;
     145             :   }
     146        3936 :   else if (tr::is_true(right))
     147             :   {
     148         198 :     result=tr::true_();
     149             :   }
     150        3738 :   else if (tr::is_false(right))
     151             :   {
     152        2677 :     result=left;
     153             :   }
     154        1061 :   else if (left == right)
     155             :   {
     156           5 :     result=left;
     157             :   }
     158             :   else
     159             :   {
     160        1056 :     tr::make_or_(result, left, right);
     161             :   }
     162        4610 : }
     163             : 
     164             : /// \brief Make an implication
     165             : /// \param left A term
     166             : /// \param right A term
     167             : /// \return The value <tt>left => right</tt>
     168             : template <typename TermTraits>
     169             : inline
     170         972 : void optimized_imp(typename TermTraits::term_type& result, 
     171             :                    const typename TermTraits::term_type& left, 
     172             :                    const typename TermTraits::term_type& right, TermTraits t)
     173             : {
     174             :   typedef TermTraits tr;
     175             : 
     176         972 :   if (tr::is_true(left))
     177             :   {
     178          95 :     result=right;
     179             :   }
     180         877 :   else if (tr::is_false(left))
     181             :   {
     182         288 :     result=tr::true_();
     183             :   }
     184         589 :   else if (tr::is_true(right))
     185             :   {
     186           0 :     result=tr::true_();
     187             :   }
     188         589 :   else if (tr::is_false(right))
     189             :   {
     190          54 :     optimized_not(result,left, t);
     191             :   }
     192         535 :   else if (left == right)
     193             :   {
     194           0 :     result=tr::true_();
     195             :   }
     196             :   else
     197             :   {
     198         535 :     tr::make_imp(result, left, right);
     199             :   }
     200         972 : }
     201             : 
     202             : /// \brief Make a universal quantification
     203             : /// \param v A sequence of variables
     204             : /// \param arg A term
     205             : ////// \param remove_variables If true, remove bound variables that do not occur in \a arg.
     206             : /// \param empty_domain_allowed If true, and there are no variables in \a v, treat
     207             : ///        as empty domain, hence yielding <tt>true</tt>, otherwise <tt>arg</tt> arg
     208             : ///        is returned in this case.
     209             : /// \return The universal quantification <tt>forall v.arg</tt>
     210             : template <typename TermTraits>
     211             : inline
     212        2221 : void optimized_forall(typename TermTraits::term_type& result, 
     213             :                       const typename TermTraits::variable_sequence_type& v, 
     214             :                       const typename TermTraits::term_type& arg, 
     215             :                       bool remove_variables, 
     216             :                       bool empty_domain_allowed, TermTraits)
     217             : {
     218             :   typedef TermTraits tr;
     219             : 
     220        2221 :   if (v.empty())
     221             :   {
     222        2044 :     if (empty_domain_allowed)
     223             :     {
     224           0 :       result = tr::true_();
     225             :     }
     226             :     else
     227             :     {
     228        2044 :       result = arg;
     229             :     }
     230             :   }
     231         177 :   else if (tr::is_true(arg))
     232             :   {
     233          19 :     result = tr::true_();
     234             :   }
     235         158 :   else if (tr::is_false(arg))
     236             :   {
     237          11 :     result = tr::false_();
     238             :   }
     239             :   else
     240             :   {
     241         147 :     if (remove_variables)
     242             :     {
     243         130 :       data::variable_list variables = data::detail::set_intersection(v, free_variables(arg));
     244         130 :       if (variables.empty())
     245             :       {
     246          21 :         result = arg;
     247             :       }
     248             :       else
     249             :       {
     250         109 :         tr::make_forall(result, variables, arg);
     251             :       }
     252         130 :     }
     253             :     else
     254             :     {
     255          17 :       tr::make_forall(result, v, arg);
     256             :     }
     257             :   }
     258        2221 : }
     259             : 
     260             : /// \brief Make an existential quantification
     261             : /// \param v A sequence of variables
     262             : /// \param arg A term
     263             : /// \param remove_variables If true, remove bound variables that do not occur in \a arg.
     264             : /// \param empty_domain_allowed If true, and there are no variables in \a v, treat
     265             : ///        as empty domain, hence yielding <tt>false</tt>, otherwise <tt>arg</tt> arg
     266             : ///        is returned in this case.
     267             : /// \return The existential quantification <tt>exists v.arg</tt>
     268             : template <typename TermTraits>
     269             : inline
     270         868 : void optimized_exists(typename TermTraits::term_type& result,
     271             :                       const typename TermTraits::variable_sequence_type& v, 
     272             :                       const typename TermTraits::term_type& arg, 
     273             :                       bool remove_variables, 
     274             :                       bool empty_domain_allowed, 
     275             :                       TermTraits)
     276             : {
     277             :   typedef TermTraits tr;
     278             : 
     279         868 :   if (v.empty())
     280             :   {
     281         536 :     if (empty_domain_allowed)
     282             :     {
     283           0 :       result = tr::false_();
     284             :     }
     285             :     else
     286             :     {
     287         536 :       result = arg;
     288             :     }
     289             :   }
     290         332 :   else if (tr::is_true(arg))
     291             :   {
     292          21 :     result = tr::true_();
     293             :   }
     294         311 :   else if (tr::is_false(arg))
     295             :   {
     296         187 :     result = tr::false_();
     297             :   }
     298             :   else
     299             :   {
     300         124 :     if (remove_variables)
     301             :     {
     302         118 :       data::variable_list variables = data::detail::set_intersection(v, free_variables(arg));
     303         118 :       if (variables.empty())
     304             :       {
     305          10 :         result = arg;
     306             :       }
     307             :       else
     308             :       {
     309         108 :         result = tr::exists(variables, arg);
     310             :       }
     311         118 :     }
     312             :     else
     313             :     {
     314           6 :       result = tr::exists(v, arg);
     315             :     }
     316             :   }
     317         868 : }
     318             : 
     319             : /// \brief Make a negation
     320             : /// \param arg A term
     321             : /// \param not_ The operation not
     322             : /// \param true_ The value true
     323             : /// \param is_true Function that tests for the value true
     324             : /// \param false_ The value false
     325             : /// \param is_false Function that tests for the value false
     326             : /// \return The value <tt>!arg</tt>
     327             : /* template <typename T1, typename T2, typename UnaryFunction, typename UnaryPredicate>
     328             : inline
     329             : T1 optimized_not(T1 arg, UnaryFunction not_, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     330             : {
     331             :   if (is_true(arg))
     332             :   {
     333             :     return false_;
     334             :   }
     335             :   else if (is_false(arg))
     336             :   {
     337             :     return true_;
     338             :   }
     339             :   else
     340             :   {
     341             :     return not_(arg);
     342             :   }
     343             : } */
     344             : 
     345             : /// \brief Make a conjunction
     346             : /// \param left A term
     347             : /// \param right A term
     348             : /// \param and_ The operation and
     349             : /// \param true_ The value true
     350             : /// \param is_true Function that tests for the value true
     351             : /// \param false_ The value false
     352             : /// \param is_false Function that tests for the value false
     353             : /// \return The value <tt>left && right</tt>
     354             : /* template <typename T1, typename T2, typename UnaryPredicate, typename BinaryFunction>
     355             : inline
     356             : T1 optimized_and(T1 left, T1 right, BinaryFunction and_, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     357             : {
     358             :   (void) true_; // Suppress a non used warning.
     359             :   if (is_true(left))
     360             :   {
     361             :     return right;
     362             :   }
     363             :   else if (is_false(left))
     364             :   {
     365             :     return false_;
     366             :   }
     367             :   else if (is_true(right))
     368             :   {
     369             :     return left;
     370             :   }
     371             :   else if (is_false(right))
     372             :   {
     373             :     return false_;
     374             :   }
     375             :   else if (left == right)
     376             :   {
     377             :     return left;
     378             :   }
     379             :   else
     380             :   {
     381             :     return and_(left, right);
     382             :   }
     383             : } */
     384             : 
     385             : /// \brief Make a disjunction
     386             : /// \param left A term
     387             : /// \param right A term
     388             : /// \param or_ The operation or
     389             : /// \param true_ The value true
     390             : /// \param is_true Function that tests for the value true
     391             : /// \param false_ The value false
     392             : /// \param is_false Function that tests for the value false
     393             : /// \return The value <tt>left || right</tt>
     394             : /* template <typename T1, typename T2, typename UnaryPredicate, typename BinaryFunction>
     395             : inline
     396             : T1 optimized_or(T1 left, T1 right, BinaryFunction or_, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     397             : {
     398             :   (void) false_; // Suppress a non used variable warning. 
     399             :   if (is_true(left))
     400             :   {
     401             :     return true_;
     402             :   }
     403             :   else if (is_false(left))
     404             :   {
     405             :     return right;
     406             :   }
     407             :   else if (is_true(right))
     408             :   {
     409             :     return true_;
     410             :   }
     411             :   else if (is_false(right))
     412             :   {
     413             :     return left;
     414             :   }
     415             :   else if (left == right)
     416             :   {
     417             :     return left;
     418             :   }
     419             :   else
     420             :   {
     421             :     return or_(left, right);
     422             :   }
     423             : } */
     424             : 
     425             : /// \brief Make an implication
     426             : /// \param left A term
     427             : /// \param right A term
     428             : /// \param imp The implication operator
     429             : /// \param not_ The operation not
     430             : /// \param true_ The value true
     431             : /// \param is_true Function that tests for the value true
     432             : /// \param false_ The value false
     433             : /// \param is_false Function that tests for the value false
     434             : /// \return The value <tt>left => right</tt>
     435             : /* template <typename T1, typename T2, typename UnaryPredicate, typename UnaryFunction, typename BinaryFunction>
     436             : inline
     437             : T1 optimized_imp(T1 left, T1 right, BinaryFunction imp, UnaryFunction not_, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     438             : {
     439             :   (void)false_; // Suppress a non used variable warning.
     440             :   if (is_true(left))
     441             :   {
     442             :     return right;
     443             :   }
     444             :   else if (is_false(left))
     445             :   {
     446             :     return true_;
     447             :   }
     448             :   else if (is_true(right))
     449             :   {
     450             :     return true_;
     451             :   }
     452             :   else if (is_false(right))
     453             :   {
     454             :     return not_(left);
     455             :   }
     456             :   else if (left == right)
     457             :   {
     458             :     return true_;
     459             :   }
     460             :   else
     461             :   {
     462             :     return imp(left, right);
     463             :   }
     464             : } */
     465             : 
     466             : /// \brief Make a universal quantification
     467             : /// \param v A sequence of variables
     468             : /// \param arg A term
     469             : /// \param forall The universal quantification operator
     470             : /// \param true_ The value true
     471             : /// \param is_true Function that tests for the value true
     472             : /// \param false_ The value false
     473             : /// \param is_false Function that tests for the value false
     474             : /// \return The universal quantification <tt>forall v.arg</tt>
     475             : /* template <typename T1, typename T2, typename VariableSequence, typename UnaryPredicate, typename Forall>
     476             : inline
     477             : void optimized_forall(T1& result, VariableSequence v, T1 arg, Forall forall, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     478             : {
     479             :   if (is_true(arg))
     480             :   {
     481             :     result = true_;
     482             :   }
     483             :   else if (is_false(arg))
     484             :   {
     485             :     result = false_;
     486             :   }
     487             :   else
     488             :   {
     489             :     make_forall(result, v, arg);
     490             :   }
     491             : } */
     492             : 
     493             : /// \brief Make an existential quantification
     494             : /// \param v A sequence of variables
     495             : /// \param arg A term
     496             : /// \param exists The existential quantification operator
     497             : /// \param true_ The value true
     498             : /// \param is_true Function that tests for the value true
     499             : /// \param false_ The value false
     500             : /// \param is_false Function that tests for the value false
     501             : /// \return The existential quantification <tt>exists v.arg</tt>
     502             : /* template <typename T1, typename T2, typename VariableSequence, typename UnaryPredicate, typename Exists>
     503             : inline
     504             : void optimized_exists(T1& result, VariableSequence v, T1 arg, Exists exists, T2 true_, UnaryPredicate is_true, T2 false_, UnaryPredicate is_false)
     505             : {
     506             :   if (is_true(arg))
     507             :   {
     508             :     result = true_;
     509             :   }
     510             :   else if (is_false(arg))
     511             :   {
     512             :     result = false_;
     513             :   }
     514             :   else
     515             :   {
     516             :     make_exists(result, v, arg);
     517             :   }
     518             : } */
     519             : 
     520             : } // namespace detail
     521             : 
     522             : /// \brief Make a negation
     523             : /// \param arg A term
     524             : /// \return The application of not to the argument.
     525             : template <typename Term>
     526             : inline
     527         514 : void optimized_not(Term& result, const Term& arg)
     528             : {
     529         514 :   detail::optimized_not(result, arg, core::term_traits<Term>());
     530         514 : }
     531             : 
     532             : /// \brief Make a conjunction, and optimize if possible.
     533             : /// \param result Contains the optimized and.
     534             : /// \param p A term
     535             : /// \param q A term
     536             : template <typename Term>
     537             : inline
     538        9838 : void optimized_and(Term& result, const Term& p, const Term& q)
     539             : {
     540        9838 :   return detail::optimized_and(result, p, q, core::term_traits<Term>());
     541             : }
     542             : 
     543             : /// \brief Make a conjunction, and optimize if possible.
     544             : /// \param p A term
     545             : /// \param q A term
     546             : /// \return The application of and to the arguments.
     547             : /* template <typename Term>
     548             : inline
     549             : Term optimized_and(const Term& p, const Term& q)
     550             : {
     551             :   return detail::optimized_and(p, q, core::term_traits<Term>());
     552             : } */
     553             : 
     554             : /// \brief Make a disjunction
     555             : /// \param p A term
     556             : /// \param q A term
     557             : /// \return The application of or to the arguments.
     558             : template <typename Term>
     559             : inline
     560        4610 : void optimized_or(Term& result, const Term& p, const Term& q)
     561             : {
     562        4610 :   detail::optimized_or(result, p, q, core::term_traits<Term>());
     563        4610 : }
     564             : 
     565             : /// \brief Make an implication
     566             : /// \param p A term
     567             : /// \param q A term
     568             : /// \return The application of implication to the arguments.
     569             : template <typename Term>
     570             : inline
     571         972 : void optimized_imp(Term& result, const Term& p, const Term& q)
     572             : {
     573         972 :   detail::optimized_imp(result, p, q, core::term_traits<Term>());
     574         972 : }
     575             : 
     576             : /// \brief Make a universal quantification
     577             : /// \param l A sequence of variables
     578             : /// \param p A term
     579             : /// \param remove_variables If true, unused quantifier variables are removed
     580             : /// \return The application of universal quantification to the arguments.
     581             : template <typename Term, typename VariableSequence>
     582             : inline
     583         100 : void optimized_forall(Term& result, const VariableSequence& l, const Term& p, bool remove_variables = false)
     584             : {
     585         100 :   bool empty_domain_allowed = true;
     586         100 :   detail::optimized_forall(result, l, p, remove_variables, empty_domain_allowed, core::term_traits<Term>());
     587         100 : }
     588             : 
     589             : /// \brief Make a universal quantification
     590             : /// \param l A sequence of variables
     591             : /// \param p A term
     592             : /// \param remove_variables If true, unused quantifier variables are removed
     593             : /// \return The application of universal quantification to the arguments.
     594             : /// The optimization forall x:empty_set. phi = true is not applied.
     595             : template <typename Term, typename VariableSequence>
     596             : inline
     597        2121 : void optimized_forall_no_empty_domain(Term& result, const VariableSequence& l, const Term& p, bool remove_variables = false)
     598             : {
     599        2121 :   bool empty_domain_allowed = false;
     600        2121 :   detail::optimized_forall(result, l, p, remove_variables, empty_domain_allowed, core::term_traits<Term>());
     601        2121 : }
     602             : 
     603             : /// \brief Make an existential quantification
     604             : /// \param l A sequence of variables
     605             : /// \param p A term
     606             : /// \param remove_variables If true, unused quantifier variables are removed
     607             : /// \return The application of existential quantification to the arguments.
     608             : template <typename Term, typename VariableSequence>
     609             : inline
     610         302 : void optimized_exists(Term& result, const VariableSequence& l, const Term& p, bool remove_variables = false)
     611             : {
     612         302 :   bool empty_domain_allowed = true;
     613         302 :   detail::optimized_exists(result, l, p, remove_variables, empty_domain_allowed, core::term_traits<Term>());
     614         302 : }
     615             : 
     616             : /// \brief Make an existential quantification
     617             : /// \param l A sequence of variables
     618             : /// \param p A term
     619             : /// \param remove_variables If true, unused quantifier variables are removed
     620             : /// \return The application of existential quantification to the arguments.
     621             : /// The optimization exists x:empty_set. phi = false is not applied.
     622             : template <typename Term, typename VariableSequence>
     623             : inline
     624         566 : void optimized_exists_no_empty_domain(Term& result, const VariableSequence& l, const Term& p, bool remove_variables = false)
     625             : {
     626         566 :   bool empty_domain_allowed = false;
     627         566 :   detail::optimized_exists(result, l, p, remove_variables, empty_domain_allowed, core::term_traits<Term>());
     628         566 : }
     629             : 
     630             : } // namespace data
     631             : 
     632             : } // namespace mcrl2
     633             : 
     634             : #endif // MCRL2_DATA_OPTIMIZED_BOOLEAN_OPERATORS_H

Generated by: LCOV version 1.14