OKlibrary  0.2.1.6
ClauseSet.hpp
Go to the documentation of this file.
00001 // Oliver Kullmann, 27.2.2002 (Swansea)
00002 /* Copyright 2002 - 2007, 2011 Oliver Kullmann
00003 This file is part of the OKlibrary. OKlibrary is free software; you can redistribute
00004 it and/or modify it under the terms of the GNU General Public License as published by
00005 the Free Software Foundation and included in this library; either version 3 of the
00006 License, or any later version. */
00007 
00014 #ifndef WAECHTERCLAUSESET_hbew90
00015 #define WAECHTERCLAUSESET_hbew90
00016 
00017 #include <set>
00018 #include <numeric>
00019 #include <iostream>
00020 #include <iterator>
00021 #include <algorithm>
00022 
00023 #include <OKlib/Satisfiability/ProblemInstances/Variables/VarSet.hpp>
00024 #include <OKlib/Satisfiability/ProblemInstances/Literals/Literal.hpp>
00025 #include <OKlib/Satisfiability/ProblemInstances/Clauses/Clause.hpp>
00026 
00027 namespace Clausesets {
00028 
00029   using namespace Variables;
00030   using namespace Literals;
00031 
00032   class Cls {
00033     typedef Clauses::Cl clause_type;
00034     typedef std::set<clause_type> clauseset_t;
00035     clauseset_t cls;
00036   public :
00037     typedef clauseset_t::const_iterator iterator;
00038     typedef iterator const_iterator;
00039     Cls () {}
00040     Cls (const clauseset_t&);
00041     Cls& read(Var_Set&); // input from standard input in 
00042     // "generalised DIMACS format";
00043     // arbitrary (non-empty) strings are allowed as names except 
00044     // of "p" and "c"
00045     std::set<Var> var() const;
00046     Clauses::Litset lit() const;
00047     bool is_empty() const;
00048     bool empty_clause() const;
00049     Clauses::size_type n() const;
00050     Clauses::size_type c() const;
00051     Clauses::size_type c(Clauses::size_type) const;
00052     unsigned long int l() const;
00053     Clauses::size_type pmin() const;
00054     Clauses::size_type pmax() const;
00055     Cls& add(const clause_type&);
00056     Cls& remove(const clause_type&);
00057     bool operator ==(const Cls&) const;
00058     const Cls operator +(const Cls&) const;
00059     const Cls operator -(const Cls&) const;
00060     const Cls operator &(const Cls&) const;
00061     const clauseset_t& clauseset() const { return cls; }
00062   };
00063 
00064   inline Cls::Cls(const std::set<Clauses::Cl>& F) { cls = F; }
00065 
00066   inline Cls& Cls::read(Var_Set& V) {
00067     Clauses::Litset C;
00068     std::string s;
00069     char c;
00070 
00071     while (std::cin >> s) {
00072       if (s == "c" || s == "p") {
00073         while (std::cin.get(c)) if (c == '\n') break;
00074         if (! std::cin) break;
00075         else continue;
00076       }
00077       else if (s == "0") {
00078         if (! C.tautological()) cls.insert(C);
00079         C = Clauses::Litset();
00080       }
00081       else if (s[0] == '-')
00082         C.add(Lit(V.get_var(s.substr(1)), true));
00083       else
00084         C.add(Lit(V.get_var(s), false));
00085     }
00086     return *this;
00087   }
00088 
00089   inline const Clauses::Litset& acc_plus(Clauses::Litset& A, const Clauses::Cl& B) {
00090     return A.add_ls((B));
00091   }
00092   inline Clauses::Litset Cls::lit() const {
00093     return accumulate(cls.begin(), cls.end(), Clauses::Litset(), acc_plus);
00094   }
00095   inline std::set<Var> Cls::var() const { return this -> lit().var(); }
00096   inline bool Cls::is_empty() const { return cls.empty(); }
00097   inline bool Cls::empty_clause() const {
00098     if (cls.empty()) return false;
00099     return cls.begin() -> empty();
00100     // setzt voraus, dass die leere Klausel ganz vorne in cls abgelegt wird
00101   }
00102   inline Clauses::size_type Cls::n() const { return this -> var().size(); }
00103   inline Clauses::size_type Cls::c() const { return cls.size(); }
00104   inline bool has_length(const Clauses::Cl& C, Clauses::size_type k = 0) {
00105     static Clauses::size_type kfixed;
00106     if (k != 0) {
00107       kfixed = k;
00108       return false;
00109     }
00110     else
00111       return C.size() == kfixed;
00112   }
00113   inline Clauses::size_type Cls::c(const Clauses::size_type k) const {
00114     has_length(Clauses::Cl(), k);
00115     return count_if(cls.begin(), cls.end(), has_length);
00116   }
00117   inline Clauses::size_type length_plus(const Clauses::size_type a, const Clauses::Cl& B) {
00118     return a + B.size();
00119   }
00120   inline unsigned long int Cls::l() const {
00121     return accumulate(cls.begin(), cls.end(), 0, length_plus);
00122   }
00123   inline Clauses::size_type Cls::pmin() const {
00124     Clauses::size_type minl = Clauses::max_length;
00125     for (std::set<Clauses::Cl>::iterator i = cls.begin(); i != cls.end(); ++i)
00126       minl = std::min(minl, i->size());
00127     return minl;
00128   }
00129   inline Clauses::size_type Cls::pmax() const {
00130     Clauses::size_type maxl = 0;
00131     for (std::set<Clauses::Cl>::iterator i = cls.begin(); i != cls.end(); ++i)
00132       maxl = std::max(maxl, i->size());
00133     return maxl;
00134   }
00135   inline Cls& Cls::add(const Clauses::Cl& C) {
00136     cls.insert(C);
00137     return *this;
00138   }
00139   inline Cls& Cls::remove(const Clauses::Cl& C) {
00140     cls.erase(C);
00141     return *this;
00142   }
00143   inline bool Cls::operator ==(const Cls& F) const { return F.cls == cls; }
00144   inline const Cls Cls::operator +(const Cls& F) const {
00145     std::set<Clauses::Cl> result;
00146     std::insert_iterator< std::set<Clauses::Cl> > res_ins(result, result.begin());
00147     std::set_union(cls.begin(), cls.end(), F.cls.begin(), F.cls.end(), res_ins);
00148     return Cls(result);
00149   }
00150   inline const Cls Cls::operator -(const Cls& F) const {
00151     std::set<Clauses::Cl> result;
00152     std::insert_iterator< std::set<Clauses::Cl> > res_ins(result, result.begin());
00153     std::set_difference(cls.begin(), cls.end(), F.cls.begin(), F.cls.end(), res_ins);
00154     return result;
00155   }
00156   inline const Cls Cls::operator & (const Cls& F) const {
00157     std::set<Clauses::Cl> result;
00158     std::insert_iterator< std::set<Clauses::Cl> > res_ins(result, result.begin());
00159     std::set_intersection(cls.begin(), cls.end(), F.cls.begin(), F.cls.end(), res_ins);
00160     return result;
00161   }
00162 
00163 }
00164 
00165 #endif