blob: 47eb1e2a81112f351a28b63b744b48387b72a981 (
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
126
|
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.prelude.semantics.engine;
import com.yahoo.prelude.semantics.rule.Condition;
/**
* A choice point in an rule evaluation. A choicepoint is open if there are other choices to make at the point,
* closed if there are no further choices. In addition it contains enough information to enable
* the rule evaluation to backtrack to this point
*
* @author bratseth
*/
public class Choicepoint {
/** Whether there are (or may be) open choices to explore at this choicepoint yet */
private boolean open=true;
/** The number of tries made at this choice point */
private int tries=0;
/** The condition creating this choicepoint */
private Condition condition;
/** The state this choice point can be rolled back to */
private State state;
private RuleEvaluation owner;
public Choicepoint(RuleEvaluation e, Condition condition) {
this.owner=e;
state=new State(this,e);
this.condition=condition;
if (e.getTraceLevel()>=5)
e.trace(5,"Added choice point at " + e.currentItem() + " for '" + condition + "'");
}
/** Returns the condition which created this choice point */
public Condition getCondition() { return condition; }
/** Returns wether there are (or may be) open choices to explore at this choicepoint yet */
public boolean isOpen() { return open; }
/** Marks this choice point as closed (!open) - there are no further choices to explore */
public void close() { this.open=false; }
/** Returns the number open tries made at this point */
public int tryCount() { return tries; }
/** Registers that another try has been made */
public void addTry() {
tries++;
}
/**
* Backtrack to the evaluation state at the point where this choicepoint were instantiated.
*/
public void backtrack() {
state.backtrack(owner);
if (owner.getTraceLevel()>=5)
owner.trace(5,"Backtracked to " + owner.currentItem() + " for '" + condition + "'");
}
/** Backtracks the position only, not matches */
public void backtrackPosition() {
state.backtrackPosition(owner);
}
/**
* Updates the state of this choice point to the current state of its evaluation
*/
public void updateState() {
state.updateState(owner);
}
/** Returns the state of this choice point */
public State getState() { return state; }
/** The state of this choicepoint */
public final static class State {
private int position=0;
private int referencedMatchCount=0;
private int nonreferencedMatchCount=0;
public State(Choicepoint choicepoint,RuleEvaluation evaluation) {
updateState(evaluation);
}
public void updateState(RuleEvaluation evaluation) {
position=evaluation.currentPosition();
referencedMatchCount=evaluation.getReferencedMatchCount();
nonreferencedMatchCount=evaluation.getNonreferencedMatchCount();
}
/** Backtrack to the evaluation state at the point where this choicepoint were instantiated */
public void backtrack(RuleEvaluation e) {
backtrackPosition(e);
// Is this check masking errors?
if (e.referencedMatches().size()>referencedMatchCount)
e.referencedMatches().subList(referencedMatchCount,
e.referencedMatches().size())
.clear();
// Is this check masking errors?
if (e.nonreferencedMatches().size()>nonreferencedMatchCount)
e.nonreferencedMatches().subList(nonreferencedMatchCount,
e.nonreferencedMatches().size())
.clear();
}
public void backtrackPosition(RuleEvaluation e) {
e.setPosition(position);
}
public int getPosition() { return position; }
public int getReferencedMatchCount() { return referencedMatchCount; }
public int getNonreferencedMatchCount() { return nonreferencedMatchCount; }
}
}
|