public static IEnumerable<QualifiedSubset> ExploreAllSubsets(ThresholdSubset threshold)
 {
     var comb = threshold.thresholdParties.Combinations(threshold.K).Select(po => new QualifiedSubset(po));
     if (threshold.fixedParties != null && threshold.fixedParties.Count() > 0)
     {
         List<QualifiedSubset> largerQS = new List<QualifiedSubset>();
         foreach (var qs in comb)
         {
             QualifiedSubset lqs = new QualifiedSubset(threshold.fixedParties.Union(qs.Parties));
             largerQS.Add(lqs);
         }
         return largerQS;
     }
     return comb;
 }
        public static IEnumerable <QualifiedSubset> ExploreAllSubsets(ThresholdSubset threshold)
        {
            var comb = threshold.thresholdParties.Combinations(threshold.K).Select(po => new QualifiedSubset(po));

            if (threshold.fixedParties != null && threshold.fixedParties.Count() > 0)
            {
                List <QualifiedSubset> largerQS = new List <QualifiedSubset>();
                foreach (var qs in comb)
                {
                    QualifiedSubset lqs = new QualifiedSubset(threshold.fixedParties.Union(qs.Parties));
                    largerQS.Add(lqs);
                }
                return(largerQS);
            }
            return(comb);
        }
        public override bool Equals(Object obj)
        {
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            ThresholdSubset p = (ThresholdSubset)(obj);

            if (this.fixedParties.Count() == p.fixedParties.Count())
            {
                foreach (var t in p.fixedParties)
                {
                    if (!this.fixedParties.Contains(t))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
            if (this.thresholdParties.Count() == p.thresholdParties.Count())
            {
                foreach (var t in p.thresholdParties)
                {
                    if (!this.thresholdParties.Contains(t))
                    {
                        return(false);
                    }
                }
            }
            else
            {
                return(false);
            }
            return(true);
        }
        public static IEnumerable <ThresholdSubset> CheckInclusiveThresholds(IEnumerable <ThresholdSubset> thresholds)
        {
            List <ThresholdSubset> alreadyIncludedThresholds = new List <ThresholdSubset>();

            foreach (var th in thresholds)
            {
                var allSubsets = ThresholdSubset.ExploreAllSubsets(th);
                foreach (var sth in thresholds)
                {
                    if (th.Equals(sth))
                    {
                        continue;
                    }
                    var sallsubs           = ThresholdSubset.ExploreAllSubsets(sth);
                    var inclusivethreshold = !sallsubs.Except(allSubsets).Any();
                    if (inclusivethreshold)
                    {
                        alreadyIncludedThresholds.Add(sth);
                    }
                }
            }
            return(thresholds.Except(alreadyIncludedThresholds).ToList());
        }
        public static List <ThresholdSubset> findThreshold(IEnumerable <QualifiedSubset> candidateSets, int k, int allparties, int NRSFT, bool findIntersection = true)
        {
            int allsentences = candidateSets.Count();

            //add trace
            attemptTrace.Add(string.Format("Set:{0}, Attempted threshold:({1},{2})", QualifiedSubset.DumpElementsIntoSingleString(candidateSets), k, allparties));

            // normal case
            List <ThresholdSubset> thresholds = new List <ThresholdSubset>();
            var ncr = nCr(allparties, k);

            if (ncr == allsentences)
            {
                ThresholdSubset th = new ThresholdSubset(allparties, k, new List <Trustee>(), QualifiedSubset.GetAllInvolvedParties(candidateSets).Parties);
                thresholds.Add(th);
            }
            /// if the candidate set is larger than nCr then probably some sets don't belong to the threshold
            /// Here we recusrively rotate parties and select all possible combinations to see which ones are
            /// building threshold for e.g. p1p2p3 p2p3p4 p1p3p4 p1p2p4 p2p4p5
            else if (allsentences < ncr)
            {
                if (NRSFT > allsentences)
                {
                    NRSFT = GetNumberOfRequiredSetsForThreshold(allparties, k, allsentences);
                }
                if (NRSFT == 1)
                {
                    return(thresholds);
                }

                //all possible candidate sets must be generated and recursively called
                var smallersetcombinations      = candidateSets.Combinations(NRSFT);
                var subsetsAlreadyHaveThreshold = new List <QualifiedSubset>();
                foreach (var smallerset in smallersetcombinations)
                {
                    var newallparties = QualifiedSubset.GetAllInvolvedParties(smallerset).Parties.Count;
                    List <ThresholdSubset> foundthresholds = new List <ThresholdSubset>();
                    //add trace
                    attemptTrace.Add(string.Format("Set:{0}, Attempted threshold:({1},{2})",
                                                   QualifiedSubset.DumpElementsIntoSingleString(smallerset), k, newallparties));

                    if (nCr(newallparties, k) == smallerset.Count() && k < newallparties)//not interested in k=n thresholds
                    {
                        foundthresholds = findThreshold(smallerset, k, newallparties, NRSFT, findIntersection);
                        if (foundthresholds.Count > 0)
                        {
                            subsetsAlreadyHaveThreshold.AddRange(smallerset);
                        }
                    }
                    ///try filtering the fixed sets maybe find a threshold
                    if (foundthresholds.Count == 0 && findIntersection)
                    {
                        foundthresholds = findFixedConcatThreshold(smallerset, k, newallparties, NRSFT);
                    }
                    if (foundthresholds != null)
                    {
                        thresholds.AddRange(foundthresholds);
                    }
                }
                if (--NRSFT > 1)
                {
#if filterThresholds
                    var minusAlreadyFoundSets = candidateSets.Except(subsetsAlreadyHaveThreshold);
                    var minusSentences        = minusAlreadyFoundSets.Count();
                    if (minusSentences < allsentences)
                    {
                        var minusInvolvedParties = QualifiedSubset.GetAllInvolvedParties(minusAlreadyFoundSets).Parties.Count;
                        //calculate new NRSFT
                        //NRSFT = GetNumberOfRequiredSetsForThreshold(minusInvolvedParties, k, minusAlreadyFoundSets.Count());
                        //if (NRSFT == 1) return thresholds;
                    }
                    thresholds.AddRange(findThreshold(minusAlreadyFoundSets, k, allparties, NRSFT, findIntersection));
#else
                    thresholds.AddRange(findThreshold(candidateSets, k, allparties, NRSFT, findIntersection));
#endif
                }
            }

            return(thresholds);
        }
        public static List<ThresholdSubset> findThreshold(IEnumerable<QualifiedSubset> candidateSets, int k, int allparties, int NRSFT, bool findIntersection = true)
        {
            int allsentences = candidateSets.Count();
            //add trace 
            attemptTrace.Add(string.Format("Set:{0}, Attempted threshold:({1},{2})", QualifiedSubset.DumpElementsIntoSingleString(candidateSets), k, allparties));

            // normal case
            List<ThresholdSubset> thresholds = new List<ThresholdSubset>();
            var ncr = nCr(allparties, k);
            if (ncr == allsentences)
            {
                ThresholdSubset th = new ThresholdSubset(allparties, k, new List<Trustee>(), QualifiedSubset.GetAllInvolvedParties(candidateSets).Parties);
                thresholds.Add(th);
            }
            /// if the candidate set is larger than nCr then probably some sets don't belong to the threshold 
            /// Here we recusrively rotate parties and select all possible combinations to see which ones are 
            /// building threshold for e.g. p1p2p3 p2p3p4 p1p3p4 p1p2p4 p2p4p5 
            else if (allsentences < ncr)
            {
              
                if (NRSFT > allsentences) NRSFT = GetNumberOfRequiredSetsForThreshold(allparties, k, allsentences);
                if (NRSFT == 1) return thresholds;
              
                //all possible candidate sets must be generated and recursively called
                var smallersetcombinations = candidateSets.Combinations(NRSFT);
                var subsetsAlreadyHaveThreshold = new List<QualifiedSubset>();
                foreach (var smallerset in smallersetcombinations)
                {
                    var newallparties = QualifiedSubset.GetAllInvolvedParties(smallerset).Parties.Count;
                    List<ThresholdSubset> foundthresholds = new List<ThresholdSubset>();
                    //add trace 
                    attemptTrace.Add(string.Format("Set:{0}, Attempted threshold:({1},{2})",
                        QualifiedSubset.DumpElementsIntoSingleString(smallerset), k, newallparties));

                    if (nCr(newallparties, k) == smallerset.Count() && k < newallparties)//not interested in k=n thresholds
                    {
                        foundthresholds = findThreshold(smallerset, k, newallparties, NRSFT, findIntersection);
                        if (foundthresholds.Count > 0)
                        {
                            subsetsAlreadyHaveThreshold.AddRange(smallerset);
                        }
                    }
                    ///try filtering the fixed sets maybe find a threshold 
                    if (foundthresholds.Count == 0 && findIntersection)
                    {
                        foundthresholds = findFixedConcatThreshold(smallerset, k, newallparties, NRSFT);
                    }
                    if (foundthresholds != null)
                    {
                        thresholds.AddRange(foundthresholds);
                    }

                }
                if (--NRSFT > 1)
                {
#if filterThresholds
                    var minusAlreadyFoundSets = candidateSets.Except(subsetsAlreadyHaveThreshold);
                    var minusSentences = minusAlreadyFoundSets.Count();
                    if (minusSentences < allsentences)
                    {
                        var minusInvolvedParties = QualifiedSubset.GetAllInvolvedParties(minusAlreadyFoundSets).Parties.Count;
                        //calculate new NRSFT
                        //NRSFT = GetNumberOfRequiredSetsForThreshold(minusInvolvedParties, k, minusAlreadyFoundSets.Count());
                        //if (NRSFT == 1) return thresholds;
                    }
                    thresholds.AddRange(findThreshold(minusAlreadyFoundSets, k, allparties, NRSFT, findIntersection));
#else
                    thresholds.AddRange(findThreshold(candidateSets, k, allparties, NRSFT, findIntersection));
#endif
                }
            }

            return thresholds;
        }