Bug 154811 - [compiler] Internal compiler error while parsing/formatting
Summary: [compiler] Internal compiler error while parsing/formatting
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.3 M3   Edit
Assignee: David Audel CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-08-23 01:38 EDT by Jacek Kisyński CLA
Modified: 2006-10-30 15:00 EST (History)
0 users

See Also:


Attachments
Proposed fix (7.80 KB, patch)
2006-10-25 03:36 EDT, David Audel CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jacek Kisyński CLA 2006-08-23 01:38:35 EDT
Simple mistake at 604:55 in the code listed at the bottom causes the following error:

Internal compiler error java.lang.ClassCastException: 
 org.eclipse.jdt.internal.compiler.parser.RecoveredBlock at 
 org.eclipse.jdt.internal.compiler.parser.Parser.consumeType
 HeaderNameWithTypeParameters(Parser.java:2109) at 
 org.eclipse.jdt.internal.compiler.parser.Parser.consumeRule
 (Parser.java:4961) at 
 org.eclipse.jdt.internal.compiler.parser.Parser.parse
 (Parser.java:8839) at 
 org.eclipse.jdt.internal.compiler.parser.Parser.parse
 (Parser.java:9160) at 
 org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.parse
 Statements(MethodDeclaration.java:117) at 
 org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.parseM
 ethod(TypeDeclaration.java:805) at 
 org.eclipse.jdt.internal.compiler.parser.Parser.getMethodBod
 ies(Parser.java:8111) at 
 org.eclipse.jdt.internal.compiler.Compiler.process
 (Compiler.java:583) at 
 org.eclipse.jdt.internal.compiler.Compiler.compile
 (Compiler.java:411) at 
 org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.co
 mpile(AbstractImageBuilder.java:300) at 
 org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.co
 mpile(AbstractImageBuilder.java:237) at 
 org.eclipse.jdt.internal.core.builder.IncrementalImageBuilder.
 build(IncrementalImageBuilder.java:120) at 
 org.eclipse.jdt.internal.core.builder.JavaBuilder.buildDeltas
 (JavaBuilder.java:260) at 
 org.eclipse.jdt.internal.core.builder.JavaBuilder.build
 (JavaBuilder.java:185) at 
 org.eclipse.core.internal.events.BuildManager$2.run
 (BuildManager.java:603) at 
 org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:
 37) at 
 org.eclipse.core.internal.events.BuildManager.basicBuild
 (BuildManager.java:167) at 
 org.eclipse.core.internal.events.BuildManager.basicBuild
 (BuildManager.java:201) at 
 org.eclipse.core.internal.events.BuildManager$1.run
 (BuildManager.java:230) at 
 org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:
 37) at 
 org.eclipse.core.internal.events.BuildManager.basicBuild
 (BuildManager.java:233) at 
 org.eclipse.core.internal.events.BuildManager.basicBuildLo
 op(BuildManager.java:252) at 
 org.eclipse.core.internal.events.BuildManager.build
 (BuildManager.java:285) at 
 org.eclipse.core.internal.events.AutoBuildJob.doBuild
 (AutoBuildJob.java:145) at 
 org.eclipse.core.internal.events.AutoBuildJob.run
 (AutoBuildJob.java:208) at 
 org.eclipse.core.internal.jobs.Worker.run(Worker.java:58)


-------------------- FactorStoreIndexed.java --------------------------
import java.util.Iterator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.NoSuchElementException;

