2  * File:   GroebnerBase.tpp
 
    5  * Created on 8. August 2016, 16:15
 
   13 template<typename Number>
 
   14 bool GroebnerBase<Number>::hasFiniteMon() const {
 
   15         std::set<Variable> vars = this->gatherVariables();
 
   16         std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
 
   17         for (const auto& v: vars) {
 
   19             for (const auto& m : lmons) {
 
   20                 assert(is_one(m.coeff()));
 
   21                 if (m.has_no_other_variable(v)) {
 
   26             if (found) return false;
 
   32 template<typename Number>
 
   33 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::cor() const {
 
   34         std::vector<typename GroebnerBase<Number>::Monomial> res;
 
   35         for(const auto& p : this->get()) {
 
   36                 res.push_back(GroebnerBase<Number>::Monomial(p.lmon()));
 
   41 // general helper function
 
   42 // returns true iff any of the monomials in list divides m
 
   43 template<typename Number>
 
   44 bool anyDivides(const std::vector<typename GroebnerBase<Number>::Monomial>& list, const typename GroebnerBase<Number>::Monomial& m) {
 
   45         CARL_LOG_ASSERT("carl.thom.groebner", is_one(m.coeff()), "invalid monomial!");
 
   46         for(const auto& m_prime : list) {
 
   47                 CARL_LOG_ASSERT("carl.thom.groebner", is_one(m_prime.coeff()), "invalid monomial!");
 
   48                 if(m.divisible(m_prime)) {
 
   57 // this is a helper function for mon
 
   58 template<typename Number> // i dont know why this has to be a template but i get a linker error if its not
 
   59 bool nextTuple(std::vector<carl::uint>& tuple, const std::vector<carl::uint>& maxTuple) {
 
   60         assert(tuple.size() == maxTuple.size());
 
   61         if(tuple[0] < maxTuple[0]) {
 
   66                 assert(tuple[0] == maxTuple[0]);
 
   68                 for(carl::uint i = 1; i < tuple.size(); i++) {
 
   69                         if(tuple[i] < maxTuple[i]) {
 
   70                                 for(carl::uint j = 0; j < i; j++) tuple[j] = 0;
 
   82 template<typename Number>
 
   83 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::mon() const {
 
   84         CARL_LOG_FUNC("carl.thom.groebner", "groebner base: " << this->get());
 
   85         CARL_LOG_ASSERT("carl.thom.groebner", this->hasFiniteMon(), "tried to compute mon of non-zerodimensional system"); 
 
   86         std::set<Variable> varsset = this->gatherVariables();
 
   87         std::vector<Variable> vars(varsset.begin(), varsset.end());
 
   88         std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
 
   89         std::vector<uint> degrees;
 
   90         for(const auto& v : vars) {
 
   91                 for(const auto& m : lmons) {
 
   92                         CARL_LOG_ASSERT("carl.thom.groebner", is_one(m.coeff()), "invalid monomial!");
 
   93                         if(m.has_no_other_variable(v)) {
 
   94                                 degrees.push_back(m.monomial()->tdeg());
 
   99         CARL_LOG_ASSERT("carl.thom.groebner", degrees.size() == vars.size(), "");
 
  100         CARL_LOG_TRACE("carl.thom.groebner", "variables: " << vars);
 
  101         CARL_LOG_TRACE("carl.thom.groebner", "vector of degrees: " << degrees);
 
  103         std::vector<typename GroebnerBase<Number>::Monomial> res;
 
  104         std::vector<uint> currTuple(degrees.size(), 0);
 
  106                 typename GroebnerBase<Number>::Monomial candidate(Number(1));
 
  107                 for(uint i = 0; i < currTuple.size(); i++) {
 
  108                         for(uint d = 0; d < currTuple[i]; d++) {
 
  109                                 candidate = candidate * vars[i];
 
  112                 if(!anyDivides<Number>(lmons, candidate)) {
 
  113                         res.push_back(candidate);
 
  116         while(::nextTuple<Number>(currTuple, degrees));
 
  117         CARL_LOG_TRACE("carl.thom.groebner", "result: " << res);
 
  121 template<typename Number>
 
  122 std::vector<typename GroebnerBase<Number>::Monomial> GroebnerBase<Number>::bor() const {
 
  123         std::vector<typename GroebnerBase<Number>::Monomial> res;
 
  124         std::vector<typename GroebnerBase<Number>::Monomial> lmons = this->cor();
 
  125         std::set<Variable> vars = this->gatherVariables();
 
  126         std::vector<typename GroebnerBase<Number>::Monomial> _mon = this->mon();
 
  127         for(const Variable& v : vars) {
 
  128                 for(const auto& m : _mon) {
 
  129                         assert(is_one(m.coeff()));
 
  130                         typename GroebnerBase<Number>::Monomial currMon = m * v;
 
  131                         if(std::find(res.begin(), res.end(), currMon) == res.end()) { // not already contained in res
 
  132                                 if(std::find(_mon.begin(), _mon.end(), currMon) == _mon.end()) { // not contained in _mon
 
  133                                         res.push_back(currMon);
 
  141 template<typename Number>
 
  142 std::set<Variable> GroebnerBase<Number>::gatherVariables() const {
 
  144         for(const auto& p : this->get()) {
 
  145                 carl::variables(p, vars);
 
  147         return vars.as_set();