private Disjunction groupUpClausules(List <Disjunction> disjunctions) { List <LogicalArgument> result = new List <LogicalArgument>(); result.AddRange(disjunctions[0].arguments); // Groups up remaining unabsorbed disjuncts into a one line disjunction // Removes redundant disjuncts foreach (Disjunction disj in disjunctions) { foreach (LogicalArgument arg in disj.arguments) { if (result.Exists(a => a.isEqual(arg)) == false) { result.Add(arg); } } } Disjunction disjResult = new Disjunction(result); return(disjResult); }
// Main function which does all the steps AQ11 takes to generate rules public Rule ruleInference() { // AQ11 inputs // Positive examples E1 List <Example> positiveExamples = examples.FindAll(example => example.groupClass == groupClass); // Negative examples E2 List <Example> negativeExamples = examples.Except(positiveExamples).ToList(); // Data member for the most specific wrappers ei/ej(positive vs negative example) List <List <Disjunction> > firstLevelClausules = new List <List <Disjunction> >(); // Data member for the more general wrappers ei/E2(positive example vs negative class) List <Conjunction> secondLevelClausules = new List <Conjunction>(); // Data member indicting which examples were already covered by generated wrappers and thus // no longer need to be analyzed List <int> skipList = new List <int>(); // AQ11 runs through all positive examples for (int i = 0; i < positiveExamples.Count; i++) { // Replaces "remove all positive examples covered by any ei/E2 wrapper" to avoid // problems with modifying the list that is currently being iterated if (skipList.Exists(num => num == i)) { continue; } Example pos = positiveExamples[i]; firstLevelClausules.Add(new List <Disjunction>()); // Generate ei/ej wrapper for every negative example for (int j = 0; j < negativeExamples.Count; j++) { Example neg = negativeExamples[j]; // Each wrapper consists of a disjunction of inequalities List <LogicalArgument> ineqs = new List <LogicalArgument>(); for (int k = 0; k < pos.attributes.Count; k++) { // Inequality for each separate attribute is generated if the positive and negative // examples do not share the same value in it if (pos.attributes[k].value != neg.attributes[k].value) { Variable var = new Variable(pos.attributes[k].name); Constant cons = new Constant(neg.attributes[k].value); Inequality ineq = new Inequality(var, cons); ineqs.Add(ineq); } } // Disjunction is created for all generated inequalities and added to correct data member Disjunction disj = new Disjunction(ineqs); firstLevelClausules[firstLevelClausules.Count - 1].Add(disj); } // Generates ei/E2 wrapper for the current positive example as conjunction of all // ei/ej wrappers and by applying the absorb rule secondLevelClausules.Add(applyAbsorbRule(firstLevelClausules[firstLevelClausules.Count - 1])); // Using the newly generated ei/E2 wrapper, skip list is updated to include positive examples // covered by it skipList.AddRange(skipCoveredExamples(secondLevelClausules[secondLevelClausules.Count - 1], positiveExamples, i)); } // All ei/E2 wrappers are merged using disjunctions in a final rule wrapper E1/E2 Rule rule = new Rule(secondLevelClausules, groupClass); return(rule); }