Exemplo n.º 1
0
            public override Explanation Explain(IndexReader ir, int i)
            {
                Explanation inner = weight.Explain(ir, i);

                if (Enclosing_Instance.GetBoost() != 1)
                {
                    Explanation preBoost = inner;
                    inner = new Explanation(inner.GetValue() * Enclosing_Instance.GetBoost(), "product of:");
                    inner.AddDetail(new Explanation(Enclosing_Instance.GetBoost(), "boost"));
                    inner.AddDetail(preBoost);
                }
                Filter           f                = Enclosing_Instance.filter;
                DocIdSet         docIdSet         = f.GetDocIdSet(ir);
                DocIdSetIterator docIdSetIterator = docIdSet == null?DocIdSet.EMPTY_DOCIDSET.Iterator() : docIdSet.Iterator();

                if (docIdSetIterator == null)
                {
                    docIdSetIterator = DocIdSet.EMPTY_DOCIDSET.Iterator();
                }
                if (docIdSetIterator.Advance(i) == i)
                {
                    return(inner);
                }
                else
                {
                    Explanation result = new Explanation(0.0f, "failure to match filter: " + f.ToString());
                    result.AddDetail(inner);
                    return(result);
                }
            }
Exemplo n.º 2
0
            public virtual Explanation Explain(IndexReader ir, int i)
            {
                Explanation inner = weight.Explain(ir, i);

                if (Enclosing_Instance.GetBoost() != 1)
                {
                    Explanation preBoost = inner;
                    inner = new Explanation(inner.GetValue() * Enclosing_Instance.GetBoost(), "product of:");
                    inner.AddDetail(new Explanation(Enclosing_Instance.GetBoost(), "boost"));
                    inner.AddDetail(preBoost);
                }
                Filter           f = Enclosing_Instance.filter;
                DocIdSetIterator docIdSetIterator = f.GetDocIdSet(ir).Iterator();

                if (docIdSetIterator.SkipTo(i) && docIdSetIterator.Doc() == i)
                {
                    return(inner);
                }
                else
                {
                    Explanation result = new Explanation(0.0f, "failure to match filter: " + f.ToString());
                    result.AddDetail(inner);
                    return(result);
                }
            }
Exemplo n.º 3
0
        public override Explanation Explain(IndexReader reader, int doc)
        {
            ComplexExplanation result = new ComplexExplanation();
            result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
            System.String field = ((SpanQuery) GetQuery()).GetField();

            Explanation idfExpl = new Explanation(idf, "idf(" + field + ": " + idfExp.Explain() + ")");

            // explain query weight
            Explanation queryExpl = new Explanation();
            queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

            Explanation boostExpl = new Explanation(GetQuery().GetBoost(), "boost");
            if (GetQuery().GetBoost() != 1.0f)
                queryExpl.AddDetail(boostExpl);
            queryExpl.AddDetail(idfExpl);

            Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
            queryExpl.AddDetail(queryNormExpl);

            queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

            result.AddDetail(queryExpl);

            // explain field weight
            ComplexExplanation fieldExpl = new ComplexExplanation();
            fieldExpl.SetDescription("fieldWeight(" + field + ":" + query.ToString(field) + " in " + doc + "), product of:");

            Explanation tfExpl = Scorer(reader, true, false).Explain(doc);
            fieldExpl.AddDetail(tfExpl);
            fieldExpl.AddDetail(idfExpl);

            Explanation fieldNormExpl = new Explanation();
            byte[] fieldNorms = reader.Norms(field);
            float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):1.0f;
            fieldNormExpl.SetValue(fieldNorm);
            fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")");
            fieldExpl.AddDetail(fieldNormExpl);

            fieldExpl.SetMatch(tfExpl.IsMatch());
            fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

            result.AddDetail(fieldExpl);
            System.Boolean tempAux = fieldExpl.GetMatch();
            result.SetMatch(tempAux);

            // combine them
            result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

            if (queryExpl.GetValue() == 1.0f)
                return fieldExpl;

            return result;
        }
Exemplo n.º 4
0
                public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl)
                {
                    float       valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.GetValue();
                    Explanation exp         = new Explanation(valSrcScore + subQueryExpl.GetValue(), "custom score: sum of:");

                    exp.AddDetail(subQueryExpl);
                    if (valSrcExpl != null)
                    {
                        exp.AddDetail(valSrcExpl);
                    }
                    return(exp);
                }
            /* Explain the score we computed for doc */
            public virtual Explanation Explain(IndexReader reader, int doc)
            {
                if (Enclosing_Instance.disjuncts.Count == 1)
                {
                    return(((Weight)weights[0]).Explain(reader, doc));
                }
                Explanation result = new Explanation();
                float       max = 0.0f, sum = 0.0f;

                result.SetDescription(Enclosing_Instance.tieBreakerMultiplier == 0.0f ? "max of:" : "max plus " + Enclosing_Instance.tieBreakerMultiplier + " times others of:");
                for (int i = 0; i < weights.Count; i++)
                {
                    Explanation e = ((Weight)weights[i]).Explain(reader, doc);
                    if (e.GetValue() > 0)
                    {
                        result.AddDetail(e);
                        sum += e.GetValue();
                        max  = System.Math.Max(max, e.GetValue());
                    }
                }
                result.SetValue(max + (sum - max) * Enclosing_Instance.tieBreakerMultiplier);
                return(result);
            }
