1 /* Copyright (c) 1997-2021
2    Ewgenij Gawrilow, Michael Joswig, and the polymake team
3    Technische Universität Berlin, Germany
4    https://polymake.org
5 
6    This program is free software; you can redistribute it and/or modify it
7    under the terms of the GNU General Public License as published by the
8    Free Software Foundation; either version 2, or (at your option) any
9    later version: http://www.gnu.org/licenses/gpl.txt.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 --------------------------------------------------------------------------------
16 */
17 
18 #pragma once
19 
20 namespace polymake { namespace matroid {
21 
22 namespace operations {
23 
24 using namespace polymake::operations;
25 
26 template <typename SetRef>
27 struct contains {
28    typedef typename pm::deref<SetRef>::type set_type;
29    typedef set_type argument_type;
30    typedef bool result_type;
31    typedef typename pm::deref<SetRef>::type::element_type element_type;
32 
33    element_type elem;
34 
elemcontains35    contains(element_type e = element_type()) : elem(e) {}
36 
operatorcontains37    result_type operator() (typename pm::function_argument<SetRef>::const_type set) const
38    {
39       return set.contains(elem);
40    }
41 };
42 
43 template <typename Scalar>
44 struct dropshift {
45    typedef typename pm::deref<Scalar>::type scalar_type;
46    scalar_type elem;
47 public:
48    typedef scalar_type argument_type;
49    typedef scalar_type result_type;
50 
elemdropshift51    dropshift(scalar_type e = scalar_type()) : elem(e) {}
52 
operatordropshift53    result_type operator() (argument_type value) const
54    {
55       return value < elem ? value : value-1;
56    }
57 };
58 
59 }
60 
61 template <typename Container>
62 auto
63 select_k(const Container& sets, const Int k,
64          std::enable_if_t<pm::isomorphic_to_container_of<Container, Set<Int>>::value, std::nullptr_t> = nullptr)
65 {
66    return pm::SelectedSubset<const Container&, operations::contains<Set<Int>>>(sets, operations::contains<Set<Int>>(k));
67 }
68 
69 template <typename Container>
70 auto
71 select_not_k(const Container& sets, const Int k,
72              std::enable_if_t<pm::isomorphic_to_container_of<Container, Set<Int>>::value, std::nullptr_t> = nullptr)
73 {
74    return pm::SelectedSubset<const Container&, operations::composed11<operations::contains<Set<Int>>, std::logical_not<bool>>>(sets, operations::composed11<operations::contains<Set<Int>>, std::logical_not<bool>>(operations::contains<Set<Int>>(k), std::logical_not<bool>()));
75 }
76 
77 template <typename Container>
drop_shift(const Container & sets,const Int k)78 auto drop_shift(const Container& sets, const Int k)
79 {
80    return attach_operation(
81             attach_operation(sets, pm::operations::construct_unary2_with_arg< pm::SelectedSubset, operations::fix2<Int, operations::ne> >(operations::fix2<Int, operations::ne>(k))),
82               pm::operations::construct_unary2_with_arg<pm::TransformedContainer, operations::dropshift<Int>>(operations::dropshift<Int>(k)));
83 }
84 
85 template <typename Container>
86 Array<Set<Int>>
shift_elements(const Container & sets,const Int n)87 shift_elements(const Container& sets, const Int n)
88 {
89    return Array<Set<Int>>{ attach_operation(sets,
90                                             pm::operations::construct_unary2_with_arg<pm::TransformedContainer,
91                                             operations::fix2<Int, operations::add> >(operations::fix2<Int, operations::add>(n))) };
92 }
93 
94 }}
95 
96 
97 // Local Variables:
98 // mode:C++
99 // c-basic-offset:3
100 // indent-tabs-mode:nil
101 // End:
102