View Javadoc

1   /*
2    * #%L
3    * prolobjectlink-jpi-jtrolog
4    * %%
5    * Copyright (C) 2012 - 2018 WorkLogic Project
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as
9    * published by the Free Software Foundation, either version 2.1 of the
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-2.1.html>.
20   * #L%
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   * @author janerist@stud.ntnu.no
33   * @author ivar.orstavik@hist.no
34   */
35  @SuppressWarnings({ "rawtypes" })
36  class ChoicePoint {
37  	// CP head
38  	Struct head;
39  	int headCtx = -1;
40  	// CP body
41  	private Struct[] body;
42  	private int nextInBody = 0;
43  	private int bodySize = 0;
44  	int bodyCtx;
45  
46  	// CP parent and cutParent
47  	ChoicePoint parent;
48  	ChoicePoint cutParent;
49  
50  	// alternative rules
51  	List alternatives;
52  	int altPos;
53  	int alternativeCount;
54  
55  	// or primitive
56  	PrimitiveInfo prim;
57  
58  	/**
59  	 * recycles previously used CP objects on the stack
60  	 * 
61  	 * @param s
62  	 * @param ctx
63  	 * @param parent
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  	 * removes any choice points (alternative rules) on the ChoicePoint.
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 }