Exemplo n.º 6
0
                // add an explanation about whether the document was filtered
                public override Explanation Explain(int i)
                {
                    Explanation exp = scorer.Explain(i);

                    exp.SetValue(Enclosing_Instance.Enclosing_Instance.GetBoost() * exp.GetValue());

                    if (bitset.Get(i))
                    {
                        exp.SetDescription("allowed by filter: " + exp.GetDescription());
                    }
                    else
                    {
                        exp.SetDescription("removed by filter: " + exp.GetDescription());
                    }
                    return(exp);
                }
Exemplo n.º 7
0
            public virtual Explanation Explain(IndexReader reader, int doc)
            {
                // explain query weight
                Explanation queryExpl = new Explanation();

                queryExpl.SetDescription("MatchAllDocsQuery:");

                Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");

                if (Enclosing_Instance.GetBoost() != 1.0f)
                {
                    queryExpl.AddDetail(boostExpl);
                }
                queryExpl.SetValue(boostExpl.GetValue());

                return(queryExpl);
            }
Exemplo n.º 8
0
                public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[] valSrcExpls)
                {
                    if (valSrcExpls.Length == 0)
                    {
                        return(subQueryExpl);
                    }
                    Explanation exp = new Explanation(valSrcExpls[0].GetValue() + subQueryExpl.GetValue(), "sum of:");

                    exp.AddDetail(subQueryExpl);
                    exp.AddDetail(valSrcExpls[0]);
                    if (valSrcExpls.Length == 1)
                    {
                        exp.SetDescription("CustomMulAdd, sum of:");
                        return(exp);
                    }
                    Explanation exp2 = new Explanation(valSrcExpls[1].GetValue() * exp.GetValue(), "custom score: product of:");

                    exp2.AddDetail(valSrcExpls[1]);
                    exp2.AddDetail(exp);
                    return(exp2);
                }
Exemplo n.º 9
0
        private void AddNode(TreeNode tn, Explanation e)
        {
            TreeNode node = new TreeNode(e.GetValue().ToString("G4") + "  " + e.GetDescription());

            if (null == tn)
            {
                treeExplain.Nodes.Add(node);
            }
            else
            {
                tn.Nodes.Add(node);
            }

            Explanation[] kids = e.GetDetails();
            if (kids != null && kids.Length > 0)
            {
                for (int i = 0; i < kids.Length; i++)
                {
                    AddNode(node, kids[i]);
                }
            }
        }
Exemplo n.º 10
0
        public static float EXPLAIN_SCORE_TOLERANCE_DELTA = 0.00025f;           // {{See: LUCENENET-288}} Intentional diversion from Java Lucene per above comment

        /// <summary> Tests that all documents up to maxDoc which are *not* in the
        /// expected result set, have an explanation which indicates no match
        /// (ie: Explanation value of 0.0f)
        /// </summary>
        public static void  CheckNoMatchExplanations(Query q, System.String defaultFieldName, Searcher searcher, int[] results)
        {
            System.String d = q.ToString(defaultFieldName);
            System.Collections.Hashtable ignore = new System.Collections.Hashtable();
            for (int i = 0; i < results.Length; i++)
            {
                SupportClass.CollectionsHelper.AddIfNotContains(ignore, (System.Int32)results[i]);
            }

            int maxDoc = searcher.MaxDoc();

            for (int doc = 0; doc < maxDoc; doc++)
            {
                if (ignore.Contains((System.Int32)doc))
                {
                    continue;
                }

                Explanation exp = searcher.Explain(q, doc);
                Assert.IsNotNull(exp, "Explanation of [[" + d + "]] for #" + doc + " is null");
                Assert.AreEqual(0.0f, exp.GetValue(), 0.0f, "Explanation of [[" + d + "]] for #" + doc + " doesn't indicate non-match: " + exp.ToString());
            }
        }
Exemplo n.º 11
0
            public virtual Explanation Explain(IndexReader ir, int i)
            {
                Explanation inner = weight.Explain(ir, i);

                if (Enclosing_Instance.GetBoost() != 1)
                {
                    Explanation preBoost = inner;
                    inner = new Explanation(inner.GetValue() * Enclosing_Instance.GetBoost(), "product of:");
                    inner.AddDetail(new Explanation(Enclosing_Instance.GetBoost(), "boost"));
                    inner.AddDetail(preBoost);
                }
                Filter f = Enclosing_Instance.filter;

                System.Collections.BitArray matches = f.Bits(ir);
                if (matches.Get(i))
                {
                    return(inner);
                }
                Explanation result = new Explanation(0.0f, "failure to match filter: " + f.ToString());

                result.AddDetail(inner);
                return(result);
            }