/**
 * A place to store factors during computation. This indexes to find the the variable proposed by a heuristic efficiently.
 * 
 * @param <T> type of the heuristic object.
 * 
 * <p>
 * This file is part of CIspace.ve package. <br>
 * CIspace.ve package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your option) any later version. <br>
 * CIspace.ve package is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. <br>
 * You should have received a copy of the GNU General Public License along with CIspace.ve package; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 * </p>
 * 
 * @author David Poole
 * 
 * @version 1.1 22-August-2006
 * 
 * <p>
 * TODO Remove bug in min-fill(?) - there are variables with no factors associated with<br>
 * *************************************
 * <ul>
 * Changes by Jacek Kisy&#324;ski:
 * <li>changed to abstract, heuristic value stored in parameterized type object - it allows to implement constraints on heuristic.
 * <li>remove(Variable) and willBeNext() methods added - used by {@link CIspace.ve.QueryStepByStep}.
 * <li>use of generics (update to J2SE 5.0)
 * <li>use of automatic boxing and unboxing (update to J2SE 5.0)
 * <li>use of generics (update to J2SE 5.0)
 * <li>uses Variable.compareTo(Object) instead of Variable.getId()
 * <li>uses Variable.equals(Object) instead of "=="
 * <li>uses Variable.getDomainSize() instead of Variable.getDomain().length
 * <li>implements (not extends) CIspace.ve.FactorStore
 * <li>many identifiers renamed
 * <li>unnecessary recomputing of neighbours removed (methods: clean_up() and compute_neighbours() removed)
 * <li>unnecessary recomputing of heuristics removed
 * <li><b>Interface change </b> heuristics added/renamed: "min-factor" (="min-weight") || "min-degree" (="min-size") || "min-fill"
 * (="min-deficiency", "min-discrepancy") || "max-cardinality" (constructor takes one more parameter)
 * <li>throws java.lang.IllegalArgumentException() if provided ordering heuristic is not one of listed above
 * <li>iterators are now ItrSafe not CIspace.ve.FactorIterators
 * <li>member VariableToEliminate.positionInPQ removed (never used)
 * <li>heap rebuilding debugged (it wasn't being rebuild after heuristics were updated)
 * <li>maxNumNeighs debugged (it was equal to numbers of variables to sum out)
 * <li>parameter Variables added in constructor
 * <li>private class FactorLink removed and Factor index created (so it can be used for min-fill heuristic)
 * <li>enumFacsRemaining class removed
 * </ul>
 */
public abstract class FactorStoreIndexed<T extends Comparable<T>> implements FactorStore {

	/** Priority queue of Variables to be eliminated stored as VariableToEliminate. */
	protected VariableToEliminate<T>[] varsPQ;

	/** Number of Variables to be eliminated. */
	protected int numVariablesToEliminate;

	/**
	 * Elimination heuristic: <br>
	 * "min-factor" (="min-weight") || "min-degree" (="min-size") || "min-fill" (="min-deficiency", "min-discrepancy") || "max-cardinality".
	 */
	String how;

	/** The last Variable returned. */
	private VariableToEliminate<T> last = null;

	/** Maps Variable to VariableToEliminate */
	private HashMap<Variable, VariableToEliminate<T>> varToVarInQuery;

	/** Final factors. */
	private Factor[] finalFacs;

	/** Number of final Factors. */
	private int numFinalFacs;

	/** Index of factors. */
	private HashMap<Variable, HashSet<Factor>> factorIndex;

	/**
	 * Constructor.
	 * 
	 * @param toSumOut - Variables to be summed out.
	 * @param initFactorsIterator - initial Factors.
	 * @param nrInitFactors - number of initial Factors.
	 * @param variablesIterator - Variables in the network.
	 * @param numVariables - number of Variables in the network.
	 * @param how an ordering heuristic: min-factor (=min-weight), min-degree (=min-size), min-fill (=min-deficiency, min-discrepancy),
	 * max-cardinality.
	 * 
	 * @throws java.lang.IllegalArgumentException() if provided ordering heuristic is not one of listed above.
	 */
	public FactorStoreIndexed(Variable[] toSumOut, Iterator<Factor> initFactorsIterator, int nrInitFactors, Iterator<Variable> variablesIterator,
			int numVariables, String how) {
		this.numVariablesToEliminate = toSumOut.length;
		this.varToVarInQuery = new HashMap<Variable, VariableToEliminate<T>>(this.numVariablesToEliminate * 3 / 2);
		this.finalFacs = new Factor[nrInitFactors + 1];
		this.numFinalFacs = 0;

		// Determine heuristic
		if ((how.equals("min-degree")) || ((how.equals("min-size"))))
			this.how = "min-degree";
		else if ((how.equals("min-fill")) || (how.equals("min-deficiency")) || (how.equals("min-discrepancy")))
			this.how = "min-fill";
		else if ((how.equals("min-factor")) || (how.equals("min-weight")))
			this.how = "min-factor";
		else if (how.equals("max-cardinality"))
			this.how = "max-cardinality";
		else
			throw new IllegalArgumentException("Wrong ordering heuristic!");

		// Create VariablesToEliminate
		this.createHeapSpace(toSumOut, numVariables);

		// Create FactorIndex
		this.factorIndex = new HashMap<Variable, HashSet<Factor>>((int) Math.round(1.4 * numVariables));
		while (variablesIterator.hasNext())
			this.factorIndex.put(variablesIterator.next(), new HashSet<Factor>());
		while (initFactorsIterator.hasNext())
			this.add(initFactorsIterator.next());

		// Update heuristic
		if (this.how.equals("min-degree"))
			for (int i = 0; i < this.numVariablesToEliminate; i++)
				this.varsPQ[i].setMinDegree();
		else if (this.how.equals("min-fill"))
			for (int i = 0; i < this.numVariablesToEliminate; i++)
				this.varsPQ[i].setMinFill();
		else if (this.how.equals("min-factor"))
			for (int i = 0; i < this.numVariablesToEliminate; i++)
				this.varsPQ[i].setMinFactor();
		// else this.how.equals("max-cardinality")) - do nothing, all heuristics for max-cardinality are zero right now

		// Make into a heap
		for (int i = 1; i < this.numVariablesToEliminate; i++)
			shuffleUp(i);
	}

	/**
	 * @param toSumOut
	 * @param numVariables
	 */
	abstract protected void createHeapSpace(Variable[] toSumOut, int numVariables);

	/**
	 * @see CIspace.ve.FactorStore#hasNext()
	 */
	public boolean hasNext() {
		return this.numVariablesToEliminate > 0;
	}

	/**
	 * Used by {@link CIspace.ve.QueryStepByStep}.
	 * 
	 * @return variable, which will be eliminated next.
	 */
	protected Variable nextToEliminate() {
		return this.varsPQ[0].var;
	}

	/**
	 * @see CIspace.ve.FactorStore#next()
	 */
	public Variable next() {
		// System.out.println("\n" + varsPQ[0].var.getName() + " is at the top of the heap");
		// System.out.println(" num factors:" + varsPQ[0].numFactors + ". numNeighbours:" + varsPQ[0].numNeighbours);
		this.last = this.varsPQ[0];
		this.varsPQ[0] = this.varsPQ[--this.numVariablesToEliminate];
		// Update heuristic (if "max-cardinality" is a current heuristic)
		if (this.how.equals("max-cardinality")) {
			for (int i = 0; i < this.last.numNeighbours; i++) {
				VariableToEliminate vte = this.varToVarInQuery.get(this.last.neighbours[i]);
				if (vte != null)
					vte.setHeuristicValue(vte.recomputeMaxCardinality());
			}
			// Rebuild the heap
			for (int i = ((this.numVariablesToEliminate / 2) - 1); i >= 0; i--)
				shuffleDown(i);
		} else
			// Rebuild the heap
			shuffleDown(0);
		// Remove Factors on last from last's index (we remove those Factors from indexes of other Variables in
		// FactorStoreIndexed.EnumFacsRemoved.next()
		this.factorIndex.remove(this.last.var);
		return this.last.var;
	}

	/**
	 * Removes variable from the FactorStore. Used by {@link CIspace.ve.QueryStepByStep}. Shouldn't be used during inference with this heuristic!
	 * 
	 * @param variable to be removed from the FactorStore.
	 */
	protected void remove(Variable variable) {
		int i = 0;
		while (!variable.equals(this.varsPQ[i].var))
			i++;
		this.last = this.varsPQ[i];
		this.varsPQ[i] = this.varsPQ[--this.numVariablesToEliminate];
		// Update heuristic (if "max-cardinality" is a current heuristic)
		if (this.how.equals("max-cardinality")) {
			for (int j = 0; j < this.last.numNeighbours; j++) {
				VariableToEliminate vte = this.varToVarInQuery.get(this.last.neighbours[j]);
				if (vte != null)
					vte.setHeuristicValue(vte.recomputeMaxCardinality());
			}
			// Rebuild the heap
			for (int j = ((this.numVariablesToEliminate / 2) - 1); j >= 0; j--)
				shuffleDown(j);
		} else
			// Rebuild the heap
			shuffleDown(0);
		// Remove Factors on last from last's index
		this.factorIndex.remove(this.last.var);
		// Remove factors on last from other indexes
		Iterator<Factor> factorsIterator = this.last.factors.iterator();
		while (factorsIterator.hasNext()) {
			Factor factor = factorsIterator.next();
			ItrSafe<Variable> variablesIterator = factor.getVariables();
			while (variablesIterator.hasNext()) {
				Variable var = variablesIterator.next();
				VariableToEliminate vte = FactorStoreIndexed.this.varToVarInQuery.get(var);
				if (vte != null) {
					if (vte != FactorStoreIndexed.this.last)
						// Remove from index
						FactorStoreIndexed.this.factorIndex.get(var).remove(factor);
					// Update neighbours count (and neighbours list)
					vte.removeNeighbours(factor.variables);
				} else
					// Remove from index
					FactorStoreIndexed.this.factorIndex.get(var).remove(factor);
			}
		}
	}

