1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package jTrolog.engine;
23
24 import jTrolog.terms.Struct;
25 import jTrolog.terms.Clause;
26 import jTrolog.errors.PrologException;
27 import jTrolog.parser.Parser;
28
29 import java.util.List;
30
31
32
33
34
35 @SuppressWarnings({ "rawtypes" })
36 class ChoicePoint {
37
38 Struct head;
39 int headCtx = -1;
40
41 private Struct[] body;
42 private int nextInBody = 0;
43 private int bodySize = 0;
44 int bodyCtx;
45
46
47 ChoicePoint parent;
48 ChoicePoint cutParent;
49
50
51 List alternatives;
52 int altPos;
53 int alternativeCount;
54
55
56 PrimitiveInfo prim;
57
58
59
60
61
62
63
64
65 final void set(final Struct s, final int ctx, final ChoicePoint parent) throws PrologException {
66 head = s;
67 headCtx = ctx;
68 this.parent = parent;
69 cutParent = Parser.isSemiAndNotIf(parent.head) ? parent.parent.cutParent : this;
70
71 altPos = 0;
72 this.alternatives = null;
73 this.alternativeCount = 0;
74
75 bodyCtx = -1;
76
77 nextInBody = 0;
78 bodySize = 0;
79 }
80
81 final void setRules(final List rules) throws PrologException {
82 altPos = 0;
83 alternatives = rules;
84 alternativeCount = alternatives.size();
85 }
86
87 final boolean hasAlternatives() {
88 return altPos < alternativeCount;
89 }
90
91 final Clause nextAlternative() {
92 return (Clause) alternatives.get(altPos++);
93 }
94
95
96
97
98 final void cutAlternatives() {
99 altPos = alternativeCount;
100 }
101
102 public String toString() {
103 if (prim != null)
104 return "!!" + head + "<" + headCtx + ">" + "!!";
105 String s2 = head == null ? "?-\n " : head + "<" + headCtx + "> :-\n ";
106 if (body != null) {
107 for (int i = 0; i < bodySize; i++) {
108 if (i != 0)
109 s2 += ",\n ";
110 Object rule = body[i];
111 if (i == nextInBody)
112 s2 += "**" + rule + "**";
113 else
114 s2 += rule;
115 }
116 }
117 if (hasAlternatives()) {
118 s2 += "\n\n rules:\n";
119 for (int i = altPos; i < alternativeCount; i++)
120 s2 += " " + alternatives.get(i) + "\n";
121 }
122 return s2;
123 }
124
125 boolean hasTODO() {
126 return nextInBody < bodySize;
127 }
128
129 public void fail() {
130 bodySize = 0;
131 nextInBody = 0;
132 parent.nextInBody--;
133 }
134
135 Struct getTODO() {
136 return body[nextInBody++];
137 }
138
139 final void setBody(final Struct[] body, final int bodyCtx) {
140 this.bodyCtx = bodyCtx;
141 this.body = body;
142 nextInBody = 0;
143 bodySize = body.length;
144 }
145
146 public void reuse() {
147 this.head = body[0];
148 this.headCtx = bodyCtx;
149 this.nextInBody = 0;
150 this.altPos = 0;
151 }
152 }