Exemplo n.º 12
0
        public virtual void  TestExplain()
        {
            Term      allTerm   = new Term(FIELD, "all");
            TermQuery termQuery = new TermQuery(allTerm);

            Weight weight = termQuery.Weight(indexSearcher);

            TermScorer  ts          = new TermScorer(weight, indexReader.TermDocs(allTerm), indexSearcher.GetSimilarity(), indexReader.Norms(FIELD));
            Explanation explanation = ts.Explain(0);

            Assert.IsTrue(explanation != null, "explanation is null and it shouldn't be");
            //System.out.println("Explanation: " + explanation.toString());
            //All this Explain does is return the term frequency
            Assert.IsTrue(explanation.GetValue() == 1, "term frq is not 1");
            explanation = ts.Explain(1);
            Assert.IsTrue(explanation != null, "explanation is null and it shouldn't be");
            //System.out.println("Explanation: " + explanation.toString());
            //All this Explain does is return the term frequency
            Assert.IsTrue(explanation.GetValue() == 0, "term frq is not 0");

            Term dogsTerm = new Term(FIELD, "dogs");

            termQuery = new TermQuery(dogsTerm);
            weight    = termQuery.Weight(indexSearcher);

            ts          = new TermScorer(weight, indexReader.TermDocs(dogsTerm), indexSearcher.GetSimilarity(), indexReader.Norms(FIELD));
            explanation = ts.Explain(1);
            Assert.IsTrue(explanation != null, "explanation is null and it shouldn't be");
            //System.out.println("Explanation: " + explanation.toString());
            //All this Explain does is return the term frequency
            float sqrtTwo = (float)System.Math.Sqrt(2.0f);

            Assert.IsTrue(explanation.GetValue() == sqrtTwo, "term frq: " + explanation.GetValue() + " is not the square root of 2");

            explanation = ts.Explain(10);             //try a doc out of range
            Assert.IsTrue(explanation != null, "explanation is null and it shouldn't be");
            //System.out.println("Explanation: " + explanation.toString());
            //All this Explain does is return the term frequency

            Assert.IsTrue(explanation.GetValue() == 0, "term frq: " + explanation.GetValue() + " is not 0");
        }
Exemplo n.º 13
0
        public virtual Explanation Explain(IndexReader reader, int doc)
        {
            ComplexExplanation result = new ComplexExplanation();
            result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
            System.String field = ((SpanQuery) GetQuery()).GetField();

            System.Text.StringBuilder docFreqs = new System.Text.StringBuilder();
            System.Collections.IEnumerator i = terms.GetEnumerator();
            while (i.MoveNext())
            {
                System.Collections.DictionaryEntry tmp = (System.Collections.DictionaryEntry) i.Current;
                Term term = (Term) tmp.Key;
                docFreqs.Append(term.Text());
                docFreqs.Append("=");
                docFreqs.Append(reader.DocFreq(term));

                if (i.MoveNext())
                {
                    docFreqs.Append(" ");
                }
            }

            Explanation idfExpl = new Explanation(idf, "idf(" + field + ": " + docFreqs + ")");

            // explain query weight
            Explanation queryExpl = new Explanation();
            queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

            Explanation boostExpl = new Explanation(GetQuery().GetBoost(), "boost");
            if (GetQuery().GetBoost() != 1.0f)
                queryExpl.AddDetail(boostExpl);
            queryExpl.AddDetail(idfExpl);

            Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
            queryExpl.AddDetail(queryNormExpl);

            queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

            result.AddDetail(queryExpl);

            // explain field weight
            ComplexExplanation fieldExpl = new ComplexExplanation();
            fieldExpl.SetDescription("fieldWeight(" + field + ":" + query.ToString(field) + " in " + doc + "), product of:");

            Explanation tfExpl = Scorer(reader).Explain(doc);
            fieldExpl.AddDetail(tfExpl);
            fieldExpl.AddDetail(idfExpl);

            Explanation fieldNormExpl = new Explanation();
            byte[] fieldNorms = reader.Norms(field);
            float fieldNorm = fieldNorms != null ? Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f;
            fieldNormExpl.SetValue(fieldNorm);
            fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")");
            fieldExpl.AddDetail(fieldNormExpl);

            fieldExpl.SetMatch(tfExpl.IsMatch());
            fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

            result.AddDetail(fieldExpl);
            System.Boolean tempAux = fieldExpl.GetMatch();
            result.SetMatch(tempAux);

            // combine them
            result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

            if (queryExpl.GetValue() == 1.0f)
                return fieldExpl;

            return result;
        }
Exemplo n.º 14
0
            public override Explanation Explain(IndexReader reader, int doc)
            {
                ComplexExplanation result = new ComplexExplanation();

                result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");

                Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");

                // explain query weight
                Explanation queryExpl = new Explanation();

                queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

                Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");

                if (Enclosing_Instance.GetBoost() != 1.0f)
                {
                    queryExpl.AddDetail(boostExpl);
                }

                queryExpl.AddDetail(idfExpl);

                Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");

                queryExpl.AddDetail(queryNormExpl);

                queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

                result.AddDetail(queryExpl);

                // explain field weight
                ComplexExplanation fieldExpl = new ComplexExplanation();

                fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");

                Scorer scorer = Scorer(reader, true, false);

                if (scorer == null)
                {
                    return(new Explanation(0.0f, "no matching docs"));
                }
                Explanation tfExpl = scorer.Explain(doc);

                fieldExpl.AddDetail(tfExpl);
                fieldExpl.AddDetail(idfExpl);

                Explanation fieldNormExpl = new Explanation();

                byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
                float  fieldNorm  = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f;

                fieldNormExpl.SetValue(fieldNorm);
                fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
                fieldExpl.AddDetail(fieldNormExpl);

                fieldExpl.SetMatch(tfExpl.IsMatch());
                fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

                result.AddDetail(fieldExpl);
                System.Boolean?tempAux = fieldExpl.GetMatch();
                result.SetMatch(tempAux);

                // combine them
                result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

                if (queryExpl.GetValue() == 1.0f)
                {
                    return(fieldExpl);
                }

                return(result);
            }