	/**
	 * Make into a heap by shuffling down the value at position pos. This assumes that varsPQ is a heap except maybe that the value at position pos is
	 * larger than it's children.
	 * 
	 * @param pos position of the value to be shuffled down.
	 */
	private void shuffleDown(int pos) {
		int smallest;
		if (2 * pos + 1 < this.numVariablesToEliminate && (this.varsPQ[2 * pos + 1].heuristicValue.compareTo(this.varsPQ[pos].heuristicValue) < 0))
			smallest = 2 * pos + 1;
		else
			smallest = pos;
		if (2 * pos + 2 < this.numVariablesToEliminate
				&& (this.varsPQ[2 * pos + 2].heuristicValue.compareTo(this.varsPQ[smallest].heuristicValue) < 0))
			smallest = 2 * pos + 2;
		if (smallest != pos) {
			// swap varsPQ[pos] & varsPQ[smallest]
			VariableToEliminate<T> tmp = this.varsPQ[pos];
			this.varsPQ[pos] = this.varsPQ[smallest];
			this.varsPQ[smallest] = tmp;
			shuffleDown(smallest);
		}
	}

	/**
	 * Make into a heap by shuffling up the value at position pos. This assumes that varsPQ is a heap except maybe that the value at position pos is
	 * smaller than it's parent.
	 * 
	 * @param pos position of the value to be shuffled up.
	 */
	private void shuffleUp(int pos) {
		VariableToEliminate<T> tmp = this.varsPQ[pos];
		while (pos > 0 & (tmp.heuristicValue.compareTo(this.varsPQ[(pos - 1) / 2].heuristicValue) < 0)) {
			this.varsPQ[pos] = this.varsPQ[(pos - 1) / 2];
			pos = (pos - 1) / 2;
		}
		this.varsPQ[pos] = tmp;
	}

