00001
00002
00003
00004
00005
00006 #ifndef __formula__
00007 #define __formula__
00008
00009
00010 #include "Atom.hpp"
00011
00012
00013 class Position;
00014 class Substitution;
00015 class FormulaList;
00016 class InferenceList;
00017
00018
00019 class Formula
00020 {
00021 private:
00022 class Data;
00023 class AtomicData;
00024 class UnaryData;
00025 class BinaryData;
00026 class QuantifiedData;
00027 class JunctionData;
00028
00029 public:
00035 enum Connective {
00036 ATOM = 0,
00037 AND = 1,
00038 OR = 2,
00039 IMP = 3,
00040 IFF = 4,
00041 XOR = 5,
00042 NOT = 6,
00043 FORALL = 7,
00044 EXISTS = 8
00045 };
00046
00047 public:
00048
00049 Formula ();
00050 Formula (const Formula& f);
00051 ~Formula ();
00052 void operator= (const Formula& rhs);
00053 Formula ( Connective c, const Formula& l, const Formula& r);
00054 Formula ( Connective c, const Formula& a );
00055 Formula ( Connective c, const FormulaList& fs );
00056 Formula (Connective c, const VarList& vs, const Formula& a);
00057 explicit Formula ( const Atom& a );
00058 void makeJunction (Connective c, Formula& lhs, Formula& rhs);
00059
00060
00061 Connective connective () const;
00062 const FormulaList& args () const;
00063 const Formula& left () const;
00064 const Formula& right () const;
00065 const Formula& qarg () const;
00066 const VarList& vars () const;
00067 const Formula& uarg () const;
00068 const Atom& atom () const;
00069 bool operator == (const Formula& rhs) const;
00070 bool isNull () const;
00071 void makeNull ();
00072
00073
00074 void* operator new (size_t);
00075
00076
00077 bool isEqualityAxiom () const;
00078 bool hasFreeVars () const;
00079 void flatten ();
00080 void ennf (bool polarity);
00081 void rectify ();
00082 void rectify (VarList& originalVars, TermList& answerAtom);
00083 void rectify (Substitution&, Var& last, VarList& freeVars);
00084 void removeIff ();
00085 void skolemizeNNF ();
00086 void skolemizeNNF (Substitution& subst, VarList);
00087 bool isPredicateDefinition (Atom& lhs, Formula& rhs ) const;
00088 bool isFunctionDefinition (Term& lhs, Term& rhs) const;
00089 bool occurs (const Signature::Pred* p) const;
00090 int universalPrefixLength () const;
00091
00092
00093 void miniscope (InferenceList&);
00094 void miniscope (InferenceList&, const Position&);
00095 void occurring (const VarList& input,
00096 VarList& output,
00097 VarList& removedVars) const;
00098 void topMiniscope (Connective, const VarList&,
00099 InferenceList&, const Position&);
00100 private:
00101
00102 Data* _data;
00103
00104
00105 bool hasFreeVars (VarListList) const;
00106
00107
00108 bool isReflexivityAxiom () const;
00109 bool isFunctionReflexivityAxiom () const;
00110 bool isPredicateReflexivityAxiom () const;
00111 bool isSymmetryAxiom () const;
00112 bool isTransitivityAxiom () const;
00113
00114
00115 void occurring (bool* occurrences, Var max) const;
00116 static void splitVarList (const VarList& in,
00117 VarList& out,
00118 VarList& removed,
00119 bool* occurrences);
00120 };
00121
00122
00123 class FormulaList
00124 : public Lst <Formula>
00125 {
00126 public:
00127
00128 FormulaList ();
00129 FormulaList (const FormulaList&);
00130 explicit FormulaList (const Formula& t);
00131 FormulaList (const Formula& head, const FormulaList& tail);
00132 explicit FormulaList (LstData<Formula>*);
00133
00134
00135 const FormulaList& tail () const
00136 { return static_cast<const FormulaList&>(Lst<Formula>::tail()); }
00137
00138
00139 void flatten (Formula::Connective);
00140 void ennf (Formula::Connective andOr, bool polarity);
00141 void rectify (Substitution&, Var& last, VarList& freeVars);
00142 void removeIff ();
00143 void skolemizeNNF (Substitution& subst, VarList);
00144 void miniscope (Formula::Connective con,
00145 InferenceList&, const Position&,
00146 int argNumber,
00147 const FormulaList& lst);
00148 void topMiniscope (Formula::Connective,
00149 const VarList& vars,
00150 InferenceList& inf,
00151 const Position& pos,
00152 int index);
00153 static void appendN (const FormulaList& fst,
00154 const FormulaList& snd,
00155 int N,
00156 FormulaList& result);
00157 };
00158
00159
00160 class Formula::Data
00161 {
00162 public:
00163 Data (Connective c);
00164 ~Data ();
00165
00166 void ref ();
00167 void deref ();
00168
00169 Connective connective () const;
00170
00171 protected:
00172
00173 int _counter;
00174 Connective _connective;
00175
00176
00177 void destroy ();
00178 };
00179
00180
00181 class Formula::AtomicData :
00182 public Formula::Data
00183 {
00184 public:
00185 explicit AtomicData (const Atom& atom);
00186
00187 const Atom& atom () const;
00188
00189 protected:
00190
00191 Atom _atom;
00192 };
00193
00194
00195 class Formula::UnaryData :
00196 public Formula::Data
00197 {
00198 public:
00199 UnaryData (Connective c, const Formula& arg);
00200
00201 const Formula& arg () const;
00202
00203 protected:
00204
00205 Formula _arg;
00206 };
00207
00208
00209 class Formula::BinaryData :
00210 public Formula::Data
00211 {
00212 public:
00213 BinaryData (Connective c, const Formula& lhs, const Formula& rhs);
00214
00215 const Formula& left () const;
00216 const Formula& right () const;
00217
00218 protected:
00219
00220 Formula _lhs;
00221 Formula _rhs;
00222 };
00223
00224
00225 class Formula::JunctionData :
00226 public Formula::Data
00227 {
00228 public:
00229 JunctionData (Connective c, const FormulaList& lhs);
00230
00231 const FormulaList& args () const;
00232
00233 protected:
00234
00235 FormulaList _args;
00236 };
00237
00238
00239 class Formula::QuantifiedData :
00240 public Formula::Data
00241 # if DEBUG_PREPRO
00242 , public Memory <CID_QFORMULA>
00243 # endif
00244 {
00245 public:
00246 QuantifiedData (Connective c, const VarList& vs, const Formula& arg);
00247
00248 const Formula& arg () const;
00249 const VarList& vars () const;
00250
00251 protected:
00252
00253 VarList _vars;
00254 Formula _arg;
00255 };
00256
00257
00258
00259
00260 inline
00261 Formula::Formula ()
00262 :
00263 _data (0)
00264 {
00265 }
00266
00267
00268
00269 inline
00270 bool Formula::isNull () const
00271 {
00272 return _data == 0;
00273 }
00274
00275
00276
00277
00278 inline
00279 Formula::Formula (Connective c, const VarList& vs, const Formula& a)
00280 :
00281 _data (new QuantifiedData(c,vs,a))
00282 {
00283 }
00284
00285
00286
00287
00288 inline
00289 Formula::Formula (const Atom& atom)
00290 :
00291 _data (new AtomicData(atom))
00292 {
00293 }
00294
00295
00296
00297
00298 inline
00299 Formula::Formula (Connective c, const Formula& arg)
00300 :
00301 _data (new UnaryData(c,arg))
00302 {
00303 }
00304
00305
00306
00307
00308 inline
00309 Formula::Formula (Connective c, const Formula& lhs, const Formula& rhs)
00310 :
00311 _data (new BinaryData(c,lhs,rhs))
00312 {
00313 }
00314
00315
00316
00317
00318 inline
00319 Formula::Formula (Connective c, const FormulaList& args)
00320 :
00321 _data (new JunctionData(c,args))
00322 {
00323 }
00324
00325
00326 inline
00327 Formula::~Formula ()
00328 {
00329 if (_data) {
00330 _data->deref ();
00331 }
00332 }
00333
00334
00335
00336 inline
00337 Formula::Formula (const Formula& t)
00338 :
00339 _data (t._data)
00340 {
00341 if (_data) {
00342 _data->ref ();
00343 }
00344 }
00345
00346
00347 inline
00348 bool Formula::operator == (const Formula& rhs) const
00349 {
00350 ASS (_data && rhs._data);
00351
00352 return _data == rhs._data;
00353 }
00354
00355
00356 inline
00357 Formula::Connective Formula::connective () const
00358 {
00359 return _data->connective();
00360 }
00361
00362
00363 inline
00364 const Atom& Formula::atom () const
00365 {
00366 ASS (connective() == ATOM);
00367
00368 return (static_cast<AtomicData*>(_data))->atom();
00369 }
00370
00371
00372 inline
00373 const FormulaList& Formula::args () const
00374 {
00375 ASS (connective() == AND || connective() == OR);
00376
00377 return (static_cast<JunctionData*>(_data))->args();
00378 }
00379
00380
00381 inline
00382 const Formula& Formula::left () const
00383 {
00384 ASS (connective() == IFF ||
00385 connective() == XOR ||
00386 connective() == IMP);
00387
00388 return (static_cast<BinaryData*>(_data))->left();
00389 }
00390
00391
00392 inline
00393 const Formula& Formula::right () const
00394 {
00395 ASS (connective() == IFF ||
00396 connective() == XOR ||
00397 connective() == IMP);
00398
00399 return (static_cast<BinaryData*>(_data))->right();
00400 }
00401
00402
00403 inline
00404 const Formula& Formula::uarg () const
00405 {
00406 ASS (connective() == NOT);
00407
00408 return (static_cast<UnaryData*>(_data))->arg();
00409 }
00410
00411
00412 inline
00413 const Formula& Formula::qarg () const
00414 {
00415 ASS (connective() == FORALL || connective() == EXISTS);
00416
00417 return (static_cast<QuantifiedData*>(_data))->arg();
00418 }
00419
00420
00421 inline
00422 const VarList& Formula::vars () const
00423 {
00424 ASS (connective() == FORALL || connective() == EXISTS);
00425
00426 return (static_cast<QuantifiedData*>(_data))->vars();
00427 }
00428
00429
00430
00431
00432 inline
00433 Formula::Data::Data (Connective c)
00434 :
00435 _counter (1),
00436 _connective (c)
00437 {
00438 }
00439
00440
00441 inline
00442 Formula::Data::~Data ()
00443 {
00444 TRACER( "Formula::Data::~Data" );
00445
00446 ASS (_counter == 0);
00447 }
00448
00449
00450 inline
00451 void Formula::Data::ref ()
00452 {
00453 ASS (this);
00454
00455 _counter++;
00456 }
00457
00458
00459 inline
00460 void Formula::Data::deref ()
00461 {
00462 ASS (this);
00463 ASS (_counter > 0);
00464 _counter--;
00465
00466 if (_counter == 0) {
00467 destroy ();
00468 }
00469 }
00470
00471
00472 inline
00473 Formula::Connective Formula::Data::connective () const
00474 {
00475 ASS (this);
00476
00477 return _connective;
00478 }
00479
00480
00481
00482
00483
00484 inline
00485 Formula::AtomicData::AtomicData (const Atom& atom)
00486 :
00487 Data (ATOM),
00488 _atom (atom)
00489 {
00490 }
00491
00492
00493 inline
00494 const Atom& Formula::AtomicData::atom () const
00495 {
00496 return _atom;
00497 }
00498
00499
00500
00501
00502
00503 inline
00504 Formula::UnaryData::UnaryData (Connective c,
00505 const Formula& arg)
00506 :
00507 Data (c),
00508 _arg (arg)
00509 {
00510 ASS ( c == NOT );
00511 }
00512
00513
00514 inline
00515 const Formula& Formula::UnaryData::arg () const
00516 {
00517 return _arg;
00518 }
00519
00520
00521
00522
00523
00524 inline
00525 Formula::BinaryData::BinaryData (Connective c,
00526 const Formula& lhs,
00527 const Formula& rhs)
00528 :
00529 Data (c),
00530 _lhs (lhs),
00531 _rhs (rhs)
00532 {
00533 ASS ( c == IMP || c == IFF || c == XOR );
00534 }
00535
00536
00537 inline
00538 const Formula& Formula::BinaryData::left () const
00539 {
00540 return _lhs;
00541 }
00542
00543
00544 inline
00545 const Formula& Formula::BinaryData::right () const
00546 {
00547 return _rhs;
00548 }
00549
00550
00551
00552
00553
00554 inline
00555 Formula::JunctionData::JunctionData (Connective c, const FormulaList& args)
00556 :
00557 Data (c),
00558 _args (args)
00559 {
00560 ASS ( c == AND || c == OR );
00561 }
00562
00563
00564 inline
00565 const FormulaList& Formula::JunctionData::args () const
00566 {
00567 return _args;
00568 }
00569
00570
00571
00572
00573
00574 inline
00575 Formula::QuantifiedData::QuantifiedData (Connective c,
00576 const VarList& vs,
00577 const Formula& arg)
00578 :
00579 Data (c),
00580 _vars (vs),
00581 _arg (arg)
00582 {
00583 ASS ( c == FORALL || c == EXISTS );
00584 }
00585
00586
00587 inline
00588 const Formula& Formula::QuantifiedData::arg () const
00589 {
00590 return _arg;
00591 }
00592
00593
00594 inline
00595 const VarList& Formula::QuantifiedData::vars () const
00596 {
00597 return _vars;
00598 }
00599
00600
00601
00602
00603 inline
00604 FormulaList::FormulaList ()
00605 :
00606 Lst<Formula> ()
00607 {
00608 }
00609
00610
00611
00612
00613 inline
00614 FormulaList::FormulaList (const FormulaList& ts)
00615 :
00616 Lst<Formula> (ts)
00617 {
00618 }
00619
00620
00621
00622
00623 inline
00624 FormulaList::FormulaList (LstData<Formula>* d)
00625 :
00626 Lst<Formula> (d)
00627 {
00628 }
00629
00630
00631
00632
00633 inline
00634 FormulaList::FormulaList (const Formula &hd, const FormulaList& tl)
00635 :
00636 Lst<Formula> (hd,tl)
00637 {
00638 }
00639
00640
00641
00642
00643 inline
00644 FormulaList::FormulaList (const Formula &hd)
00645 :
00646 Lst<Formula> (hd)
00647 {
00648 }
00649
00650
00651 #endif // __formula__