internal override BooleanExpression ToDNF_Helper() { var newOperands = this.operands.Select(x => x.ToDNF_Helper()); // flatten a conjunction over the operands to get operands without superfluous operator levels, // i.e. when one of the operands was a disjunction, but becomes a conjunction due to distributing // when putting it into DNF, we need to flatten in order to get all conjunction operands into the same layer var newOperandsList = ((Conjunction) new Conjunction(newOperands).Flatten()).GetOperands().ToList(); var disjunctions = newOperands.Where(op => op is Disjunction).Cast <Disjunction>(); if (!disjunctions.Any()) { // no operand is a disjunction, so we can't distribute anything. return(new Conjunction(newOperands)); } else { Disjunction disj = disjunctions.First(); // disjunction will be distributed, so remove it newOperandsList.Remove(disj); var distributedOperandLists = new List <List <BooleanExpression> >(); foreach (BooleanExpression op in disj.GetOperands()) { distributedOperandLists.Add(newOperandsList.Append(op).ToList()); } BooleanExpression resultDisj = new Disjunction(distributedOperandLists.Select(ops => new Conjunction(ops).ToDNF_Helper())); resultDisj = resultDisj.Flatten().Simplify().ToDNF_Helper().Simplify(); return(resultDisj); } }
public override BooleanExpression Flatten() { var flattenedOperands = this.GetOperands().Select(op => op.Flatten()); var resultOperands = new List <BooleanExpression>(); foreach (BooleanExpression expr in flattenedOperands) { if (expr is Disjunction disj) { foreach (BooleanExpression op in disj.GetOperands()) { resultOperands.Add(op); } } else { resultOperands.Add(expr); } } var result = new Disjunction(resultOperands); return(result); }