Exemplo n.º 15
0
        /// <summary> Assert that an explanation has the expected score, and optionally that its
        /// sub-details max/sum/factor match to that score.
        ///
        /// </summary>
        /// <param name="q">String representation of the query for assertion messages
        /// </param>
        /// <param name="doc">Document ID for assertion messages
        /// </param>
        /// <param name="score">Real score value of doc with query q
        /// </param>
        /// <param name="deep">indicates whether a deep comparison of sub-Explanation details should be executed
        /// </param>
        /// <param name="expl">The Explanation to match against score
        /// </param>
        public static void  VerifyExplanation(System.String q, int doc, float score, bool deep, Explanation expl)
        {
            float value_Renamed = expl.GetValue();

            Assert.AreEqual(score, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": score(doc=" + doc + ")=" + score + " != explanationScore=" + value_Renamed + " Explanation: " + expl);

            if (!deep)
            {
                return;
            }

            Explanation[] detail = expl.GetDetails();
            if (detail != null)
            {
                if (detail.Length == 1)
                {
                    // simple containment, no matter what the description says,
                    // just verify contained expl has same score
                    VerifyExplanation(q, doc, score, deep, detail[0]);
                }
                else
                {
                    // explanation must either:
                    // - end with one of: "product of:", "sum of:", "max of:", or
                    // - have "max plus <x> times others" (where <x> is float).
                    float         x              = 0;
                    System.String descr          = expl.GetDescription().ToLower();
                    bool          productOf      = descr.EndsWith("product of:");
                    bool          sumOf          = descr.EndsWith("sum of:");
                    bool          maxOf          = descr.EndsWith("max of:");
                    bool          maxTimesOthers = false;
                    if (!(productOf || sumOf || maxOf))
                    {
                        // maybe 'max plus x times others'
                        int k1 = descr.IndexOf("max plus ");
                        if (k1 >= 0)
                        {
                            k1 += "max plus ".Length;
                            int k2 = descr.IndexOf(" ", k1);
                            try
                            {
                                x = SupportClass.Single.Parse(descr.Substring(k1, (k2) - (k1)).Trim());
                                if (descr.Substring(k2).Trim().Equals("times others of:"))
                                {
                                    maxTimesOthers = true;
                                }
                            }
                            catch (System.FormatException e)
                            {
                            }
                        }
                    }
                    Assert.IsTrue(productOf || sumOf || maxOf || maxTimesOthers, q + ": multi valued explanation description=\"" + descr + "\" must be 'max of plus x times others' or end with 'product of'" + " or 'sum of:' or 'max of:' - " + expl);
                    float sum     = 0;
                    float product = 1;
                    float max     = 0;
                    for (int i = 0; i < detail.Length; i++)
                    {
                        float dval = detail[i].GetValue();
                        VerifyExplanation(q, doc, dval, deep, detail[i]);
                        product *= dval;
                        sum     += dval;
                        max      = System.Math.Max(max, dval);
                    }
                    float combined = 0;
                    if (productOf)
                    {
                        combined = product;
                    }
                    else if (sumOf)
                    {
                        combined = sum;
                    }
                    else if (maxOf)
                    {
                        combined = max;
                    }
                    else if (maxTimesOthers)
                    {
                        combined = max + x * (sum - max);
                    }
                    else
                    {
                        Assert.IsTrue(false, "should never get here!");
                    }
                    Assert.AreEqual(combined, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": actual subDetails combined==" + combined + " != value=" + value_Renamed + " Explanation: " + expl);
                }
            }
        }
Exemplo n.º 16
0
            public virtual Explanation Explain(IndexReader reader, int doc)
            {
                Explanation result = new Explanation();

                result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");

                Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");

                // explain query weight
                Explanation queryExpl = new Explanation();

                queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

                Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");

                if (Enclosing_Instance.GetBoost() != 1.0f)
                {
                    queryExpl.AddDetail(boostExpl);
                }

                queryExpl.AddDetail(idfExpl);

                Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");

                queryExpl.AddDetail(queryNormExpl);

                queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

                result.AddDetail(queryExpl);

                // explain field weight
                Explanation fieldExpl = new Explanation();

                fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");

                Explanation tfExpl = Scorer(reader).Explain(doc);

                fieldExpl.AddDetail(tfExpl);
                fieldExpl.AddDetail(idfExpl);

                Explanation fieldNormExpl = new Explanation();

                byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
                float  fieldNorm  = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f;

                fieldNormExpl.SetValue(fieldNorm);
                fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
                fieldExpl.AddDetail(fieldNormExpl);

                fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

                result.AddDetail(fieldExpl);

                // combine them
                result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

                if (queryExpl.GetValue() == 1.0f)
                {
                    return(fieldExpl);
                }

                return(result);
            }
