/* Copyright (c) 1997-2010
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
   http://www.polymake.de

   This program is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by the
   Free Software Foundation; either version 2, or (at your option) any
   later version: http://www.gnu.org/licenses/gpl.txt.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
--------------------------------------------------------------------------------
   $Project: polymake $$Id: matroid_test.cc 9991 2010-12-12 23:36:28Z gawrilow $
*/

#include "polymake/client.h"
#include "polymake/Array.h"
#include "polymake/Set.h"

namespace polymake { namespace matroid {

bool matroid_test(const Array< Set<int> >& bases, bool print)
{
  Set< Set<int> > bases_set;
  const int rank=bases[0].size();
  for (Entire< Array<Set <int> > >::const_iterator i=entire(bases); !i.at_end(); ++i) {
    if((*i).size()!=rank) {
      cout << "Bases do not have the same cardinality."<<endl;
      return false;
    cout<<*i<<endl;
    }
    bases_set.insert(*i);
  }

  //test the Steiniz property
  for (Entire< Array<Set <int> > >::const_iterator i=entire(bases); !i.at_end(); ++i) 
    for (Entire< Array<Set <int> > >::const_iterator j=entire(bases); !j.at_end(); ++j) {
      const Set<int> diff=(*i-*j);
      for(Entire< Set<int> >::const_iterator k=entire(diff); !k.at_end(); ++k) {
        bool found=false;
        const Set<int> other_diff=*j-*i;
        for(Entire< Set<int> >::const_iterator l=entire(other_diff); !found && !l.at_end(); ++l)
          if (bases_set.contains(*i-*k+*l)) found=true;
        if (!found) {
          if (print) 
            cout << "No replacement found for "<<*k<<" in "<<*i<<" by any element of "<<*j<<"."<<endl;
          return false;
        }
      }
    }
  return true;
}

UserFunction4perl("# @category Others"
                  "# Tests whether the given //bases// do actually form the bases of a matroid.\n"
                  "# @param Array<Set<Int>> bases"
                  "# @option Bool print if set to true the output tells which condition fails;"
                  "#        default value is 0",
                  &matroid_test, "matroid_test($;$=0)");

} }

// Local Variables:
// mode:C++
// c-basic-offset:3
// indent-tabs-mode:nil
// End:
