Exemplo n.º 1
0
 private IEnumerable <IFilter> GenerateFilters(IEnumerable <string> queries)
 {
     foreach (var s in queries)
     {
         FilterCluster cluster = null;
         try
         {
             cluster = QueryCompiler.ToFilter(s);
         }
         catch (Exception e)
         {
             ExceptionStorage.Register(e, ExceptionCategory.ConfigurationError, "フィルタ クエリを読み取れません: " + s);
         }
         if (cluster != null)
         {
             if (cluster.Filters.Count() == 1)
             {
                 var filter = cluster.Filters.First();
                 if (cluster.Negate)
                 {
                     filter.Negate = !filter.Negate;
                 }
                 yield return(filter);
             }
             else
             {
                 yield return(cluster);
             }
         }
     }
 }
Exemplo n.º 2
0
 public FilterClusterViewModel(FilterEditorViewModel root, FilterClusterViewModel parent, FilterCluster cluster)
     : base(root, parent)
 {
     if (cluster == null)
     {
         throw new ArgumentNullException("cluster");
     }
     this.cluster = cluster;
 }
Exemplo n.º 3
0
 private static IEnumerable <IFilter> OptimizeCo(IFilter filter, FilterCluster parent)
 {
     System.Diagnostics.Debug.WriteLine("Current focus: " + filter.ToQuery() + " / on " + parent.ToQuery());
     if (filter is FilterCluster)
     {
         return(OptimizeCoCluster((FilterCluster)filter, parent));
     }
     else
     {
         return new[] { filter }
     };
 }
Exemplo n.º 4
0
        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() });
            }
        }
Exemplo n.º 5
0
 /// <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();
     }
 }
Exemplo n.º 6
0
        /// <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());
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// フィルタを縮約化します。
        /// </summary>
        private static FilterCluster Contraction(this FilterCluster cluster)
        {
            // クラスタ内の全空フィルタクラスタを取得する
            var emptyClusters = cluster.Filters.OfType <FilterCluster>().Where(f => f.Filters.Count() == 0).ToArray();

            // [全ての空フィルタクラスタはORかNORである]
            if (emptyClusters.FirstOrDefault(f => f.ConcatenateAnd) != null)
            {
                throw new ArgumentException("All empty filters must be OR or NOR.");
            }

            // フィルタと非空フィルタクラスタを待避
            var filters = cluster.Filters.Except(emptyClusters).ToArray();

            // 1    : U [全ツイートの抽出: !() [NOR(Φ)]]
            // 0    : F [一つだけ含まれるフィルタ]
            // -1   : Φ [抽出されるツイート無し: () [OR(Φ)]
            int resultValue = 0;

            if (cluster.ConcatenateAnd)
            {
                // AND 結合モード

                // OR 空フィルタが含まれていたら resultvalue = -1 (Φ)
                if (emptyClusters.FirstOrDefault(f => !f.Negate) != null)
                {
                    resultValue = -1;
                }
                // そうでない場合は、フィルタが存在すればresultValue = 0, でなければ 1
                else if (filters.Length > 0)
                {
                    resultValue = 0;
                }
                else
                {
                    resultValue = 1;
                }
            }
            else
            {
                // OR 結合モード

                // NOR 空フィルタが含まれていたら resultvalue = 1 (U)
                if (emptyClusters.FirstOrDefault(f => f.Negate) != null)
                {
                    resultValue = 1;
                }
                // そうでない場合は、フィルタが存在すればresultValue = 0, でなければ -1
                else if (filters.Length > 0)
                {
                    resultValue = 0;
                }
                else
                {
                    resultValue = -1;
                }
            }

            if (resultValue == 1) // U
            {
                return new FilterCluster()
                       {
                           ConcatenateAnd = true,
                           Negate         = cluster.Negate
                       }
            }
            ;
            else if (resultValue == 0) // F
            {
                return new FilterCluster()
                       {
                           ConcatenateAnd = cluster.ConcatenateAnd,
                           Filters        = filters,
                           Negate         = cluster.Negate
                       }
            }
            ;
            else if (resultValue == -1) // Φ
            {
                return new FilterCluster()
                       {
                           ConcatenateAnd = false,
                           Negate         = !cluster.Negate
                       }
            }
            ;
            else
            {
                throw new InvalidOperationException("resultValue is invalid:" + resultValue.ToString());
            }
        }