Exemplo n.º 17
0
            public override Explanation Explain(IndexReader reader, int doc)
            {
                int minShouldMatch         = Enclosing_Instance.GetMinimumNumberShouldMatch();
                ComplexExplanation sumExpl = new ComplexExplanation();

                sumExpl.SetDescription("sum of:");
                int   coord            = 0;
                int   maxCoord         = 0;
                float sum              = 0.0f;
                bool  fail             = false;
                int   shouldMatchCount = 0;

                for (System.Collections.IEnumerator wIter = weights.GetEnumerator(), cIter = Enclosing_Instance.clauses.GetEnumerator(); wIter.MoveNext();)
                {
                    cIter.MoveNext();

                    Weight        w = (Weight)wIter.Current;
                    BooleanClause c = (BooleanClause)cIter.Current;
                    if (w.Scorer(reader, true, true) == null)
                    {
                        continue;
                    }
                    Explanation e = w.Explain(reader, doc);
                    if (!c.IsProhibited())
                    {
                        maxCoord++;
                    }
                    if (e.IsMatch())
                    {
                        if (!c.IsProhibited())
                        {
                            sumExpl.AddDetail(e);
                            sum += e.GetValue();
                            coord++;
                        }
                        else
                        {
                            Explanation r = new Explanation(0.0f, "match on prohibited clause (" + c.GetQuery().ToString() + ")");
                            r.AddDetail(e);
                            sumExpl.AddDetail(r);
                            fail = true;
                        }
                        if (c.GetOccur() == Occur.SHOULD)
                        {
                            shouldMatchCount++;
                        }
                    }
                    else if (c.IsRequired())
                    {
                        Explanation r = new Explanation(0.0f, "no match on required clause (" + c.GetQuery().ToString() + ")");
                        r.AddDetail(e);
                        sumExpl.AddDetail(r);
                        fail = true;
                    }
                }
                if (fail)
                {
                    System.Boolean tempAux = false;
                    sumExpl.SetMatch(tempAux);
                    sumExpl.SetValue(0.0f);
                    sumExpl.SetDescription("Failure to meet condition(s) of required/prohibited clause(s)");
                    return(sumExpl);
                }
                else if (shouldMatchCount < minShouldMatch)
                {
                    System.Boolean tempAux2 = false;
                    sumExpl.SetMatch(tempAux2);
                    sumExpl.SetValue(0.0f);
                    sumExpl.SetDescription("Failure to match minimum number " + "of optional clauses: " + minShouldMatch);
                    return(sumExpl);
                }

                sumExpl.SetMatch(0 < coord?true:false);
                sumExpl.SetValue(sum);

                float coordFactor = similarity.Coord(coord, maxCoord);

                if (coordFactor == 1.0f)
                {
                    // coord is no-op
                    return(sumExpl);
                }
                // eliminate wrapper
                else
                {
                    ComplexExplanation result = new ComplexExplanation(sumExpl.IsMatch(), sum * coordFactor, "product of:");
                    result.AddDetail(sumExpl);
                    result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + maxCoord + ")"));
                    return(result);
                }
            }
Exemplo n.º 18
0
                // add an explanation about whether the document was filtered
                public override Explanation Explain(int i)
                {
                    Explanation exp = scorer.Explain(i);

                    if (docIdSetIterator.Advance(i) == i)
                    {
                        exp.SetDescription("allowed by filter: " + exp.GetDescription());
                        exp.SetValue(Enclosing_Instance.Enclosing_Instance.GetBoost() * exp.GetValue());
                    }
                    else
                    {
                        exp.SetDescription("removed by filter: " + exp.GetDescription());
                        exp.SetValue(0.0f);
                    }
                    return(exp);
                }
Exemplo n.º 19
0
			public virtual Explanation Explain(IndexReader reader, int doc)
			{
				
				ComplexExplanation result = new ComplexExplanation();
				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
				
				Explanation idfExpl = new Explanation(idf, "idf(docFreq=" + reader.DocFreq(Enclosing_Instance.term) + ", numDocs=" + reader.NumDocs() + ")");
				
				// explain query weight
				Explanation queryExpl = new Explanation();
				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
				
				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
				if (Enclosing_Instance.GetBoost() != 1.0f)
					queryExpl.AddDetail(boostExpl);
				queryExpl.AddDetail(idfExpl);
				
				Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
				queryExpl.AddDetail(queryNormExpl);
				
				queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
				
				result.AddDetail(queryExpl);
				
				// explain field weight
				System.String field = Enclosing_Instance.term.Field();
				ComplexExplanation fieldExpl = new ComplexExplanation();
				fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.term + " in " + doc + "), product of:");
				
				Explanation tfExpl = Scorer(reader).Explain(doc);
				fieldExpl.AddDetail(tfExpl);
				fieldExpl.AddDetail(idfExpl);
				
				Explanation fieldNormExpl = new Explanation();
				byte[] fieldNorms = reader.Norms(field);
				float fieldNorm = fieldNorms != null ? Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f;
				fieldNormExpl.SetValue(fieldNorm);
				fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")");
				fieldExpl.AddDetail(fieldNormExpl);
				
				fieldExpl.SetMatch(tfExpl.IsMatch());
				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
				
				result.AddDetail(fieldExpl);
				System.Boolean tempAux = fieldExpl.GetMatch();
				result.SetMatch(tempAux);
				
				// combine them
				result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
				
				if (queryExpl.GetValue() == 1.0f)
					return fieldExpl;
				
				return result;
			}
