/* Copyright (c) 1997-2005
   Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
   http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.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.
*/

#ident "$Project: polymake $$Id: morse_matching_size.cc,v 1.3 2006/01/20 14:26:06 gawrilow Exp $"


#include <Poly.h>
#include <HasseDiagram.h>

#include <morse_matching_tools.h>


using namespace polymake;




/** @file morse_matching_size
 *
 *  Input: Morse matching
 *
 *  Output: size of the Morse matching
 *
 *  @client   morse_matching_size
 *  @synopsis morse_matching_size <file>
 *
 *  @reading  MORSE_MATCHING
 *  @writing  MORSE_MATCHING_SIZE
 *
 *  @author   Marc Pfetsch
 *  @date     Fall 2005
 */

int main(int argc, const char* argv[])
{
   typedef Entire<HasseDiagram<Set<int>,bool>::out_edge_list>::const_iterator HasseDiagramOutConstIterator;

   if (argc != 2)
   {
      cerr << "usage: " << argv[0] << " <file> " << endl;
      return 1;
   }

   // read Hasse diagram
   try
   {
      Poly p(argv[1], ios::in | ios::out);
      HasseDiagram<Set<int>,bool> M;

      // read Morse
      int size = 0;       // size of the matching
      if ( p.exists("MORSE_MATCHING") )
      {
	 p.give("MORSE_MATCHING") >> M;
	 int d = M.dim() - 1;

	 // compute size of matching
	 for (int k = 0; k <= d; ++k)
	 {
	    for (Entire<sequence>::const_iterator f = entire(M.nodes_of_dim(k)); !f.at_end(); ++f)
	    {
	       if ( k < d )
	       {
		  for (HasseDiagramOutConstIterator e = entire(M.out_edges(*f)); !e.at_end(); ++e)
		  {
		     if ( *e )
			++size;
		  }
	       }
	    }
	 }
	 // write Morse Matching
	 p.take("MORSE_MATCHING_SIZE") << size;
      }
   }
   catch (const std::exception& e)
   {
      std::cerr << e.what() << endl;
      abort();
   }

   return 0;
}
