OKlibrary
0.2.1.6
|
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