Exemplo n.º 20
0
            public override Explanation Explain(IndexReader reader, int doc)
            {
                Explanation result = new Explanation();

                result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");

                System.Text.StringBuilder docFreqs = new System.Text.StringBuilder();
                System.Text.StringBuilder query    = new System.Text.StringBuilder();
                query.Append('\"');
                docFreqs.Append(idfExp.Explain());
                for (int i = 0; i < Enclosing_Instance.terms.Count; i++)
                {
                    if (i != 0)
                    {
                        query.Append(" ");
                    }

                    Term term = (Term)Enclosing_Instance.terms[i];

                    query.Append(term.Text());
                }
                query.Append('\"');

                Explanation idfExpl = new Explanation(idf, "idf(" + Enclosing_Instance.field + ":" + docFreqs + ")");

                // explain query weight
                Explanation queryExpl = new Explanation();

                queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

                Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");

                if (Enclosing_Instance.GetBoost() != 1.0f)
                {
                    queryExpl.AddDetail(boostExpl);
                }
                queryExpl.AddDetail(idfExpl);

                Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");

                queryExpl.AddDetail(queryNormExpl);

                queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

                result.AddDetail(queryExpl);

                // explain field weight
                Explanation fieldExpl = new Explanation();

                fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:");

                Scorer scorer = Scorer(reader, true, false);

                if (scorer == null)
                {
                    return(new Explanation(0.0f, "no matching docs"));
                }
                Explanation tfExpl = scorer.Explain(doc);

                fieldExpl.AddDetail(tfExpl);
                fieldExpl.AddDetail(idfExpl);

                Explanation fieldNormExpl = new Explanation();

                byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
                float  fieldNorm  = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 1.0f;

                fieldNormExpl.SetValue(fieldNorm);
                fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
                fieldExpl.AddDetail(fieldNormExpl);

                fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

                result.AddDetail(fieldExpl);

                // combine them
                result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

                if (queryExpl.GetValue() == 1.0f)
                {
                    return(fieldExpl);
                }

                return(result);
            }
Exemplo n.º 21
0
            public virtual Explanation Explain(IndexReader reader, int doc)
            {
                ComplexExplanation result = new ComplexExplanation();

                result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");

                Explanation idfExpl = new Explanation(idf, "idf(docFreq=" + reader.DocFreq(Enclosing_Instance.term) + ", numDocs=" + reader.NumDocs() + ")");

                // explain query weight
                Explanation queryExpl = new Explanation();

                queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");

                Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");

                if (Enclosing_Instance.GetBoost() != 1.0f)
                {
                    queryExpl.AddDetail(boostExpl);
                }
                queryExpl.AddDetail(idfExpl);

                Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");

                queryExpl.AddDetail(queryNormExpl);

                queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());

                result.AddDetail(queryExpl);

                // explain field weight
                System.String      field     = Enclosing_Instance.term.Field();
                ComplexExplanation fieldExpl = new ComplexExplanation();

                fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.term + " in " + doc + "), product of:");

                Explanation tfExpl = Scorer(reader).Explain(doc);

                fieldExpl.AddDetail(tfExpl);
                fieldExpl.AddDetail(idfExpl);

                Explanation fieldNormExpl = new Explanation();

                byte[] fieldNorms = reader.Norms(field);
                float  fieldNorm  = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f;

                fieldNormExpl.SetValue(fieldNorm);
                fieldNormExpl.SetDescription("fieldNorm(field=" + field + ", doc=" + doc + ")");
                fieldExpl.AddDetail(fieldNormExpl);

                fieldExpl.SetMatch(tfExpl.IsMatch());
                fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());

                result.AddDetail(fieldExpl);
                System.Boolean tempAux = fieldExpl.GetMatch();
                result.SetMatch(tempAux);

                // combine them
                result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());

                if (queryExpl.GetValue() == 1.0f)
                {
                    return(fieldExpl);
                }

                return(result);
            }
 public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation valSrcExpl)
 {
     float valSrcScore = valSrcExpl == null ? 0 : valSrcExpl.GetValue();
     Explanation exp = new Explanation(valSrcScore + subQueryExpl.GetValue(), "custom score: sum of:");
     exp.AddDetail(subQueryExpl);
     if (valSrcExpl != null)
     {
         exp.AddDetail(valSrcExpl);
     }
     return exp;
 }
Exemplo n.º 23
0
		/// <summary> Assert that an explanation has the expected score, and optionally that its
		/// sub-details max/sum/factor match to that score.
		/// 
		/// </summary>
		/// <param name="q">String representation of the query for assertion messages
		/// </param>
		/// <param name="doc">Document ID for assertion messages
		/// </param>
		/// <param name="score">Real score value of doc with query q
		/// </param>
		/// <param name="deep">indicates whether a deep comparison of sub-Explanation details should be executed
		/// </param>
		/// <param name="expl">The Explanation to match against score
		/// </param>
		public static void  VerifyExplanation(System.String q, int doc, float score, bool deep, Explanation expl)
		{
			float value_Renamed = expl.GetValue();
			Assert.AreEqual(score, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": score(doc=" + doc + ")=" + score + " != explanationScore=" + value_Renamed + " Explanation: " + expl);
			
			if (!deep)
				return ;
			
			Explanation[] detail = expl.GetDetails();
			if (detail != null)
			{
				if (detail.Length == 1)
				{
					// simple containment, no matter what the description says, 
					// just verify contained expl has same score
					VerifyExplanation(q, doc, score, deep, detail[0]);
				}
				else
				{
					// explanation must either:
					// - end with one of: "product of:", "sum of:", "max of:", or
					// - have "max plus <x> times others" (where <x> is float).
					float x = 0;
					System.String descr = expl.GetDescription().ToLower();
					bool productOf = descr.EndsWith("product of:");
					bool sumOf = descr.EndsWith("sum of:");
					bool maxOf = descr.EndsWith("max of:");
					bool maxTimesOthers = false;
					if (!(productOf || sumOf || maxOf))
					{
						// maybe 'max plus x times others'
						int k1 = descr.IndexOf("max plus ");
						if (k1 >= 0)
						{
							k1 += "max plus ".Length;
							int k2 = descr.IndexOf(" ", k1);
							try
							{
								x = SupportClass.Single.Parse(descr.Substring(k1, (k2) - (k1)).Trim());
								if (descr.Substring(k2).Trim().Equals("times others of:"))
								{
									maxTimesOthers = true;
								}
							}
							catch (System.FormatException)
							{
							}
						}
					}
					Assert.IsTrue(productOf || sumOf || maxOf || maxTimesOthers, q + ": multi valued explanation description=\"" + descr + "\" must be 'max of plus x times others' or end with 'product of'" + " or 'sum of:' or 'max of:' - " + expl);
					float sum = 0;
					float product = 1;
					float max = 0;
					for (int i = 0; i < detail.Length; i++)
					{
						float dval = detail[i].GetValue();
						VerifyExplanation(q, doc, dval, deep, detail[i]);
						product *= dval;
						sum += dval;
						max = System.Math.Max(max, dval);
					}
					float combined = 0;
					if (productOf)
					{
						combined = product;
					}
					else if (sumOf)
					{
						combined = sum;
					}
					else if (maxOf)
					{
						combined = max;
					}
					else if (maxTimesOthers)
					{
						combined = max + x * (sum - max);
					}
					else
					{
						Assert.IsTrue(false, "should never get here!");
					}
					Assert.AreEqual(combined, value_Renamed, EXPLAIN_SCORE_TOLERANCE_DELTA, q + ": actual subDetails combined==" + combined + " != value=" + value_Renamed + " Explanation: " + expl);
				}
			}
		}
