/usr/include/boolstuff-0.1/boolstuff/BoolExpr.h is in boolstuff-dev 0.1.15-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 | /* $Id: BoolExpr.h,v 1.23 2013/03/03 08:19:28 sarrazip Exp $
BoolExpr.h - Boolean expression binary tree node
boolstuff - Disjunctive Normal Form boolean expression library
Copyright (C) 2002-2013 Pierre Sarrazin <http://sarrazip.com/>
This program 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 2
of the License, or (at your option) any later version.
This program 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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*/
#ifndef _H_BoolExpr
#define _H_BoolExpr
#include <iostream>
#include <string>
#include <vector>
#include <set>
#include <algorithm>
#include <cassert>
#include <sstream>
/**
Namespace that contains all symbols defined by this library.
*/
namespace boolstuff {
/**
Object representing a node in a boolean expression binary tree.
All objects of this class are expected to be allocated by operator new.
The value type T must be a concrete type with a default constructor,
a copy constructor and an assignment operator.
Type T must be LessThan Comparable (i.e., it supports the operators
< and ==).
If one of the print() methods is called, there must be a function
of the form operator << (std::ostream &, const T &).
See class BoolExprParser for a way to obtain a tree from a
textual boolean expression.
*/
template <class T>
class BoolExpr
{
public:
/**
Possible types for a boolean expression tree node.
*/
enum Type
{
/** Node, without subtrees, that contains a value of type T.
*/
VALUE,
/** Conjunction node with left and right subtrees.
*/
AND,
/** Disjunction node with left and right subtrees.
*/
OR,
/** Negation node with only a right subtree.
*/
NOT
};
/**
Creates a VALUE node with the given initial value.
This library expects all BoolExpr objects to be allocated
by operator new.
@param initValue initial value for the created node
*/
BoolExpr(const T &initValue = T());
/**
Creates a node of the given type and with the given children.
A NOT node must only have a right-hand child, while AND and OR
nodes must have both left-hand and right-hand children.
Example:<BR>
BoolExpr<string> *left = new BoolExpr<string>("left subtree");<BR>
BoolExpr<string> *right = new BoolExpr<string>("right subtree");<BR>
BoolExpr<string> *root = new BoolExpr<string>(
BoolExpr<string>::AND, left, right);<BR>
delete root;<BR>
@param t type of the node (must be AND, OR or NOT)
@param l subtree to attach as the left-hand child (NULL for NOT)
@param r subtree to attach as the right-hand child
*/
BoolExpr(Type t, BoolExpr *l, BoolExpr *r);
/**
Calls delete on the left and right subtrees of this node.
This library expects all BoolExpr objects to be destroyed
by operator delete.
*/
~BoolExpr();
/** Returns the type of this node. */
Type getType() const;
/** Returns the left-hand child of this node. */
const BoolExpr *getLeft() const;
/**
Returns the left-hand child of this node.
Operator delete should not be called on the subtrees returned
by getLeft(). Only the root of a tree should
be the target of a destruction.
*/
BoolExpr *getLeft();
/** Returns the right-hand child of this node. */
const BoolExpr *getRight() const;
/**
Returns the right-hand child of this node.
Operator delete should not be called on the subtrees returned
by getRight(). Only the root of a tree should
be the target of a destruction.
*/
BoolExpr *getRight();
/**
Returns the value of this node.
getValue() should only be called on a node for which getType()
returns BoolExpr::VALUE.
*/
const T &getValue() const;
/**
Returns the value of this node.
getValue() should only be called on a node for which getType()
returns BoolExpr::VALUE.
*/
T &getValue();
/**
Changes the type of this node.
@param t the type to this to this node
*/
void setType(Type t);
/**
Attaches a subtree as this node's left-hand child.
If this node already had a non null left-hand child, it is
not destroyed before attaching the new child.
@param subtree the subtree to attach (may be NULL)
*/
void setLeft(BoolExpr *subtree);
/**
Attaches a subtree as this node's right-hand child.
If this node already had a non null right-hand child, it is
not destroyed before attaching the new child.
@param subtree the subtree to attach (may be NULL)
*/
void setRight(BoolExpr *subtree);
/**
Changes the value of this node.
This method should only be called on a node of type VALUE.
The given value is copied into this node's value field.
@param v value to give to this node
*/
void setValue(const T &v);
/**
Returns a copy of the designated tree.
All nodes in the returned tree are independent copies of those
in the original tree.
All the cloned nodes are created with operator new.
The caller must eventually destroy the cloned tree by calling
operator delete on its root node.
@param root the root of the tree to be copied
@returns the root of the created tree (NULL if root was NULL)
*/
static BoolExpr *cloneTree(const BoolExpr *root);
/**
Transforms the designated tree into its Disjunctive Normal Form.
The proper way to call this method is the following:
root = BoolExpr<SomeType>::getDisjunctiveNormalForm(root);
The original tree root does not necessarily remain the root
of the transformed tree.
A simplification is applied: when a term of the form
a&!a&(something) is seen, it is deleted unless it is the
root of the whole tree.
CAUTION: this method can return a NULL pointer; such a result
should be interpreted as a "false" boolean expression.
Examples are when the original (or resulting) tree is
a&!a, or a&!a|b&!b.
This method also returns NULL if 'root' is NULL.
@param root root of the tree to transform
@returns the root of the transformed tree (may be NULL)
*/
static BoolExpr *getDisjunctiveNormalForm(BoolExpr *root);
/**
Like getDisjunctiveNormalForm(), but without simplifications.
@param root root of the tree to transform
@param tooLarge indicates if the resulting expression would be too large;
check this when the returned pointer is null.
@returns the root of the transformed tree (may be NULL)
*/
static BoolExpr *getRawDNF(BoolExpr *root, bool &tooLarge);
/**
Determines if the tree rooted at this node is in the DNF.
@returns true or false
*/
bool isDisjunctiveNormalForm() const;
/**
Gets the roots of the terms of an tree in DNF form.
The DNF is a sum of products. Each term in this sum is
represented by a subtree of the tree rooted at the current node.
This method produces the BoolExpr<T> pointers that
represent the roots of the term subtrees.
Returns the iterator at the position past the last insertion.
The tree must first be in DNF. See getDisjunctiveNormalForm().
For example, if the current node is the root a of DNF tree
representing the expression a&b | c | d&e, then three pointers
will be stored: one for the 'a&b' subtree, one for the 'c'
subtree (a single node) and one for the 'd&e' subtree.
If the tree is a single node, then 'this' designates the
only term in the sum and it is returned as the root of the
unique term.
The stored pointers must not be destroyed directly.
Example:<BR>
vector<const BoolExpr<string> *> termRoots;
dnfRoot->getDNFTermRoots(inserter(termRoots, termRoots.end()));
@param dest output iterator that supports the notation *dest++,
where the expression *dest is of type
'const BoolExpr<T> *'.
@returns the output iterator that designates the end of the
produced sequence
*/
template <class OutputIter>
OutputIter getDNFTermRoots(OutputIter dest) const;
/**
Returns the variables that are used in the tree rooted at this node.
Example: with T == string and the expression a&b&!a&!c,
the 'positives' set will contain "a" and "b" and the
'negatives' set will contain "a" and "c".
When the intersection between the two sets is not empty
and the only binary operator used in the tree is AND, the
tree always evaluates to false (because we have an expression
of the form (a&!a)&(whatever)).
If the only binary operator is OR, the tree always evaluates
to true.
@param positives set that receives the T values of the variables
that are used positively
@param negatives set that receives the T values of the variables
that are used negatively
*/
void getTreeVariables(std::set<T> &positives, std::set<T> &negatives) const;
/**
Determines if this DNF term always evaluates to false.
Must only be called on a term of a DNF tree, which can be obtained
with the getDNFTermRoots() method.
(e.g., a&b&!a).
@returns true if and only if this term always evaluates to false
*/
bool isDNFTermUseful() const;
/**
Prints the boolean expression tree rooted at this node in a stream.
Does not print a newline afterwards.
Uses no unnecessary parentheses.
Uses '!', '|' and '&' as the NOT, OR and AND operator.
If this method is called, there must be a function
of the form operator << (ostream &, const T &).
@param out stream into which the tree representation is written
*/
void print(std::ostream &out) const;
/**
Prints the boolean expression tree rooted at this node in a string.
If this method is called, there must be a method
of the form operator << (ostream &, const T &).
@returns the string representation of this tree
*/
std::string print() const;
private:
Type type;
T value;
BoolExpr *left;
BoolExpr *right;
friend class BoolExprParser;
static void simplifyConjunctionList(std::vector<BoolExpr<T> *> &conjunctionList);
static BoolExpr<T> *simplifyConjunction(BoolExpr<T> *conj);
static void simplifyXAndXTerms(std::vector<BoolExpr<T> *> &terms);
static void destroyDNFBinaryOpNodes(BoolExpr<T> *root, bool destroyOrNodes);
static BoolExpr<T> *joinTreesWithOrNodes(
const std::vector<BoolExpr<T> *> &trees);
bool isDNFTermUseful(const std::set<T> &positives,
const std::set<T> &negatives) const;
static BoolExpr<T> *negateDNF(BoolExpr<T> *root, bool &tooLarge);
template <class OutputIter>
OutputIter getDNFFactorRoots(OutputIter dest) const;
// Forbidden operations:
BoolExpr<T>(const BoolExpr<T> &);
BoolExpr<T> &operator = (const BoolExpr<T> &);
};
template <class T>
inline
std::ostream &
operator << (std::ostream &out, const BoolExpr<T> *root)
/*
Prints nothing if 'root' is NULL.
*/
{
if (root != NULL)
root->print(out);
return out;
}
#include <boolstuff/BoolExpr.cpp>
} // namespace boolstuff
#endif /* _H_BoolExpr */
|