You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
342 lines
8.1 KiB
342 lines
8.1 KiB
/*
|
|
* This file is part of the program ltl2dstar (http://www.ltl2dstar.de/).
|
|
* Copyright (C) 2005-2007 Joachim Klein <j.klein@ltl2dstar.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#ifndef APMONOM_H
|
|
#define APMONOM_H
|
|
|
|
/** @file
|
|
* Provides class APMonom.
|
|
*/
|
|
|
|
#include "common/Exceptions.hpp"
|
|
#include "common/SimpleBitSet.hpp"
|
|
#include <cassert>
|
|
#include <iostream>
|
|
|
|
// As TRUE and FALSE are defined to equal true and false on Windows, they need to be undefined.
|
|
#undef TRUE
|
|
#undef FALSE
|
|
|
|
/**
|
|
* Class representing a subset of 2^AP where AP is the set of
|
|
* atomic propositions (APSet). It stores two bits per AP:
|
|
* One bit to determine if the value of this AP is set,
|
|
* the second bit to store the value.<br>
|
|
* Additionally, the APMonom can have the special values
|
|
* TRUE or FALSE.<br>
|
|
* Currently, the APSet can only have 31 members.
|
|
*/
|
|
class APMonom {
|
|
public:
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
APMonom() {*this=TRUE;}
|
|
|
|
/**
|
|
* Constructor.
|
|
* @param set_bits integer representation of the bits which are set
|
|
* @param value_bits integer representation of the value bits
|
|
*/
|
|
APMonom(unsigned int set_bits, unsigned int value_bits) {
|
|
bits_set.set(set_bits);
|
|
bits_value.set(value_bits);
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
* Is the AP set?
|
|
* @param index index of AP
|
|
* @return <b>true</b> if AP is set
|
|
*/
|
|
bool isSet(unsigned int index) const {
|
|
if (!isNormal()) {
|
|
THROW_EXCEPTION(IllegalArgumentException, "Can't get AP, is either TRUE/FALSE!");
|
|
}
|
|
return bits_set.get(index);
|
|
}
|
|
|
|
/**
|
|
* Gets the value for this AP. You can't get the value if the AP is not set.
|
|
* @param index index of AP
|
|
* @return <b>true</b> if AP is true
|
|
*/
|
|
bool getValue(unsigned int index) const {
|
|
if (!isNormal()) {
|
|
THROW_EXCEPTION(IllegalArgumentException, "Can't get AP, is either TRUE/FALSE!");
|
|
}
|
|
|
|
if (!bits_set.get(index)) {
|
|
THROW_EXCEPTION(IllegalArgumentException, "Can't get value: AP not set!");
|
|
}
|
|
|
|
return bits_value.get(index);
|
|
}
|
|
|
|
/**
|
|
* Sets the value for this AP. Implicitly, it also sets the AP to 'set'.
|
|
* @param index index of AP
|
|
* @param value value of AP
|
|
*/
|
|
void setValue(unsigned int index, bool value) {
|
|
bits_set.set(index, true);
|
|
bits_value.set(index, value);
|
|
|
|
#ifdef APMONOM_DEBUG
|
|
assert(isNormalized());
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* Perform a logical AND operation of this APMonom with a single AP.
|
|
* @param index index index of AP
|
|
* @param value value of AP
|
|
*/
|
|
void andAP(unsigned int index, bool value) {
|
|
if (isFalse()) {return;}
|
|
|
|
if (!isTrue()) {
|
|
if (isSet(index) && getValue(index)!=value) {
|
|
// contradiction
|
|
*this=FALSE;
|
|
return;
|
|
}
|
|
}
|
|
|
|
setValue(index, value);
|
|
}
|
|
|
|
|
|
/**
|
|
* Unsets this AP.
|
|
* @param index index of AP
|
|
*/
|
|
void unset(unsigned int index) {
|
|
bits_value.set(index,false);
|
|
bits_set.set(index, false);
|
|
|
|
#ifdef APMONOM_DEBUG
|
|
assert(isNormalized());
|
|
#endif
|
|
}
|
|
|
|
|
|
/**
|
|
* Checks if this APMonom is equivalent to TRUE.
|
|
* @return <b>true</b> if this APMonom is TRUE
|
|
*/
|
|
bool isTrue() const {
|
|
return *this==TRUE;
|
|
}
|
|
|
|
/**
|
|
* Checks if this APMonom is equivalent to FALSE.
|
|
* @return <b>true</b> if this APMonom is FALSE
|
|
*/
|
|
bool isFalse() const {
|
|
return *this==FALSE;
|
|
}
|
|
|
|
/**
|
|
* Checks if this APMonom is a normal APMonon (not equivalent to TRUE or FALSE).
|
|
* @return <b>true</b> if this APMonom is normal (not TRUE/FALSE).
|
|
*/
|
|
bool isNormal() const {
|
|
return bits_set!=0;
|
|
}
|
|
|
|
/**
|
|
* Provides access to the underlying bitset representing the
|
|
* value (AP occurs in positive or negative form).
|
|
* @return the SimpleBitSet of the values
|
|
*/
|
|
SimpleBitSet getValueBits() const {
|
|
#ifdef APMONOM_DEBUG
|
|
assert(isNormalized());
|
|
#endif
|
|
return bits_value;
|
|
}
|
|
|
|
/**
|
|
* Provides access to the underlying bitset representing the
|
|
* bits that are set (AP occurs).
|
|
* @return the SimpleBitSet of the occuring APs
|
|
*/
|
|
SimpleBitSet getSetBits() const {
|
|
#ifdef APMONOM_DEBUG
|
|
assert(isNormalized());
|
|
#endif
|
|
return bits_set;
|
|
};
|
|
|
|
|
|
/**
|
|
* Performs an intersection check.
|
|
* @param m1 the first APMonom
|
|
* @param m2 the second APMonom
|
|
* @return <b>true</b> if the intersection of <i>m1</i> and <i>m2</i> is empty.
|
|
*/
|
|
static bool isIntersectionEmpty(const APMonom& m1,
|
|
const APMonom& m2) {
|
|
// check if there are contradicting values
|
|
unsigned int set_in_both=
|
|
m1.getSetBits() & m2.getSetBits();
|
|
|
|
if ((m1.getValueBits() & set_in_both) !=
|
|
(m2.getValueBits() & set_in_both)) {
|
|
// contradiction
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform logical conjunction with other APMonom.
|
|
* @param other the other APMonom
|
|
*/
|
|
APMonom operator&(const APMonom& other) const {
|
|
if (this->isFalse() || other.isFalse()) {
|
|
return FALSE;
|
|
}
|
|
|
|
if (this->isTrue()) {return other;}
|
|
if (other.isTrue()) {return *this;}
|
|
|
|
// both are not TRUE/FALSE:
|
|
|
|
if (isIntersectionEmpty(*this, other)) {
|
|
// return APMonom equivalent to false
|
|
return FALSE;
|
|
}
|
|
|
|
// both Monoms are not contradicting...
|
|
unsigned int result_set=
|
|
this->getSetBits() | other.getSetBits();
|
|
|
|
unsigned int result_value=
|
|
this->getValueBits() | other.getValueBits();
|
|
|
|
return APMonom(result_set, result_value);
|
|
}
|
|
|
|
/**
|
|
* Perform 'minus' operation (equal to *this & !other).
|
|
* @param other the other APMonom
|
|
*/
|
|
APMonom operator-(const APMonom& other) const {
|
|
if (this->isFalse()) {
|
|
// false & anything == false
|
|
return FALSE;
|
|
}
|
|
|
|
if (other.isFalse()) {
|
|
// *this & !(false) == *this & true == *this
|
|
return *this;
|
|
}
|
|
|
|
if (other.isTrue()) {
|
|
// *this & !(true) == *this & false == false
|
|
return FALSE;
|
|
}
|
|
|
|
// the result will be false, if there are two set bits
|
|
// with equal value
|
|
unsigned int set_in_both=
|
|
this->getSetBits() & other.getSetBits();
|
|
|
|
if ((this->getValueBits() & set_in_both) !=
|
|
((~other.getValueBits()) & set_in_both)) {
|
|
// return false;
|
|
return FALSE;
|
|
}
|
|
|
|
unsigned int result_set=
|
|
this->getSetBits() | other.getSetBits();
|
|
|
|
unsigned int result_value=
|
|
this->getValueBits() & (~(other.getValueBits()));
|
|
|
|
return APMonom(result_set, result_value);
|
|
}
|
|
|
|
|
|
/**
|
|
* Checks for equality.
|
|
* @param other the other APMonom
|
|
* @return <b>true</b> if this and the other APMonom are equal
|
|
*/
|
|
bool operator==(const APMonom& other) const {
|
|
return (this->getValueBits()==other.getValueBits()) &&
|
|
(this->getSetBits()==other.getSetBits());
|
|
}
|
|
|
|
|
|
/**
|
|
* Output APMonom on an ostream.
|
|
* @param out the output stream
|
|
* @param m the APMonom
|
|
*/
|
|
friend std::ostream& operator<<(std::ostream& out,
|
|
const APMonom& m) {
|
|
if (m.isTrue()) {
|
|
out << "true";
|
|
} else if (m.isFalse()) {
|
|
out << "false";
|
|
} else {
|
|
for (unsigned int i=0;i<32;i++) {
|
|
if (m.isSet(i)) {
|
|
if (m.getValue(i)) {
|
|
out << "+" << i;
|
|
} else {
|
|
out << "-" << i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return out;
|
|
}
|
|
|
|
/** An APMonom representing TRUE */
|
|
static const APMonom TRUE;
|
|
/** An APMonom representing FALSE */
|
|
static const APMonom FALSE;
|
|
|
|
private:
|
|
/** The bitset for the values */
|
|
SimpleBitSet bits_value;
|
|
/** The bitset for the occurence */
|
|
SimpleBitSet bits_set;
|
|
|
|
/** Checks to see if the bitset representation is normalized. */
|
|
bool isNormalized() {
|
|
if (isTrue() || isFalse()) {
|
|
return true;
|
|
}
|
|
|
|
return (bits_value.getBitSet() & ~(bits_set.getBitSet())) == 0;
|
|
}
|
|
};
|
|
|
|
|
|
#endif
|
|
|