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

  1. /*
  2. * This file is part of the program ltl2dstar (http://www.ltl2dstar.de/).
  3. * Copyright (C) 2005-2007 Joachim Klein <j.klein@ltl2dstar.de>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 2 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. */
  18. #ifndef APMONOM_H
  19. #define APMONOM_H
  20. /** @file
  21. * Provides class APMonom.
  22. */
  23. #include "common/Exceptions.hpp"
  24. #include "common/SimpleBitSet.hpp"
  25. #include <cassert>
  26. #include <iostream>
  27. // As TRUE and FALSE are defined to equal true and false on Windows, they need to be undefined.
  28. #undef TRUE
  29. #undef FALSE
  30. /**
  31. * Class representing a subset of 2^AP where AP is the set of
  32. * atomic propositions (APSet). It stores two bits per AP:
  33. * One bit to determine if the value of this AP is set,
  34. * the second bit to store the value.<br>
  35. * Additionally, the APMonom can have the special values
  36. * TRUE or FALSE.<br>
  37. * Currently, the APSet can only have 31 members.
  38. */
  39. class APMonom {
  40. public:
  41. /**
  42. * Constructor.
  43. */
  44. APMonom() {*this=TRUE;}
  45. /**
  46. * Constructor.
  47. * @param set_bits integer representation of the bits which are set
  48. * @param value_bits integer representation of the value bits
  49. */
  50. APMonom(unsigned int set_bits, unsigned int value_bits) {
  51. bits_set.set(set_bits);
  52. bits_value.set(value_bits);
  53. }
  54. /**
  55. * Is the AP set?
  56. * @param index index of AP
  57. * @return <b>true</b> if AP is set
  58. */
  59. bool isSet(unsigned int index) const {
  60. if (!isNormal()) {
  61. THROW_EXCEPTION(IllegalArgumentException, "Can't get AP, is either TRUE/FALSE!");
  62. }
  63. return bits_set.get(index);
  64. }
  65. /**
  66. * Gets the value for this AP. You can't get the value if the AP is not set.
  67. * @param index index of AP
  68. * @return <b>true</b> if AP is true
  69. */
  70. bool getValue(unsigned int index) const {
  71. if (!isNormal()) {
  72. THROW_EXCEPTION(IllegalArgumentException, "Can't get AP, is either TRUE/FALSE!");
  73. }
  74. if (!bits_set.get(index)) {
  75. THROW_EXCEPTION(IllegalArgumentException, "Can't get value: AP not set!");
  76. }
  77. return bits_value.get(index);
  78. }
  79. /**
  80. * Sets the value for this AP. Implicitly, it also sets the AP to 'set'.
  81. * @param index index of AP
  82. * @param value value of AP
  83. */
  84. void setValue(unsigned int index, bool value) {
  85. bits_set.set(index, true);
  86. bits_value.set(index, value);
  87. #ifdef APMONOM_DEBUG
  88. assert(isNormalized());
  89. #endif
  90. }
  91. /**
  92. * Perform a logical AND operation of this APMonom with a single AP.
  93. * @param index index index of AP
  94. * @param value value of AP
  95. */
  96. void andAP(unsigned int index, bool value) {
  97. if (isFalse()) {return;}
  98. if (!isTrue()) {
  99. if (isSet(index) && getValue(index)!=value) {
  100. // contradiction
  101. *this=FALSE;
  102. return;
  103. }
  104. }
  105. setValue(index, value);
  106. }
  107. /**
  108. * Unsets this AP.
  109. * @param index index of AP
  110. */
  111. void unset(unsigned int index) {
  112. bits_value.set(index,false);
  113. bits_set.set(index, false);
  114. #ifdef APMONOM_DEBUG
  115. assert(isNormalized());
  116. #endif
  117. }
  118. /**
  119. * Checks if this APMonom is equivalent to TRUE.
  120. * @return <b>true</b> if this APMonom is TRUE
  121. */
  122. bool isTrue() const {
  123. return *this==TRUE;
  124. }
  125. /**
  126. * Checks if this APMonom is equivalent to FALSE.
  127. * @return <b>true</b> if this APMonom is FALSE
  128. */
  129. bool isFalse() const {
  130. return *this==FALSE;
  131. }
  132. /**
  133. * Checks if this APMonom is a normal APMonon (not equivalent to TRUE or FALSE).
  134. * @return <b>true</b> if this APMonom is normal (not TRUE/FALSE).
  135. */
  136. bool isNormal() const {
  137. return bits_set!=0;
  138. }
  139. /**
  140. * Provides access to the underlying bitset representing the
  141. * value (AP occurs in positive or negative form).
  142. * @return the SimpleBitSet of the values
  143. */
  144. SimpleBitSet getValueBits() const {
  145. #ifdef APMONOM_DEBUG
  146. assert(isNormalized());
  147. #endif
  148. return bits_value;
  149. }
  150. /**
  151. * Provides access to the underlying bitset representing the
  152. * bits that are set (AP occurs).
  153. * @return the SimpleBitSet of the occuring APs
  154. */
  155. SimpleBitSet getSetBits() const {
  156. #ifdef APMONOM_DEBUG
  157. assert(isNormalized());
  158. #endif
  159. return bits_set;
  160. };
  161. /**
  162. * Performs an intersection check.
  163. * @param m1 the first APMonom
  164. * @param m2 the second APMonom
  165. * @return <b>true</b> if the intersection of <i>m1</i> and <i>m2</i> is empty.
  166. */
  167. static bool isIntersectionEmpty(const APMonom& m1,
  168. const APMonom& m2) {
  169. // check if there are contradicting values
  170. unsigned int set_in_both=
  171. m1.getSetBits() & m2.getSetBits();
  172. if ((m1.getValueBits() & set_in_both) !=
  173. (m2.getValueBits() & set_in_both)) {
  174. // contradiction
  175. return true;
  176. } else {
  177. return false;
  178. }
  179. }
  180. /**
  181. * Perform logical conjunction with other APMonom.
  182. * @param other the other APMonom
  183. */
  184. APMonom operator&(const APMonom& other) const {
  185. if (this->isFalse() || other.isFalse()) {
  186. return FALSE;
  187. }
  188. if (this->isTrue()) {return other;}
  189. if (other.isTrue()) {return *this;}
  190. // both are not TRUE/FALSE:
  191. if (isIntersectionEmpty(*this, other)) {
  192. // return APMonom equivalent to false
  193. return FALSE;
  194. }
  195. // both Monoms are not contradicting...
  196. unsigned int result_set=
  197. this->getSetBits() | other.getSetBits();
  198. unsigned int result_value=
  199. this->getValueBits() | other.getValueBits();
  200. return APMonom(result_set, result_value);
  201. }
  202. /**
  203. * Perform 'minus' operation (equal to *this & !other).
  204. * @param other the other APMonom
  205. */
  206. APMonom operator-(const APMonom& other) const {
  207. if (this->isFalse()) {
  208. // false & anything == false
  209. return FALSE;
  210. }
  211. if (other.isFalse()) {
  212. // *this & !(false) == *this & true == *this
  213. return *this;
  214. }
  215. if (other.isTrue()) {
  216. // *this & !(true) == *this & false == false
  217. return FALSE;
  218. }
  219. // the result will be false, if there are two set bits
  220. // with equal value
  221. unsigned int set_in_both=
  222. this->getSetBits() & other.getSetBits();
  223. if ((this->getValueBits() & set_in_both) !=
  224. ((~other.getValueBits()) & set_in_both)) {
  225. // return false;
  226. return FALSE;
  227. }
  228. unsigned int result_set=
  229. this->getSetBits() | other.getSetBits();
  230. unsigned int result_value=
  231. this->getValueBits() & (~(other.getValueBits()));
  232. return APMonom(result_set, result_value);
  233. }
  234. /**
  235. * Checks for equality.
  236. * @param other the other APMonom
  237. * @return <b>true</b> if this and the other APMonom are equal
  238. */
  239. bool operator==(const APMonom& other) const {
  240. return (this->getValueBits()==other.getValueBits()) &&
  241. (this->getSetBits()==other.getSetBits());
  242. }
  243. /**
  244. * Output APMonom on an ostream.
  245. * @param out the output stream
  246. * @param m the APMonom
  247. */
  248. friend std::ostream& operator<<(std::ostream& out,
  249. const APMonom& m) {
  250. if (m.isTrue()) {
  251. out << "true";
  252. } else if (m.isFalse()) {
  253. out << "false";
  254. } else {
  255. for (unsigned int i=0;i<32;i++) {
  256. if (m.isSet(i)) {
  257. if (m.getValue(i)) {
  258. out << "+" << i;
  259. } else {
  260. out << "-" << i;
  261. }
  262. }
  263. }
  264. }
  265. return out;
  266. }
  267. /** An APMonom representing TRUE */
  268. static const APMonom TRUE;
  269. /** An APMonom representing FALSE */
  270. static const APMonom FALSE;
  271. private:
  272. /** The bitset for the values */
  273. SimpleBitSet bits_value;
  274. /** The bitset for the occurence */
  275. SimpleBitSet bits_set;
  276. /** Checks to see if the bitset representation is normalized. */
  277. bool isNormalized() {
  278. if (isTrue() || isFalse()) {
  279. return true;
  280. }
  281. return (bits_value.getBitSet() & ~(bits_set.getBitSet())) == 0;
  282. }
  283. };
  284. #endif