#  Copyright (c) 1997-2009
#  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: set_types 9555 2010-03-09 22:00:06Z herr $


declare property_type Set<Element=Int> : c++ (operators => '@sets @compare') {

   user_method contains(*) : c++;

   user_method size() : c++;
}

# @category Set operations

user_function incl(Set,Set) : c++ (include => ["Set.h"]);


# @category Set operations

user_function range(Int,Int) : c++ (include => ["Set.h"]);


# @category Set operations

user_function sequence(Int,Int) : c++ (include => ["Set.h"]);

function permuted(Set, *) : c++;

function permuted_inv(Set, *) : c++;

# @category Set operations

user_function select_subset(*,*) : c++ (name => 'select', include => ["IndexedSubset.h"]);

declare property_type PowerSet<Element=Int> : Set<Set<Element>> : c++;

function permuted(PowerSet, *) : c++;

function permuted_inv(PowerSet, *) : c++;

# @category Set operations

user_function scalar2set(*) : c++ (include => ["Set.h"]);


# allow to write ~[0,1,2] in contexts where a Set<Int> is expected
function _construct_set($) : subst_const_op( ~ ) {
   if ($#{$_[0]} > 0) {
      new Set($_[0])
   } else {
      scalar2set(@{$_[0]});
   }
}

declare property_type FacetList : c++;

##################################################################################

declare property_type NonSymmetric : c++ (special => 'NonSymmetric', include => ["IncidenceMatrix.h"]);

declare property_type Symmetric : c++ (special => 'Symmetric', include => ["IncidenceMatrix.h"]);

declare property_type IncidenceMatrix<Sym=NonSymmetric> : c++ (operators => '@sets @compare | |= / /=') {

   method construct(Int,Int) : c++;

   user_method rows() : c++;

   user_method cols() : c++;

   user_method row($) : lvalue_opt : c++;

   user_method col($) : lvalue_opt : c++;

   user_method minor(*,*) : lvalue_opt : c++;

   method operator($,$) : lvalue_opt : c++;

   user_method squeeze() : non_const : void : c++;

   user_method squeeze_rows() : non_const : void : c++;

   user_method squeeze_cols() : non_const : void : c++;
}

function permuted_rows(IncidenceMatrix *) : c++;

function permuted_inv_rows(IncidenceMatrix *) : c++;

function permuted_cols(IncidenceMatrix *) : c++;

function permuted_inv_cols(IncidenceMatrix *) : c++;


# @category Linear Algebra

user_function transpose(IncidenceMatrix) : c++ (name => 'T');


##################################################################################

declare property_type Map<Key,Value> : c++ (operators => '@string') {

   method equal {
      my ($self, $m1, $m2)=@_;
      return 0 unless keys(%$m1) == keys(%$m2);
      my ($pk, $pv)=@{$self->param};
      while (my ($k1, $v1, $k2, $v2)=(each(%$m1), each(%$m2))) {
         return 0 unless $pk->equal->($k1,$k2) && $pv->equal->($v1,$v2);
      }
      1
   }
}

##################################################################################

declare property_type HashSet<Element> : c++ (name => 'hash_set', operators => '+= -= ^=');

declare property_type HashMap<Key,Value> : c++ (name => 'hash_map');


# Local Variables:
# mode: perl
# c-basic-offset:3
# End:
