// Copyright 2023 The Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef FAIR_SUBMODULAR_MATROID_MATROID_INTERSECTION_H_
#define FAIR_SUBMODULAR_MATROID_MATROID_INTERSECTION_H_

#include <set>
#include <vector>

#include "matroid.h"
#include "fairness_constraint.h"
#include "submodular_function.h"
#include "partition_matroid.h"

// Constructs a maximum cardinality set in the intersections of two matroids.
// The solution is constructed in place in both input matroid objects.
void MaxIntersection(Matroid* matroid_a,
                     Matroid* matroid_b,
                     const std::vector<int>& elements);

 // Constructs a *fair* maximum cardinality set in the intersections of two matroids.
std::vector<int> FairMaxIntersection(Matroid* matroid_a,
                      FairnessConstraint* fairness_constraint,
                      const std::vector<int>& elements);
    
void SubMaxIntersectionSwapping(Matroid* matroid_a,
                        Matroid* matroid_b,
                        SubmodularFunction* sub_func_f,
                        const std::vector<int>& universe);

// Runs the Greedy algorithm to choose feasible elements to add
std::vector<int> Greedy(Matroid* matroid_a,
                        Matroid* matroid_b,
                        SubmodularFunction* sub_func_f,
                        const std::vector<int>& universe);

// Returns a set of augmenting paths w.r.t set_Y and the intersection of a partition matroid and a fairness constraint.
std::vector<std::vector<int>> ReturnPaths(PartitionMatroid* matroid_a,
                        FairnessConstraint* fairness_constraints,
                        SubmodularFunction* sub_func_f,
                        const std::vector<int>& set_Y,
                        const std::vector<int>& set_P);


void ApproximateFairSubmodularMaximization(PartitionMatroid* matroid_a,
                        FairnessConstraint* fairness_constraints,
                        SubmodularFunction* sub_func_f,
                        float epsilon);  
#endif  
