aboutsummaryrefslogtreecommitdiffstats
path: root/searchlib/src/main/java/com/yahoo/searchlib/rankingexpression/evaluation/Context.java
blob: 67024b017611bcac74828b9629c97d47fd5e4221 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.searchlib.rankingexpression.evaluation;

import com.yahoo.searchlib.rankingexpression.Reference;
import com.yahoo.searchlib.rankingexpression.rule.Arguments;
import com.yahoo.searchlib.rankingexpression.rule.ExpressionNode;
import com.yahoo.tensor.Tensor;
import com.yahoo.tensor.TensorType;
import com.yahoo.tensor.evaluation.EvaluationContext;

import java.util.Set;
import java.util.stream.Collectors;

/**
 * The context providing value bindings for an expression evaluation.
 *
 * @author bratseth
 */
public abstract class Context implements EvaluationContext<Reference> {

    /** The default value to return if the value has not been set  */
    static Value defaultMissingValue = DoubleValue.zero;

    /** The value to return if the value has not been set  */
    Value missingValue;

    /**
     * Returns the value of a simple variable name.
     *
     * @param name the name of the variable whose value to return.
     * @return the value of the named variable.
     */
    public abstract Value get(String name);

    @Override
    public TensorType getType(String reference) {
        throw new UnsupportedOperationException("Not able to parse general references from string form");
    }

    /** Returns a variable as a tensor */
    @Override
    public Tensor getTensor(String name) { return get(name).asTensor(); }

    /**
     * <p>Returns the value of a <i>structured variable</i> on the form
     * <code>name(argument*)(.output)?</code>, where <i>argument</i> is any
     * string.  This may be used to implement more advanced variables whose
     * values are calculated at runtime from arguments.  Supporting this in a
     * context is optional.
     *
     * <p>This default implementation generates a name on the form
     * <code>name(argument1, argument2, ...argumentN).output</code>.
     * If there are no arguments the parenthesis are omitted.
     * If there is no output, the dot is omitted.</p>
     *
     * @param name      the name of this variable.
     * @param arguments the parsed arguments as given in the textual expression.
     * @param output    the name of the value to output (to enable one named
     *                  calculation to output several), or null to output the
     *                  "main" (or only) value.
     */
    // TODO: Remove/change to use reference?
    public Value get(String name, Arguments arguments, String output) {
        if (arguments != null && arguments.expressions().size() > 0)
            name = name + "(" + arguments.expressions().stream().map(ExpressionNode::toString).collect(Collectors.joining(",")) + ")";
        if (output !=null)
            name = name + "." + output;
        return get(name);
    }

    /**
     * <p>Lookup by index rather than name. This is supported by some optimized
     * context subclasses.  This default implementation throws
     * UnsupportedOperationException.</p>
     *
     * @param index the index of the variable whose value to return.
     * @return the value of the indexed variable.
     */
    public Value get(int index) {
        throw new UnsupportedOperationException(this + " does not support variable lookup by index");
    }

    /**
     * Lookup by index rather than name directly to a double. This is supported by some optimized
     * context subclasses.  This default implementation throws
     * UnsupportedOperationException.
     *
     * @param index the index of the variable whose value to return.
     * @return the value of the indexed variable.
     */
    public double getDouble(int index) {
        throw new UnsupportedOperationException(this + " does not support variable lookup by index");
    }

    /**
     * Same as put(name,DoubleValue.frozen(value))
     */
    public final void put(String name, double value) {
        put(name, DoubleValue.frozen(value));
    }

    /**
     * Sets a value to this, or throws an UnsupportedOperationException if
     * this is not supported. This default implementation does the latter.
     *
     * @param name  the name of the variable to set.
     * @param value the value to set. Ownership of this value is transferred to this - if it is mutable
     *              (not frozen) it may be modified during execution
     */
    public void put(String name, Value value) {
        throw new UnsupportedOperationException(this + " does not support variable assignment");
    }

    /**
     * Returns all the names available in this, or throws an
     * UnsupportedOperationException if this operation is not supported. This
     * default implementation does the latter.
     *
     * @return the set of all variable names.
     */
    public Set<String> names() {
        throw new UnsupportedOperationException(this + " does not support return a list of its names");
    }

}