Exemplo n.º 24
0
			public virtual Explanation Explain(IndexReader reader, int doc)
			{
				// explain query weight
				Explanation queryExpl = new Explanation();
				queryExpl.SetDescription("MatchAllDocsQuery:");
				
				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
				if (Enclosing_Instance.GetBoost() != 1.0f)
					queryExpl.AddDetail(boostExpl);
				queryExpl.SetValue(boostExpl.GetValue());
				
				return queryExpl;
			}
 public override Explanation CustomExplain(int doc, Explanation subQueryExpl, Explanation[] valSrcExpls)
 {
     if (valSrcExpls.Length == 0)
     {
         return subQueryExpl;
     }
     Explanation exp = new Explanation(valSrcExpls[0].GetValue() + subQueryExpl.GetValue(), "sum of:");
     exp.AddDetail(subQueryExpl);
     exp.AddDetail(valSrcExpls[0]);
     if (valSrcExpls.Length == 1)
     {
         exp.SetDescription("CustomMulAdd, sum of:");
         return exp;
     }
     Explanation exp2 = new Explanation(valSrcExpls[1].GetValue() * exp.GetValue(), "custom score: product of:");
     exp2.AddDetail(valSrcExpls[1]);
     exp2.AddDetail(exp);
     return exp2;
 }
Exemplo n.º 26
0
			public virtual Explanation Explain(IndexReader reader, int doc)
			{
				
				Explanation result = new Explanation();
				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
				
				System.Text.StringBuilder docFreqs = new System.Text.StringBuilder();
				System.Text.StringBuilder query = new System.Text.StringBuilder();
				query.Append('\"');
				for (int i = 0; i < Enclosing_Instance.terms.Count; i++)
				{
					if (i != 0)
					{
						docFreqs.Append(" ");
						query.Append(" ");
					}
					
					Term term = (Term) Enclosing_Instance.terms[i];
					
					docFreqs.Append(term.Text());
					docFreqs.Append("=");
					docFreqs.Append(reader.DocFreq(term));
					
					query.Append(term.Text());
				}
				query.Append('\"');
				
				Explanation idfExpl = new Explanation(idf, "idf(" + Enclosing_Instance.field + ": " + docFreqs + ")");
				
				// explain query weight
				Explanation queryExpl = new Explanation();
				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
				
				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
				if (Enclosing_Instance.GetBoost() != 1.0f)
					queryExpl.AddDetail(boostExpl);
				queryExpl.AddDetail(idfExpl);
				
				Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
				queryExpl.AddDetail(queryNormExpl);
				
				queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
				
				result.AddDetail(queryExpl);
				
				// explain field weight
				Explanation fieldExpl = new Explanation();
				fieldExpl.SetDescription("fieldWeight(" + Enclosing_Instance.field + ":" + query + " in " + doc + "), product of:");
				
				Explanation tfExpl = Scorer(reader).Explain(doc);
				fieldExpl.AddDetail(tfExpl);
				fieldExpl.AddDetail(idfExpl);
				
				Explanation fieldNormExpl = new Explanation();
				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
				float fieldNorm = fieldNorms != null ? Similarity.DecodeNorm(fieldNorms[doc]) : 0.0f;
				fieldNormExpl.SetValue(fieldNorm);
				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
				fieldExpl.AddDetail(fieldNormExpl);
				
				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
				
				result.AddDetail(fieldExpl);
				
				// combine them
				result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
				
				if (queryExpl.GetValue() == 1.0f)
					return fieldExpl;
				
				return result;
			}
