<commit_before>/*
   Copyright 2006 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/


package org.gavrog.joss.dsyms.generators;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import org.gavrog.box.collections.IteratorAdapter;
import org.gavrog.box.collections.Iterators;
import org.gavrog.box.simple.Stopwatch;
import org.gavrog.jane.numbers.Fraction;
import org.gavrog.jane.numbers.Rational;
import org.gavrog.joss.dsyms.basic.DSymbol;
import org.gavrog.joss.dsyms.basic.DynamicDSymbol;
import org.gavrog.joss.dsyms.basic.IndexList;
import org.gavrog.joss.dsyms.derived.EuclidicityTester;

/**
 * @author <NAME>
 * @version $Id: FaceTransitive.java,v 1.22 2006/12/07 23:34:24 odf Exp $
 */
public class FaceTransitive extends IteratorAdapter {

    /**
     * Generates all feasible 1-dimensional symbols of a given size.
     */
    public static class Faces extends IteratorAdapter {
		final private int minVert;
        final Iterator sets;
        int v;
        DynamicDSymbol currentSet = null;
        
        public Faces(final int size, int minVert) {
        	this.minVert = minVert;
            if (size % 2 == 1) {
                final DynamicDSymbol ds = new DynamicDSymbol(1);
                final List elms = ds.grow(size);
                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(0, elms.get(i-1), elms.get(i));
                    ds.redefineOp(1, elms.get(i), elms.get(i+1));
                }
                ds.redefineOp(1, elms.get(0), elms.get(0));
                ds.redefineOp(0, elms.get(size-1), elms.get(size-1));
                this.sets = Iterators.singleton(new DSymbol(ds));
            } else {
                final List tmp = new LinkedList();
                final DynamicDSymbol ds = new DynamicDSymbol(1);
                final List elms = ds.grow(size);
                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(0, elms.get(i-1), elms.get(i));
                    ds.redefineOp(1, elms.get(i), elms.get((i+1) % size));
                }
                tmp.add(new DSymbol(ds));

                ds.redefineOp(1, elms.get(0), elms.get(0));
                ds.redefineOp(1, elms.get(size-1), elms.get(size-1));
                tmp.add(new DSymbol(ds));

                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(1, elms.get(i-1), elms.get(i));
                    ds.redefineOp(0, elms.get(i), elms.get((i+1) % size));
                }
                ds.redefineOp(0, elms.get(0), elms.get(0));
                ds.redefineOp(0, elms.get(size-1), elms.get(size-1));
                tmp.add(new DSymbol(ds));