	/**
	 * @see CIspace.ve.FactorStore#addFactorComputed(CIspace.ve.Factor)
	 */
	public void addFactorComputed(Factor factor) {
		this.add(factor);
		if (!this.how.equals("max-cardinality")) {
			// ---------------------- MIN-DEGREE --------------------------
			if (this.how.equals("min-degree")) {
				for (int i = 0; i < factor.variables.length; i++) {
					VariableToEliminate vte = this.varToVarInQuery.get(factor.variables[i]);
					if (vte != null)
						vte.setHeuristicValue(vte.recomputeMinDegree());
				}
			// ---------------------- MIN-FILL --------------------------------
			else if (this.how.equals("min-fill")) {
				// Find neigbours of eliminated node and their neighbours.
				HashSet<VariableToEliminate> toUpdate = new HashSet<VariableToEliminate>();
				for (int i = 0; i < factor.variables.length; i++) {
					VariableToEliminate vte = this.varToVarInQuery.get(factor.variables[i]);
					if (vte != null) {
						toUpdate.add(vte);
						for (int j = 0; j < vte.numNeighbours; j++) {
							VariableToEliminate vte2 = this.varToVarInQuery.get(vte.neighbours[i]);
							if (vte2 != null)
								toUpdate.add(vte2);
						}
					}
				}
				// Recompute min-fill heuristic for neigbours of eliminated node and their neighbours.
				Iterator<VariableToEliminate> toUpdateIterator = toUpdate.iterator();
				while (toUpdateIterator.hasNext())
					toUpdateIterator.next().setHeuristicValue(recomputeMinFill());
			}
			// ---------------------- MIN-FACTOR --------------------------
			else
				// (this.how.equals("min-factor"))
				for (int i = 0; i < factor.variables.length; i++) {
					VariableToEliminate vte = this.varToVarInQuery.get(factor.variables[i]);
					if (vte != null)
						vte.setHeuristicValue(vte.recomputeMinFactor());
				}
			// ----------------------- REBUILD THE HEAP ------------------
			for (int i = ((this.numVariablesToEliminate / 2) - 1); i >= 0; i--)
				shuffleDown(i);
		}
		// else - do nothing, heuristics for max-cardinality couldn't change.
	}

	/**
	 * @see CIspace.ve.FactorStore#enumFactorsRemoved()
	 */
	public ItrSafe<Factor> enumFactorsRemoved() {
		return new EnumFacsRemoved();
	}

	/**
	 * Simple Iterator class. Does not provide opportunity to remove elements from the container.
	 * <p>
	 * This code is based on the Iterator code in {@link java.util.AbstractList}.
	 * 
	 * @author David Poole (original code) & Jacek Kisynski (adaptation for #CSP, update to Java2)
	 * 
	 * @version 1.0 23-June-2004
	 */
	private class EnumFacsRemoved extends ItrSafe<Factor> {

		/** Factors for the last Variable returned. */
		Iterator<Factor> factorsIterator = FactorStoreIndexed.this.last.factors.iterator();

		/**
		 * @return true if the iterator has more elements.
		 */
		public boolean hasNext() {
			return this.factorsIterator.hasNext();
		}

		/**
		 * @throws NoSuchElementException
		 * 
		 * @return the next element in the iteration.
		 */
		public Factor next() {
			Factor res = this.factorsIterator.next();
			for (int i = 0; i < res.variables.length; i++) {
				VariableToEliminate vte = FactorStoreIndexed.this.varToVarInQuery.get(res.variables[i]);
				if (vte != null) {
					if (vte != FactorStoreIndexed.this.last)
						// Remove from index
						FactorStoreIndexed.this.factorIndex.get(res.variables[i]).remove(res);
					// else - we don't remove from current HashSet as it would cause ConcurrentModification Exception, we simply remove the whole
					// HashSet in FactorStoreIndexed.next() method and keep it only as a member of FactorStoreIndexed.last.
					// Update neighbours count (and neighbours list)
					vte.removeNeighbours(res.variables);
				} else
					// Remove from index
					FactorStoreIndexed.this.factorIndex.get(res.variables[i]).remove(res);
			}
			return res;
		}
	}

	/**
	 * @see CIspace.ve.FactorStore#enumFactorsFinal()
	 */
	public ItrSafe<Factor> enumFactorsFinal() {
		return new ItrArray<Factor>(this.finalFacs, this.numFinalFacs);
	}

	/**
	 * This class provides the infrastructure for the Variable in the priority queue.
	 * 
	 * @param <T1> type of the heuristic object.
	 * 
	 * @author David Poole (original code) & Jacek Kisynski (adaptation for #CSP, update to Java2)
	 * 
	 * @version 1.0 26-January-2005
	 */
	protected abstract class VariableToEliminate<T1 extends T> {

		/** The Variable */
		private Variable var;

		/**
		 * The Variables that are neighbours. In order. Note that this does not only include VariablesToEliminate but also all other Variables (but
		 * does not include this.VariableToEliminate itself.
		 */
		private Variable[] neighbours;

		/** Number of factors which makes particular Variable to be a neighbour. In order. */
		private int[] neighboursCount;

		/** The number of neighbours. */
		protected int numNeighbours;

		/** The index of the Factors that involve this Variable. In no particular order. */
		private HashSet<Factor> factors;

		/** The number of factors */
		private int numFactors;

		/** If heuristic is "max-cardinality" then it is equal to (0 - number of eliminated neighbours). */
		protected long maxCardinality;

		/** Value of the current heuristic. */
		private T1 heuristicValue;

		/**
		 * Constructor.
		 * 
		 * @param variable
		 * @param maxNumNeighs
		 */
		protected VariableToEliminate(Variable variable, int maxNumNeighs) {
			this.var = variable;
			FactorStoreIndexed.this.varToVarInQuery.put(variable, (VariableToEliminate<T>) this);
			this.neighbours = new VariableNature[maxNumNeighs];
			this.numNeighbours = 0;
		}

		/**
		 * Adds neighbours to VariableToEliminate.
		 * 
		 * @param variables to be added.
		 */
		void addNeighbours(Variable[] variables) {
			Variable[] newNeighbours = new Variable[this.numNeighbours + variables.length];
			int[] newNeighboursCount = new int[this.numNeighbours + variables.length];
			// Merging algorithm
			int vPos = 0;
			int nbsPos = 0;
			int newPos = 0;
			while (vPos < variables.length && nbsPos < this.numNeighbours) {
				if (variables[vPos].equals(this.var))
					vPos++;
				else if (variables[vPos].equals(this.neighbours[nbsPos])) {
					newNeighbours[newPos] = variables[vPos++];
					newNeighboursCount[newPos++] = this.neighboursCount[nbsPos++] + 1;
				} else if (variables[vPos].compareTo(this.neighbours[nbsPos]) < 0) {
					newNeighbours[newPos] = variables[vPos++];
					newNeighboursCount[newPos++] = 1;
				} else {
					newNeighbours[newPos] = this.neighbours[nbsPos];
					newNeighboursCount[newPos++] = this.neighboursCount[nbsPos++];
				}
			}
			while (vPos < variables.length)
				if (variables[vPos].equals(this.var))
					vPos++;
				else {
					newNeighbours[newPos] = variables[vPos++];
					newNeighboursCount[newPos++] = 1;
				}
			while (nbsPos < this.numNeighbours) {
				newNeighbours[newPos] = this.neighbours[nbsPos];
				newNeighboursCount[newPos++] = this.neighboursCount[nbsPos++];
			}
			this.neighbours = newNeighbours;
			this.neighboursCount = newNeighboursCount;
			this.numNeighbours = newPos;
		}

		/**
		 * Removes neighbours from VariableToEliminate (adjusts neighbourCount, neighbours and neigbourNum).
		 * 
		 * @param variables to be removed.
		 */
		void removeNeighbours(Variable[] variables) {
			int vPos = 0;
			int nbsPos = 0;
			int newPos = 0;
			while (vPos < variables.length) {
				if (variables[vPos].equals(this.var)) // Skip Variable itself
					vPos++;
				else if (variables[vPos].equals(this.neighbours[nbsPos])) { // Neighbour
					if (this.neighboursCount[nbsPos] == 1) { // Variable is no longer a neighbour
						vPos++;
						nbsPos++;
					} else { // Variable is still a neighbour
						this.neighboursCount[newPos] = this.neighboursCount[nbsPos++] - 1;
						this.neighbours[newPos++] = variables[vPos++];
					}
				} else {
					// (variables[vPos].compareTo(this.neighbours[nbsPos]) > 0)
					this.neighboursCount[newPos] = this.neighboursCount[nbsPos];
					this.neighbours[newPos++] = this.neighbours[nbsPos++];
				}
			}
			// Copy remaining neighbours
			while (nbsPos < this.numNeighbours) {
				this.neighboursCount[newPos] = this.neighboursCount[nbsPos];
				this.neighbours[newPos++] = this.neighbours[nbsPos++];
			}
			this.numNeighbours = newPos;
		}

		/**
		 * Computes "min-factor" (="min-weight") heuristic.
		 * 
		 * @return the size of the resulting factor after this Variable has been eliminated.
		 */
		protected long recomputeMinFactor() {
			long heuristicValue = 1;
			for (int i = 0; i < this.numNeighbours; i++)
				heuristicValue *= this.neighbours[i].getDomainSize();
			return heuristicValue;
		}

		/**
		 * 
		 */
		abstract protected void setMinFactor();

		/**
		 * Recomputing min-degree (=min-size) heuristic is unnecessary, it is equal to:
		 * <p>
		 * this.numNeighbours - number of Variables in the resulting factor after this Variable has been eliminated.
		 */

		/**
		 * 
		 */
		abstract protected void setMinDegree();

		/**
		 * Recomputes min-fill" (="min-deficiency", "min-discrepancy") heuristic.
		 * 
		 * @return number of edges to be added after this Variable has been eliminated.
		 */
		protected long recomputeMinFill() {
			long heuristicValue = 0;
			// Process each neighbour
			for (int i = 0; i < (this.numNeighbours - 1); i++) {
				boolean[] neighboursAdj = new boolean[this.numNeighbours - (i + 1)]; // Adjacency vector
				// Process all Factors on current neighbour
				Iterator<Factor> factorsIterator = FactorStoreIndexed.this.factorIndex.get(this.neighbours[i]).iterator();
				while (factorsIterator.hasNext()) {
					Factor factor = factorsIterator.next();
					// Set indexes
					int nbsAdjPos = 0;
					int nbsPos = i + 1;
					int fctPos = 0;
					// Find the current neighbour
					while (factor.variables[fctPos].compareTo(this.neighbours[i]) < 0)
						fctPos++;
					fctPos++;
					// if ((fctPos < factor.variables().length) && (factor.variables()[fctPos].equals(this.neighbours[i]))) {
					// fctPos++;
					// Find connections to other neigbours using merging-like scheme
					while ((fctPos < factor.variables.length) && (nbsPos < this.numNeighbours)) {
						if (factor.variables[fctPos].equals(this.neighbours[nbsPos])) {
							neighboursAdj[nbsAdjPos++] = true;
							fctPos++;
							nbsPos++;
						} else if (factor.variables[fctPos].compareTo(this.neighbours[nbsPos]) < 0)
							fctPos++;
						else { // (fl.factor.variables()[fctPos].compareTo(this.neighbours[nbsPos]) > 0)
							nbsPos++;
							nbsAdjPos++;
						}
					}
					// }
				}
				// Update heuristic
				for (int j = 0; j < neighboursAdj.length; j++)
					if (!(neighboursAdj[j]))
						heuristicValue++;
			}
			return heuristicValue;
		}

		/**
		 * 
		 */
		abstract protected void setMinFill();

		/**
		 * Recomputes "max-cardinality" heuristic.
		 * 
		 * @return (0 - number of eliminated neighbours).
		 */
		protected long recomputeMaxCardinality() {
			return this.maxCardinality--;
		}

		/**
		 * 
		 */
		 abstract protected void setMaxCardinality();}
		
		/**
		 * @see java.lang.Object#toString()
		 */
		public String toString() {
			StringBuffer buffer = new StringBuffer(this.var + " N[");
			for (int i = 0; i < this.numNeighbours; i++)
				buffer.append(this.neighbours[i] + "-" + this.neighboursCount[i] + " ");
			buffer.append("] F(" + this.numFactors + ") H(" + this.heuristicValue + ")");
			return buffer.toString();
		}
	}