Exemplo n.º 27
0
			public override Explanation Explain(IndexReader reader, int doc)
			{
				ComplexExplanation result = new ComplexExplanation();
				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
				
				Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
				
				// explain query weight
				Explanation queryExpl = new Explanation();
				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
				
				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
				if (Enclosing_Instance.GetBoost() != 1.0f)
					queryExpl.AddDetail(boostExpl);
				
				queryExpl.AddDetail(idfExpl);
				
				Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
				queryExpl.AddDetail(queryNormExpl);
				
				queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
				
				result.AddDetail(queryExpl);
				
				// explain field weight
				ComplexExplanation fieldExpl = new ComplexExplanation();
				fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
				
				Scorer scorer = Scorer(reader, true, false);
				if (scorer == null)
				{
					return new Explanation(0.0f, "no matching docs");
				}
				Explanation tfExpl = scorer.Explain(doc);
				fieldExpl.AddDetail(tfExpl);
				fieldExpl.AddDetail(idfExpl);
				
				Explanation fieldNormExpl = new Explanation();
				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
				float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):1.0f;
				fieldNormExpl.SetValue(fieldNorm);
				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
				fieldExpl.AddDetail(fieldNormExpl);
				
				fieldExpl.SetMatch(tfExpl.IsMatch());
				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
				
				result.AddDetail(fieldExpl);
				System.Boolean? tempAux = fieldExpl.GetMatch();
				result.SetMatch(tempAux);
				
				// combine them
				result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
				
				if (queryExpl.GetValue() == 1.0f)
					return fieldExpl;
				
				return result;
			}
Exemplo n.º 28
0
			public virtual Explanation Explain(IndexReader reader, int doc)
			{
				Explanation result = new Explanation();
				result.SetDescription("weight(" + GetQuery() + " in " + doc + "), product of:");
				
				Explanation idfExpl = new Explanation(idf, "idf(" + GetQuery() + ")");
				
				// explain query weight
				Explanation queryExpl = new Explanation();
				queryExpl.SetDescription("queryWeight(" + GetQuery() + "), product of:");
				
				Explanation boostExpl = new Explanation(Enclosing_Instance.GetBoost(), "boost");
				if (Enclosing_Instance.GetBoost() != 1.0f)
					queryExpl.AddDetail(boostExpl);
				
				queryExpl.AddDetail(idfExpl);
				
				Explanation queryNormExpl = new Explanation(queryNorm, "queryNorm");
				queryExpl.AddDetail(queryNormExpl);
				
				queryExpl.SetValue(boostExpl.GetValue() * idfExpl.GetValue() * queryNormExpl.GetValue());
				
				result.AddDetail(queryExpl);
				
				// explain field weight
				Explanation fieldExpl = new Explanation();
				fieldExpl.SetDescription("fieldWeight(" + GetQuery() + " in " + doc + "), product of:");
				
				Explanation tfExpl = Scorer(reader).Explain(doc);
				fieldExpl.AddDetail(tfExpl);
				fieldExpl.AddDetail(idfExpl);
				
				Explanation fieldNormExpl = new Explanation();
				byte[] fieldNorms = reader.Norms(Enclosing_Instance.field);
				float fieldNorm = fieldNorms != null?Similarity.DecodeNorm(fieldNorms[doc]):0.0f;
				fieldNormExpl.SetValue(fieldNorm);
				fieldNormExpl.SetDescription("fieldNorm(field=" + Enclosing_Instance.field + ", doc=" + doc + ")");
				fieldExpl.AddDetail(fieldNormExpl);
				
				fieldExpl.SetValue(tfExpl.GetValue() * idfExpl.GetValue() * fieldNormExpl.GetValue());
				
				result.AddDetail(fieldExpl);
				
				// combine them
				result.SetValue(queryExpl.GetValue() * fieldExpl.GetValue());
				
				if (queryExpl.GetValue() == 1.0f)
					return fieldExpl;
				
				return result;
			}
Exemplo n.º 29
0
            public virtual Explanation Explain(IndexReader reader, int doc)
            {
                Explanation sumExpl = new Explanation();

                sumExpl.SetDescription("sum of:");
                int   coord    = 0;
                int   maxCoord = 0;
                float sum      = 0.0f;

                for (int i = 0; i < weights.Count; i++)
                {
                    BooleanClause c = (BooleanClause)Enclosing_Instance.clauses[i];
                    Weight        w = (Weight)weights[i];
                    Explanation   e = w.Explain(reader, doc);
                    if (!c.IsProhibited())
                    {
                        maxCoord++;
                    }
                    if (e.GetValue() > 0)
                    {
                        if (!c.IsProhibited())
                        {
                            sumExpl.AddDetail(e);
                            sum += e.GetValue();
                            coord++;
                        }
                        else
                        {
                            return(new Explanation(0.0f, "match prohibited"));
                        }
                    }
                    else if (c.IsRequired())
                    {
                        return(new Explanation(0.0f, "match required"));
                    }
                }
                sumExpl.SetValue(sum);

                if (coord == 1)
                {
                    // only one clause matched
                    sumExpl = sumExpl.GetDetails()[0];                     // eliminate wrapper
                }
                float coordFactor = similarity.Coord(coord, maxCoord);

                if (coordFactor == 1.0f)
                {
                    // coord is no-op
                    return(sumExpl);
                }
                // eliminate wrapper
                else
                {
                    Explanation result = new Explanation();
                    result.SetDescription("product of:");
                    result.AddDetail(sumExpl);
                    result.AddDetail(new Explanation(coordFactor, "coord(" + coord + "/" + maxCoord + ")"));
                    result.SetValue(sum * coordFactor);
                    return(result);
                }
            }