private static IEnumerable <IFilter> OptimizeCoCluster(FilterCluster cluster, FilterCluster parent) { if (parent == null) { throw new ArgumentNullException("parent"); } var items = (cluster.Filters ?? new IFilter[0]) .SelectMany(f => OptimizeCo(f, cluster)) .ToArray(); if (items.Length == 0) { // 要素無しのフィルタ return(new[] { new FilterCluster() { ConcatenateAnd = false, // 常に AND 結合 Negate = cluster.ConcatenateAnd != cluster.Negate } }); // AND => U false false // NAND => Φ false true // OR => Φ true false // NOR => U true true // ANDかNANDに集約, つまり Negate を U なら false, Φ なら trueにセットする } else if (items.Length == 1) { // 要素が1つしかない場合、このクラスタをスルーする // このクラスタがNegateであれば、直下アイテムのNegate値を変更する if (cluster.Negate) { System.Diagnostics.Debug.WriteLine("Inverse"); items[0].Negate = !items[0].Negate; // 多重処理されないようにNegateをリセットする cluster.Negate = false; } // 所属を変更する return(OptimizeCo(items[0], parent)); } else if (cluster.Negate == false && cluster.ConcatenateAnd == parent.ConcatenateAnd) { // このクラスタがNegateでなく、直上のクラスタと同じ結合である場合 // 直上のクラスタに合成する return(items.SelectMany(f => OptimizeCo(f, parent))); } else { // クラスタのアイテムを更新 cluster.Filters = items; return(new[] { cluster.Contraction() }); } }
/// <summary> /// フィルタの最適化 /// </summary> public static FilterCluster Optimize(FilterCluster cluster) { // ルートフィルタクラスタの最適化 var items = cluster.Filters.SelectMany(f => OptimizeCo(f, cluster)); if (items.Count() == 1 && items.First() is FilterCluster) { var rc = items.First() as FilterCluster; if (cluster.Negate) rc.Negate = !rc.Negate; return rc.Contraction(); } else { cluster.Filters = items.ToArray(); return cluster.Contraction(); } }
/// <summary> /// フィルタの最適化 /// </summary> public static FilterCluster Optimize(FilterCluster cluster) { // ルートフィルタクラスタの最適化 var items = cluster.Filters.SelectMany(f => OptimizeCo(f, cluster)); if (items.Count() == 1 && items.First() is FilterCluster) { var rc = items.First() as FilterCluster; if (cluster.Negate) { rc.Negate = !rc.Negate; } return(rc.Contraction()); } else { cluster.Filters = items.ToArray(); return(cluster.Contraction()); } }
private static IEnumerable<IFilter> OptimizeCoCluster(FilterCluster cluster, FilterCluster parent) { if (parent == null) throw new ArgumentNullException("parent"); var items = (cluster.Filters ?? new IFilter[0]) .SelectMany(f => OptimizeCo(f, cluster)) .ToArray(); if (items.Length == 0) { // 要素無しのフィルタ return new[]{new FilterCluster(){ ConcatenateAnd = false, // 常に AND 結合 Negate = cluster.ConcatenateAnd != cluster.Negate} }; // AND => U false false // NAND => Φ false true // OR => Φ true false // NOR => U true true // ANDかNANDに集約, つまり Negate を U なら false, Φ なら trueにセットする } else if (items.Length == 1) { // 要素が1つしかない場合、このクラスタをスルーする // このクラスタがNegateであれば、直下アイテムのNegate値を変更する if (cluster.Negate) { System.Diagnostics.Debug.WriteLine("Inverse"); items[0].Negate = !items[0].Negate; // 多重処理されないようにNegateをリセットする cluster.Negate = false; } // 所属を変更する return OptimizeCo(items[0], parent); } else if (cluster.Negate == false && cluster.ConcatenateAnd == parent.ConcatenateAnd) { // このクラスタがNegateでなく、直上のクラスタと同じ結合である場合 // 直上のクラスタに合成する return items.SelectMany(f => OptimizeCo(f, parent)); } else { // クラスタのアイテムを更新 cluster.Filters = items; return new[] { cluster.Contraction() }; } }