Exemplo n.º 8
0
 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() };
     }
 }
Exemplo n.º 9
0
 private static IEnumerable<IFilter> OptimizeCo(IFilter filter, FilterCluster parent)
 {
     System.Diagnostics.Debug.WriteLine("Current focus: " + filter.ToQuery() + " / on " + parent.ToQuery());
     if (filter is FilterCluster)
         return OptimizeCoCluster((FilterCluster)filter, parent);
     else
         return new[] { filter };
 }
Exemplo n.º 10
0
        /// <summary>
        /// フィルタ クラスタを走査し、構築します。
        /// </summary>
        /// <returns>フィルタ クラスタ</returns>
        private static FilterCluster AnalyzeCluster()
        {
            var cluster = new FilterCluster();

            bool endPoint = false;
            while (!endPoint)
            {
                if (cursor + 1 >= query.Length)
                    throw new QueryException("クエリが不適切です。オブジェクトが終了していません。");

                Next();

                switch (Tokenize())
                {
                    // 無視する文字
                    case TokenType.Space:
                        break;
                    case TokenType.Tab:
                        break;
                    case TokenType.CarriageReturn:
                        break;
                    case TokenType.LineFeed:
                        break;

                    case TokenType.OpenBracket:
                        var childCluster = AnalyzeCluster();
                        childCluster.Parent = cluster;
                        cluster.Add(childCluster);
                        break;
                    case TokenType.CloseBracket:
                        endPoint = true;
                        break;

                    case TokenType.Sharp:
                        Next();
                        switch (Tokenize())
                        {
                            case TokenType.OpenBracket:
                                var childCalculator = AnalyzeCalculator();
                                childCalculator.Parent = cluster;
                                cluster.Add(childCalculator);
                                break;
                        }
                        break;

                    case TokenType.ConcatenatorAnd: // and
                        cluster.Filters.Last().Operator = LogicalOperator.And;
                        break;
                    case TokenType.ConcatenatorOr: // or
                        cluster.Filters.Last().Operator = LogicalOperator.Or;
                        break;
                    case TokenType.ConcatenatorXor: // xor
                        cluster.Filters.Last().Operator = LogicalOperator.Xor;
                        break;

                    default:
                        cluster.Add(AnalyzeFilter());
                        break;
                }
            }

            return cluster;
        }
Exemplo n.º 11
0
 private static IEnumerable<IFilter> OptimizeCo(IFilter filter, FilterCluster parent)
 {
     if (filter is FilterCluster)
         return OptimizeCoCluster((FilterCluster)filter, parent);
     else
         return new[] { filter };
 }
Exemplo n.º 12
0
 private static FilterCluster AnalysisExpression(ExpressionTuple expressionTuple)
 {
     var retcluster = new FilterCluster()
     {
         ConcatenateOR = expressionTuple.ConcatOr.GetValueOrDefault(false)
     };
     if (expressionTuple.Expression == null)
     {
         retcluster.Filters = new[] { AnalysisExpressionBody(expressionTuple.ExpressionBody) };
     }
     else
     {
         if (!expressionTuple.ConcatOr.HasValue)
             throw new InvalidOperationException("内部エラー: ExpressionTupleはチェーンを構成しますが、接続情報がありません。");
         retcluster.Filters = new[] { AnalysisExpressionBody(expressionTuple.ExpressionBody), AnalysisExpression(expressionTuple.Expression) };
     }
     return retcluster;
 }