                this.sets = tmp.iterator();
            }
        }
        
        /* (non-Javadoc)
         * @see org.gavrog.box.collections.IteratorAdapter#findNext()
         */
        protected Object findNext() throws NoSuchElementException {
            while (true) {
                if (this.currentSet != null && this.v <= 4) {
                    final DynamicDSymbol ds = this.currentSet;
                    final Object D = ds.elements().next();
                    ds.redefineV(0, 1, D, this.v);
                    ++this.v;
                    if (ds.m(0, 1, D) < 3) {
                    	continue;
                    }
                    if (this.minVert >= 3 && ds.m(0, 1, D) > 5) {
                    	continue;
                    }
                    return new DSymbol(ds);
                } else if (this.sets.hasNext()) {
                    final DSymbol ds = (DSymbol) this.sets.next();
                    this.currentSet = new DynamicDSymbol(ds);
                    this.v = 1;
                } else {
                    throw new NoSuchElementException("at end");
                }
            }
        }
    }

    private class Augmenter extends IteratorAdapter {
        final private DSymbol base;
        final private int targetSize;
        final Object orbRep[];
        final int orbSize[];
        final int orbAdded[];
        int currentSize;

        /**
         * Constructs an instance.
         * @param base
         * @param size
         */
        public Augmenter(final DSymbol base, final int size) {
            // --- store parameters
            this.base = base;
            this.targetSize = size;
            this.currentSize = base.size();
            
            // --- collect (0,2)-orbits
            final List idcs = new IndexList(0, 2);
            final List orbits = new ArrayList();
            for (final Iterator reps = base.orbitRepresentatives(idcs); reps
                    .hasNext();) {
                final Object D = reps.next();
                final List orbit = Iterators.asList(base.orbit(idcs, D));
                orbits.add(orbit);
            }

            // --- sort by decreasing size
            Collections.sort(orbits, new Comparator() {
                public int compare(final Object arg0, final Object arg1) {
                    final List l0 = (List) arg0;
                    final List l1 = (List) arg1;
                    return l1.size() - l0.size();
                }
            });
            
            // --- create arrays
            final int n = orbits.size();
            this.orbRep = new Object[n];
            this.orbSize = new int[n];
            this.orbAdded = new int[n];
            
            // --- fill arrays
            for (int i = 0; i < n; ++i) {
                final List orb = (List) orbits.get(i);
                this.orbRep[i] = orb.get(0);
                this.orbSize[i] = orb.size();
                this.orbAdded[i] = 0;
            }
        }
        
        /* (non-Javadoc)
         * @see org.gavrog.box.collections.IteratorAdapter#findNext()
         */
        protected Object findNext() throws NoSuchElementException {
            // TODO Auto-generated method stub
            return null;
        }
    }
    
    // --- used by SingleFaceTiles
    final static Map bases = new HashMap();

    /**
     * Generates all feasible 2-dimensional symbols extending a given
     * 1-dimensional one. This version works by introducing extra degree 2
     * vertices into tiles with a smaller face in all possible ways. The base
     * tiles for this process are generated by the direct method of {@link
     * #BaseSingleFaceTiles}
     */
    private class SingleFaceTiles extends IteratorAdapter {
        final private int minVert;
        final private int targetSize;
        final private Iterator baseFaces;
        private Iterator baseTiles;
        private Iterator augmented;
        
        public SingleFaceTiles(final DSymbol face, final int minVert) {
            this.minVert = minVert;
            this.targetSize = face.size();
            this.baseFaces = baseFaces(face).iterator();
            this.baseTiles = Iterators.empty();
            this.augmented = Iterators.empty();
        }

        /**
         * Determines the type of 1-dimensional symbol. The type is -1 for a<commit_msg>Continued work on internal class Augmenter.<commit_after>/*
   Copyright 2006 <NAME>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/


package org.gavrog.joss.dsyms.generators;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.NoSuchElementException;

import org.gavrog.box.collections.IteratorAdapter;
import org.gavrog.box.collections.Iterators;
import org.gavrog.box.simple.Stopwatch;
import org.gavrog.jane.numbers.Fraction;
import org.gavrog.jane.numbers.Rational;
import org.gavrog.joss.dsyms.basic.DSymbol;
import org.gavrog.joss.dsyms.basic.DynamicDSymbol;
import org.gavrog.joss.dsyms.basic.IndexList;
import org.gavrog.joss.dsyms.derived.EuclidicityTester;

/**
 * @author <NAME>
 * @version $Id: FaceTransitive.java,v 1.23 2006/12/08 01:01:19 odf Exp $
 */
public class FaceTransitive extends IteratorAdapter {

    /**
     * Generates all feasible 1-dimensional symbols of a given size.
     */
    public static class Faces extends IteratorAdapter {
		final private int minVert;
        final Iterator sets;
        int v;
        DynamicDSymbol currentSet = null;
        
        public Faces(final int size, int minVert) {
        	this.minVert = minVert;
            if (size % 2 == 1) {
                final DynamicDSymbol ds = new DynamicDSymbol(1);
                final List elms = ds.grow(size);
                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(0, elms.get(i-1), elms.get(i));
                    ds.redefineOp(1, elms.get(i), elms.get(i+1));
                }
                ds.redefineOp(1, elms.get(0), elms.get(0));
                ds.redefineOp(0, elms.get(size-1), elms.get(size-1));
                this.sets = Iterators.singleton(new DSymbol(ds));
            } else {
                final List tmp = new LinkedList();
                final DynamicDSymbol ds = new DynamicDSymbol(1);
                final List elms = ds.grow(size);
                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(0, elms.get(i-1), elms.get(i));
                    ds.redefineOp(1, elms.get(i), elms.get((i+1) % size));
                }
                tmp.add(new DSymbol(ds));

                ds.redefineOp(1, elms.get(0), elms.get(0));
                ds.redefineOp(1, elms.get(size-1), elms.get(size-1));
                tmp.add(new DSymbol(ds));

                for (int i = 1; i < size; i += 2) {
                    ds.redefineOp(1, elms.get(i-1), elms.get(i));
                    ds.redefineOp(0, elms.get(i), elms.get((i+1) % size));
                }
                ds.redefineOp(0, elms.get(0), elms.get(0));
                ds.redefineOp(0, elms.get(size-1), elms.get(size-1));
                tmp.add(new DSymbol(ds));

                this.sets = tmp.iterator();
            }
        }
        
        /* (non-Javadoc)
         * @see org.gavrog.box.collections.IteratorAdapter#findNext()
         */
        protected Object findNext() throws NoSuchElementException {
            while (true) {
                if (this.currentSet != null && this.v <= 4) {
                    final DynamicDSymbol ds = this.currentSet;
                    final Object D = ds.elements().next();
                    ds.redefineV(0, 1, D, this.v);
                    ++this.v;
                    if (ds.m(0, 1, D) < 3) {
                    	continue;
                    }
                    if (this.minVert >= 3 && ds.m(0, 1, D) > 5) {
                    	continue;
                    }
                    return new DSymbol(ds);
                } else if (this.sets.hasNext()) {
                    final DSymbol ds = (DSymbol) this.sets.next();
                    this.currentSet = new DynamicDSymbol(ds);
                    this.v = 1;
                } else {
                    throw new NoSuchElementException("at end");
                }
            }
        }
    }

    private class Augmenter extends IteratorAdapter {
        final private DSymbol base;
        final private int targetSize;
        final Object orbRep[];
        final int orbSize[];
        final int orbAdded[];
        int currentSize;

        /**
         * Constructs an instance.
         * @param base
         * @param size
         */
        public Augmenter(final DSymbol base, final int size) {
            // --- store parameters
            this.base = base;
            this.targetSize = size;
            this.currentSize = base.size();
            
            // --- collect (0,2)-orbits
            final List idcs = new IndexList(0, 2);
            final List orbits = new ArrayList();
            for (final Iterator reps = base.orbitRepresentatives(idcs); reps
                    .hasNext();) {
                final Object D = reps.next();
                final List orbit = Iterators.asList(base.orbit(idcs, D));
                orbits.add(orbit);
            }

            // --- sort by decreasing size
            Collections.sort(orbits, new Comparator() {
                public int compare(final Object arg0, final Object arg1) {
                    final List l0 = (List) arg0;
                    final List l1 = (List) arg1;
                    return l1.size() - l0.size();
                }
            });
            
            // --- create arrays
            final int n = orbits.size();
            this.orbRep = new Object[n];
            this.orbSize = new int[n];
            this.orbAdded = new int[n];
            
            // --- fill arrays
            for (int i = 0; i < n; ++i) {
                final List orb = (List) orbits.get(i);
                this.orbRep[i] = orb.get(0);
                this.orbSize[i] = orb.size();
                this.orbAdded[i] = 0;
            }
            
            // --- a little trick to make findNext() code simpler
            if (this.currentSize == this.targetSize) {
                this.orbAdded[n-1] = -this.orbSize[n-1];
                this.currentSize -= this.orbSize[n-1];
            }
        }
        
        /* (non-Javadoc)
         * @see org.gavrog.box.collections.IteratorAdapter#findNext()
         */
        protected Object findNext() throws NoSuchElementException {
            while (true) {
                final int target = this.targetSize;
                int i = this.orbRep.length - 1;
                while (i >= 0 && this.currentSize + this.orbSize[i] > target) {
                    this.currentSize -= this.orbAdded[i];
                    this.orbAdded[i] = 0;
                    --i;
                }
                if (i < 0) {
                    throw new NoSuchElementException("at end");
                }
                this.orbAdded[i] += this.orbSize[i];
                this.currentSize += this.orbSize[i];

                if (this.currentSize == this.targetSize) {
                    return augmented();
                }
            }
        }

        /**
         * @return
         */
        private DSymbol augmented() {
            final DSymbol ds = this.base;
            // TODO augment the tile and return it
            return ds;
        }
    }
    
    // --- used by SingleFaceTiles
    final static Map bases = new HashMap();

    /**
     * Generates all feasible 2-dimensional symbols extending a given
     * 1-dimensional one. This version works by introducing extra degree 2
     * vertices into tiles with a smaller face in all possible ways. The base
     * tiles for this process are generated by the direct method of {@link
     * #BaseSingleFaceTiles}
     */
    private class SingleFaceTiles extends IteratorAdapter {
        final private int minVert;
        final private int targetSize;
        final private Iterator baseFaces;
        private Iterator baseTiles;
        private Iterator augmented;
        
        public SingleFaceTiles(final DSymbol face, final int minVert) {
            this.minVert = minVert;
            this.targetSize = face.size();
            this.baseFaces = baseFaces(face).iterator();
            this.baseTiles = Iterators.empty();
            this.augmented = Iterators.empty();
        }

        /**
         * Determines the type of 1-dimensional symbol. The type is -1 for a
{'fraction_non_alphanumeric': 0.10772833723653395, 'fraction_numerical': 0.012069897315798956, 'mean_word_length': 1.5633369247344928, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1560656', 'n_tokens_mistral': 4933, 'n_tokens_neox': 4661, 'n_words': 1255}