From 220c8e529c986c062dcd188ce1dff1121e04bff5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Euzenat?= <Jerome.Euzenat@inria.fr>
Date: Thu, 22 Aug 2024 10:14:20 +0200
Subject: [PATCH] Added ClassIterator to Classification

---
 .../inria/moex/classapp/Classification.java   | 102 +++++++++++++++---
 1 file changed, 88 insertions(+), 14 deletions(-)

diff --git a/src/fr/inria/moex/classapp/Classification.java b/src/fr/inria/moex/classapp/Classification.java
index 4d53a36..4b767f2 100644
--- a/src/fr/inria/moex/classapp/Classification.java
+++ b/src/fr/inria/moex/classapp/Classification.java
@@ -45,12 +45,13 @@ import java.util.Random;
 
 import java.lang.ProcessBuilder;
 import java.lang.Process;
+import java.lang.Iterable;
 
 import java.util.BitSet; // Used for classification guess mask!
 import java.util.Vector;
 import java.util.Arrays;
-import java.util.Hashtable;
 import java.util.Enumeration;
+import java.util.Iterator;
 
 import java.io.PrintStream;
 import java.io.BufferedOutputStream;
@@ -64,7 +65,7 @@ import org.slf4j.LoggerFactory;
  * Structure of the Classication board
  */
 
-public class Classification {
+public class Classification implements Iterable<Classification> {
 	final static Logger logger = LoggerFactory.getLogger( Classification.class );
 
 	static int NBFEATURES = Feature.NBFEATURES;
@@ -79,6 +80,9 @@ public class Classification {
 	// The feature on which this node is split
 	public Feature feature = null;
 
+	// JE: pattern should be set for all classes...
+	public int[] pattern;
+
 	// The bitset corresponding to the class (or cards belonging there?)
 	// This is actually the ClassPattern of the class... is it?
 	// May be a CardSet... or not... but should be...
@@ -89,9 +93,12 @@ public class Classification {
 
 	static Random generator = new Random();
 
+	// JE2024: Empty top class
 	public Classification() {
+		//		pattern = new int[] = {-1, -1, -1, -1};
 	}
 
+	// JE2024: Empty top class divided by features
 	public Classification ( Feature f ) {
 		feature = f;
 		if ( f != null ) {
@@ -99,6 +106,7 @@ public class Classification {
 		}
 	}
 
+	// JE2024: Taken can be replaced by pattern
 	public Classification( int level, int forks, boolean[] taken, boolean exact ) {
 		if ( forks != 0) {
 			// draw spliting feature
@@ -150,6 +158,26 @@ public class Classification {
 		return new Classification( levels, nbforks, new boolean[NBFEATURES], exact );
 	}
 
+	public boolean eqClass( Classification cl ) throws Exception {
+		if ( this == cl ) return true;
+		// I must find the meaning of the classification:
+		// could use cards, but must be filled
+		for( int i = 0; i < NBFEATURES; i++ ) {
+			if ( this.pattern[i] != cl.pattern[i] ) return false;
+		}
+		return true;
+	}
+
+	// JE2024: Taken can be replaced by pattern
+	public int[] classPattern( int color, int shape, int filling, int number ) {
+		pattern = new int[4];
+		pattern[0] = color;
+		pattern[1] = shape;
+		pattern[2] = filling;
+		pattern[3] = number;
+		return pattern;
+	}
+	
 	/**
 	 * Make leave traversing an iterator!!
 	 */
@@ -159,6 +187,8 @@ public class Classification {
 	 */
 	private void fillLeaves() { fillLeaves( -1, -1, -1, -1 ); }
 	private void fillLeaves( int color, int shape, int filling, int number ) {
+		// JE2024: fill patterns
+		pattern = classPattern( color, shape, filling, number);
 		if ( subTree == null ) {
 			cards = new CardSet(); 
 			// Fill it
@@ -205,17 +235,6 @@ public class Classification {
 
 	public CardSet getClass( int number, int filling, int shape, int color ) {
 		return getClassification( number, filling, shape, color ).cards;
-		/*if ( feature == null ) {
-			return cards;
-		} else {
-			switch ( feature ) {
-			case COLOR: return subTree[color].getClass( number, filling, shape, color );
-			case SHAPE: return subTree[shape].getClass( number, filling, shape, color );
-			case FILLING: return subTree[filling].getClass( number, filling, shape, color );
-			case NUMBER: return subTree[number].getClass( number, filling, shape, color );
-			default: return null; // or  throws Exception? (should never happen)
-			}
-			}*/
 	}
 
 	public Classification getClassification( int number, int filling, int shape, int color ) {
@@ -689,15 +708,70 @@ public class Classification {
 			}
 		}
 	}
+
+    public Iterator<Classification> iterator() {
+        return new ClassIterator( this );
+    }
+
+}
+
+class ClassIterator implements Iterator<Classification> {
+
+	// Classification piles
+    private Classification classif;
+
+	static int NBFEATURES = Feature.NBFEATURES;
+	static int NBVALUES = Card.NBVALUES;
+	
+	// We need to record the pile of super classes and where we are
+	private Classification[] prevClasses;
+	private int[] prevRank;
+	private int current;
+
+	ClassIterator( Classification cl ){
+		classif = cl;
+		prevClasses = new Classification[NBFEATURES];
+		prevRank = new int[NBFEATURES];
+		int current = -1;
+    }
+    public boolean hasNext(){
+		return ( classif != null );
+    }
+    public Classification next() {
+		Classification result = classif;
+		// compute the next one
+		if ( classif.subTree != null ) { // or feature: PUSH
+			current++;
+			prevClasses[current] = classif;
+			prevRank[current] = 0;
+			classif = prevClasses[current].subTree[prevRank[current]];
+		} else { // we are in a leave: POP
+			while ( current != -1 && prevRank[current] == NBVALUES-1 ) current--;
+			//System.err.println( "C: "+current+"prevRank[current] : "+prevRank[current] );
+			if ( prevRank[current] != NBVALUES-1 && prevClasses[current] != null ) { // NEXT
+				prevRank[current] = prevRank[current] + 1;
+				classif = prevClasses[current].subTree[prevRank[current]];
+			} else {
+				classif = null;
+			}
+		}
+		// return the other
+		return result;
+    }
 }
 
+
 /**
  * TODO
  * the idea is that it returns classifications which are leaves...
  * We are not far!
  **/
+/**
+ * TODO
+ * We want also iterate on all classes...
+ **/
 /*
-class LeaveIterator implements Iterator<Classificationn> {
+class LeaveIterator implements Iterator<Classification> {
 	
     //private int currentIndex = 0;
     private Classification classif;
-- 
GitLab