private int GetNumberOfInputsToBeRemoved(List <Set> outputsDependencies, IEnumerable <Data> removedInputs = null)
        {
            // Number of requested input to reverse in each requested output dependency set
            IEnumerable <Data> inputs = removedInputs is null ? RequestedInputsToReverse : RequestedInputsToReverse.Except(removedInputs);
            List <int>         requestedInputsPerSet = CountElementsInSets(inputs, outputsDependencies);

            // Check that at least Nin outputs map to at lest one input
            IEnumerable <Data> unmmapedVariables = RequestedOutputsToReverse.Where((d, i) => requestedInputsPerSet[i] == 0);

            return(unmmapedVariables.Count() - NoutRequest + inputs.Count());
        }
 private List <Set> GetDependencies()
 {
     //get the output dependencies
     if (Type == ReversalType.Outputs)
     {
         return(RequestedOutputsToReverse.Select(o => GetDependenciesFromOutput(o)).ToList());
     }
     else
     {
         return(RequestedInputsToReverse.Select(i => GetDependenciesFromInput(i)).ToList());
     }
 }
        private bool AllAddedVariablesDependenciesMappedFilter(Combination combination)
        {
            var addedVariables = new List <Data>();

            foreach (Data element in combination)
            {
                if (!RequestedOutputsToReverse.Contains(element) && !IndependentInputs.Contains(element))
                {
                    addedVariables.Add(element);
                }
            }

            List <Data> addedVariablesDependencies = AccumulateDependencies(addedVariables.ToArray(), IndependentInputs);

            int foundCounter = CountElementsInSet(addedVariablesDependencies, combination);

            return(foundCounter >= addedVariables.Count);
        }
        private void CheckReversalRequestCorrectness()
        {
            // Check there are not more requested inputs than workflow inputs or outputa
            if (NinRequest > Nin)
            {
                throw new ArgumentException($"The number of requested inputs is {NinRequest}, but the workflow contains only {Nin} inputs");
            }
            if (NinRequest > Nout)
            {
                throw new ArgumentException($"The number of requested inputs is {NinRequest}, but the workflow contains only {Nout} outputs");
            }

            // Check reversed inputs are amongst the workfolw inputs
            var inputsHash = new HashSet <string>(workflow.ModelDataInputs.GetNames());

            foreach (var data in this.RequestedInputsToReverse.GetNames())
            {
                if (!inputsHash.Contains(data))
                {
                    throw new ArgumentException($"The requested input {data} is not amongst the workflow inputs");
                }
            }

            // Check there are not more requested outputs than workflow workfolw outputs
            if (NoutRequest > Nout)
            {
                throw new ArgumentException($"The number of requested outputs is {NoutRequest}, but the workflow contains only {Nout} outputs");
            }
            if (NoutRequest > Nin)
            {
                throw new ArgumentException($"The number of requested outputs is {NoutRequest}, but the workflow contains only {Nin} inputs");
            }

            // Check reversed outputs are amongst the workfolw outputs
            var outputsHash = new HashSet <string>(workflow.ModelDataOutputs.GetNames());

            foreach (var data in this.RequestedOutputsToReverse.GetNames())
            {
                if (!outputsHash.Contains(data))
                {
                    throw new ArgumentException($"The requested input {data} is not amongst the workflow outputs");
                }
            }


            if (NoutRequest > NinRequest)
            {
                Type = ReversalType.Outputs;

                // Validate determined reversal
                List <Set> outputsDependencies = GetDependencies();

                // Number of requested input to reverse in each requested output dependency set
                List <int> requestedInputsPerSet = CountElementsInSets(RequestedInputsToReverse, outputsDependencies);

                // Check that at least Nin outputs map to at lest one input
                IEnumerable <Data> unmmapedVariables = RequestedOutputsToReverse.Where((d, i) => requestedInputsPerSet[i] == 0);
                if (unmmapedVariables.Count() > NoutRequest - NinRequest)
                {
                    string unmmapedString = unmmapedVariables.Aggregate(String.Empty, (t, l) => t += l.Id + ", ", t => t.TrimEnd(' ', ','));
                    throw new ArgumentException($"Only {requestedInputsPerSet.Count - unmmapedVariables.Count()} outputs map to an input variable" +
                                                $", however, {RequestedInputsToReverse.Length} outputs are needed.\n\r {unmmapedString} are the unmapped ones. Try fixing guidance");
                }
            }
            else
            {
                Type = ReversalType.Inputs;

                // Validate determined reversal
                List <Set> outputsDependencies = GetDependencies();

                // Number of requested output to reverse in each requested input dependency set
                List <int> requestedOutputsPerSet = CountElementsInSets(RequestedOutputsToReverse, outputsDependencies);

                // Check that at least Nin outputs map to at lest one input
                IEnumerable <Data> unmmapedVariables = RequestedInputsToReverse.Where((d, i) => requestedOutputsPerSet[i] == 0);
                if (unmmapedVariables.Count() > NinRequest - NoutRequest)
                {
                    string unmmapedString = unmmapedVariables.Aggregate(String.Empty, (t, l) => t += l.Id + ", ", t => t.TrimEnd(' ', ','));
                    throw new ArgumentException($"Only {requestedOutputsPerSet.Count - unmmapedVariables.Count()} inputs map to an output variable" +
                                                $", however, {RequestedOutputsToReverse.Length} inputs are needed.\n\r {unmmapedString} are the unmapped ones. Try fixing guidance");
                }
            }
        }
 private List <Set> GetInputDependencies() => RequestedOutputsToReverse.Select(i =>
 {
     HashSet <Data> set = dependencyAnalysis.BackwardTrace(i);
     set.Remove(i);             // removes element traced
     return(set);
 }).ToList();
 private List <Set> GetOutputDependencies(Data[] independentVariables) => RequestedOutputsToReverse.Select(o => dependencyAnalysis.BackwardTrace(o, independentVariables)).ToList();