dlvhex  2.5.0
src/AtomSet.cpp
Go to the documentation of this file.
00001 /* dlvhex -- Answer-Set Programming with external interfaces.
00002  * Copyright (C) 2005-2007 Roman Schindlauer
00003  * Copyright (C) 2006-2015 Thomas Krennwallner
00004  * Copyright (C) 2009-2016 Peter Schüller
00005  * Copyright (C) 2011-2016 Christoph Redl
00006  * Copyright (C) 2015-2016 Tobias Kaminski
00007  * Copyright (C) 2015-2016 Antonius Weinzierl
00008  *
00009  * This file is part of dlvhex.
00010  *
00011  * dlvhex is free software; you can redistribute it and/or modify it
00012  * under the terms of the GNU Lesser General Public License as
00013  * published by the Free Software Foundation; either version 2.1 of
00014  * the License, or (at your option) any later version.
00015  *
00016  * dlvhex is distributed in the hope that it will be useful, but
00017  * WITHOUT ANY WARRANTY; without even the implied warranty of
00018  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019  * Lesser General Public License for more details.
00020  *
00021  * You should have received a copy of the GNU Lesser General Public
00022  * License along with dlvhex; if not, write to the Free Software
00023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
00024  * 02110-1301 USA.
00025  */
00026 
00037 #ifdef HAVE_CONFIG_H
00038 #include "config.h"
00039 #endif                           // HAVE_CONFIG_H
00040 
00041 #include <vector>
00042 #include <algorithm>
00043 
00044 #include "dlvhex2/AtomSet.h"
00045 
00046 DLVHEX_NAMESPACE_BEGIN
00047 
00048 AtomSet::const_iterator
00049 AtomSet::begin() const
00050 {
00051     return const_iterator(atoms.begin());
00052 }
00053 
00054 
00055 AtomSet::const_iterator
00056 AtomSet::end() const
00057 {
00058     return const_iterator(atoms.end());
00059 }
00060 
00061 
00062 void
00063 AtomSet::clear()
00064 {
00065     atoms.clear();
00066 }
00067 
00068 
00069 bool
00070 AtomSet::empty() const
00071 {
00072     return atoms.empty();
00073 }
00074 
00075 
00076 size_t
00077 AtomSet::size() const
00078 {
00079     return atoms.size();
00080 }
00081 
00082 
00083 void
00084 AtomSet::insert(const AtomPtr& ap)
00085 {
00087 
00088     atoms.insert(ap);
00089 }
00090 
00091 
00092 void
00093 AtomSet::insert(const AtomSet& add)
00094 {
00095     atoms.insert(add.atoms.begin(), add.atoms.end());
00096 }
00097 
00098 
00099 AtomSet
00100 AtomSet::difference(const AtomSet& as) const
00101 {
00102     AtomSet res;
00103 
00104     //   std::set_difference(this->atoms.begin(), this->atoms.end(),
00105     //            as.atoms.begin(), as.atoms.end(),
00106     //            std::inserter(res.atoms, res.atoms.begin())
00107     //            );
00108 
00109     for (atomset_t::const_iterator a = atoms.begin();
00110         a != atoms.end();
00111     ++a) {
00112         if (as.atoms.find(*a) == as.atoms.end())
00113             res.atoms.insert(*a);
00114     }
00115 
00116     return res;
00117 }
00118 
00119 
00120 void
00121 AtomSet::matchPredicate(const std::string& pred,
00122 AtomSet& matched) const
00123 {
00125     for (atomset_t::const_iterator a = atoms.begin();
00126         a != atoms.end();
00127     a++) {
00128         if ((*a)->getPredicate() == pred)
00129             matched.atoms.insert(*a);
00130     }
00131 }
00132 
00133 
00134 void
00135 AtomSet::matchAtom(const AtomPtr& atom,
00136 AtomSet& matched) const
00137 {
00139     for (atomset_t::const_iterator a = atoms.begin();
00140         a != atoms.end();
00141     a++) {
00142         if ((*a)->unifiesWith(atom))
00143             matched.atoms.insert(*a);
00144     }
00145 }
00146 
00147 
00148 void
00149 AtomSet::accept(BaseVisitor& v) const
00150 {
00151     v.visit(this);
00152 }
00153 
00154 
00159 struct PredicateMatches : public std::binary_function<AtomPtr, std::string, bool>
00160 {
00161     bool
00162         operator() (const AtomPtr& g, const std::string& pred) const
00163     {
00164         return (g->getPredicate() == Term(pred));
00165     }
00166 };
00167 
00168 void
00169 AtomSet::remove(const std::string& pred)
00170 {
00171     atomset_t::iterator cur = atoms.begin();
00172 
00173     atomset_t::const_iterator last = atoms.end();
00174 
00175     while ((cur = std::find_if(cur, last, std::bind2nd(PredicateMatches(), pred))) != last) {
00176         atomset_t::iterator tmp = cur++;
00177 
00178         atoms.erase(tmp);
00179     }
00180 }
00181 
00182 
00183 void
00184 AtomSet::remove(const std::vector<std::string>& preds)
00185 {
00186     for (std::vector<std::string>::const_iterator predit = preds.begin();
00187         predit != preds.end();
00188     ++predit) {
00189         remove(*predit);
00190     }
00191 }
00192 
00193 
00194 void
00195 AtomSet::keep(const std::vector<std::string>& preds)
00196 {
00197     atomset_t::iterator cur = atoms.begin();
00198 
00199     atomset_t::const_iterator last = atoms.end();
00200 
00201     //
00202     // go through all atoms of this set
00203     //
00204     while (cur != last) {
00205         //
00206         // look if the current atom is in the filter set
00207         //
00208         if ((std::find_if(preds.begin(),
00209             preds.end(),
00210         std::bind1st(PredicateMatches(), *cur))) == preds.end()) {
00211             //
00212             // if not, delete this atom
00213             //
00214             atomset_t::iterator tmp = cur++;
00215 
00216             atoms.erase(tmp);
00217         }
00218         else {
00219             cur++;
00220         }
00221     }
00222 }
00223 
00224 
00225 void
00226 AtomSet::keepPos()
00227 {
00228     atomset_t::iterator cur = atoms.begin();
00229 
00230     atomset_t::const_iterator last = atoms.end();
00231 
00232     //
00233     // go through all atoms of this set
00234     //
00235     while (cur != last) {
00236         if ((*cur)->isStronglyNegated()) {
00237             atomset_t::iterator tmp = cur++;
00238 
00239             atoms.erase(tmp);
00240         }
00241         else {
00242             cur++;
00243         }
00244     }
00245 }
00246 
00247 
00252 struct AtomMatches : public std::binary_function<AtomPtr, Atom, bool>
00253 {
00254     bool
00255         operator() (const AtomPtr& g, const Atom& a) const
00256     {
00257         return (*g == a);
00258     }
00259 };
00260 
00261 bool
00262 AtomSet::isConsistent() const
00263 {
00264     atomset_t::iterator cur = atoms.begin();
00265 
00266     atomset_t::const_iterator last = atoms.end();
00267 
00268     //
00269     // go through all atoms of this set
00270     //
00271     while (cur != last) {
00272         Atom a(**cur);
00273         a.negate();
00274 
00275         //
00276         // see if 'cur' occurs negated (i.e., 'a') in the range of 'cur+1' to
00277         // 'last'
00278         //
00279         if (std::find_if(++cur, last, std::bind2nd(AtomMatches(), a)) != last)
00280             return false;
00281     }
00282 
00283     return true;
00284 }
00285 
00286 
00287 bool
00288 AtomSet::operator== (const AtomSet& atomset2) const
00289 {
00290     return ((this->size() == atomset2.size())
00291         && std::equal(this->begin(), this->end(), atomset2.begin()));
00292 }
00293 
00294 
00295 bool
00296 AtomSet::operator!= (const AtomSet& atomset2) const
00297 {
00298     return !(*this == atomset2);
00299 }
00300 
00301 
00302 int
00303 AtomSet::operator< (const AtomSet& atomset2) const
00304 {
00305                                  // <
00306     if (this->size() < atomset2.size()) {
00307         return true;
00308     }
00309                                  // >
00310     else if (this->size() > atomset2.size()) {
00311         return false;
00312     }
00313     else {                       // same size, they can still be < or >=
00314         // find first mismatch
00315         std::pair<AtomSet::const_iterator, AtomSet::const_iterator> result;
00316         result = std::mismatch(this->begin(), this->end(), atomset2.begin());
00317 
00318         // no mismatch: ==, otw. check if the found mismatch is < or >=
00319         return result.first == this->end() ? false : *result.first < *result.second;
00320     }
00321 }
00322 
00323 
00324 DLVHEX_NAMESPACE_END
00325 
00326 
00327 
00328 // vim:expandtab:ts=4:sw=4:
00329 // mode: C++
00330 // End: