/* Copyright (c) 1997-2006
   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: t_staircase.cc,v 1.2 2006/03/09 16:21:35 gawrilow Exp $"

#include <Poly.h>
#include <Integer.h>
#include <Array.h>
#include <PowerSet.h>

namespace polymake {
namespace topaz {

namespace {
   // m_set is an m-element set of {0,...,m+n-1}
   Array<bool> shuffle_from_m_set(const int m, const int n, const Set<int>& m_set) {
      Array<bool> shuffle(m+n+2,false);
      for (Entire< Set<int> >::const_iterator it=entire(m_set); !it.at_end(); ++it)
	 shuffle[*it]=true;
      return shuffle;
   }

   // m_set is an m-element set of {0,...,m+n-1}
   Set<int> staircase(const int m, const int n, const Set<int>& m_set) {
      Array<bool> m_shuffle=shuffle_from_m_set(m,n,m_set);
      Set<int> facet=sequence(0,1);
      
      for (int i=0, x=0, y=0; i<m+n; ++i) {
	 if (m_shuffle[i]) x+=1;
	 else y+=1;
	 facet.push_back(x+y*(m+1));
      }

      return facet;
   }
}

void t_staircase(Poly& p, const int m, const int n)
{
   const int b=Integer::binom(m+n,m);
   Array< Set<int> > triangulation(b);
   int i=0;

   Subsets_of_k<sequence> enumerator(range(0,m+n-1), m);
   for (Subsets_of_k<sequence>::iterator s=entire(enumerator); i<b; ++s, ++i)
      triangulation[i]=staircase(m,n,*s);

   p.take("FACETS") << triangulation;
}

} }

using namespace polymake;

/** @file t_staircase
 *
 *  Produce the staircase triangulation of the product of simplices Delta_m x Delta_n.
 *
 *  @synopsis t_staircase <file> <m> <n>
 *
 *  @writing  FACETS
 */

int main(int argc, const char* argv[])
{
   if (argc != 4) {
      cerr << "usage: " << argv[0] << " <file> <m> <n>" << endl;
      return 1;
   }
   int m=atoi(argv[2]), n=atoi(argv[3]);
   if (m<0 || n< 0) {
      cerr << argv[0] << ": m,n must be non-negative" << endl;
      return 1;
   }
   try {
      Poly p(argv[1], ios::out | ios::trunc, "topaz::default");
      topaz::t_staircase(p,m,n);
   } 
   catch (const std::exception& e) {
     cerr << e.what() << endl;
     return 1;
   }
   return 0;
}


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