	/**
	 * Adds Factor to the index.
	 * 
	 * @param factor to be added to the index.
	 */
	private void add(Factor factor) {
		boolean noVariablesToEliminate = true;
		for (int i = 0; i < factor.variables.length; i++) {
			HashSet<Factor> variableFactorsIndex = this.factorIndex.get(factor.variables[i]);
			variableFactorsIndex.add(factor);
			VariableToEliminate<T> vte = FactorStoreIndexed.this.varToVarInQuery.get(factor.variables[i]);
			if (vte != null) {
				noVariablesToEliminate = false;
				vte.factors = variableFactorsIndex;
				// Update neighbours count (and neighbours list)
				vte.addNeighbours(factor.variables);
			}
		}
		if (noVariablesToEliminate)
			// Add to final Factors
			FactorStoreIndexed.this.finalFacs[FactorStoreIndexed.this.numFinalFacs++] = factor;
	}
}
Comment 1 Olivier Thomann CLA 2006-08-23 09:25:41 EDT
David,

Seems to be a bug from the recovery.
Comment 2 David Audel CLA 2006-10-24 05:02:11 EDT
Smaller test case:

//-----------------------------------------//
public class X {
	void foo1() {
		{
		}
		class Y  {
		}
	void foo2() {
	}
	class Z<T> {
		
	}
}
}
//-----------------------------------------//
Comment 3 David Audel CLA 2006-10-25 03:36:13 EDT
Created attachment 52647 [details]
Proposed fix
Comment 4 David Audel CLA 2006-10-25 03:40:55 EDT
Released for 3.3 M3.

Tests added
  ComplianceDiagnoseTest#test0052()
  DietRecoveryTest#test117()
Comment 5 Olivier Thomann CLA 2006-10-30 15:00:30 EST
Formatting the code doesn't work, but it doesn't crash.
But editing is doesn't fail anymore.

Verified for 3.3 M3 using warm-up build I20061030-0800