//package hu.birot.OTKit.runableExamples;

import hu.birot.OTKit.dataType.*;
import hu.birot.OTKit.otBuildingBlocks.*;
import hu.birot.OTKit.performance.*;

import java.util.HashMap;
import java.util.Vector;

/**
 * <p>This examples creates a candidate set with three candidates (A, B and C) and two constraints:
 * noB and noC. The tableau looks as:</p> 
 * 
 * <center>
 * <table border="2">
 * <tr><td>&nbsp;</td><td>noB</td><td>noC</td></tr>
 * <tr><td>A</td><td>0</td><td>0</td></tr>
 * <tr><td>B</td><td>1</td><td>0</td></tr>
 * <tr><td>C</td><td>0</td><td>1</td></tr>
 * </table>
 * </center>
 * 
 * <p>The topology is as follows: Candidate B has two neighbors, both A and C. But candidates A
 * and C are not neighbors of each other, their sole neighbor is B. Consequently, A is globally
 * optimal, while C is (another) local optimum.<p>
 * 
 * <p>Given this tableau and topology, SA-OT will return both A and C in 50% of the cases,
 * independently of the cooling schedule. Yet, simulated annealing with Harmonic Grammar
 * will prefer the global optimum A; the frequency of returning C will diminish, as the cooling
 * schedule becomes slower.</p>
 * 
 * <p>The code of this class demonstrates how to encode a Gen, a topology, constraints and 
 * hierarchies, and how to run experiments with them subsequently.</p>
 *  
 * @author <a href="http://www.birot.hu">Tamas Biro</a>
 */

public class Delta_shape {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		
		//-------------
		// candidates and topology:
		
		Candidate a = new Candidate("A"){
			public String toString() {return "Candidate A";}
		};
		Candidate b = new Candidate("B"){
			public String toString() {return "Candidate B";}
		};
		Candidate c = new Candidate("C"){
			public String toString() {return "Candidate C";}
		};

		// Either:
		String[]    candidate_strings = {"A", "B", "C"};		
		Gen gen = GenExamples.listOfSurfaceForms(candidate_strings);
		
		// Or:
		Form[] candidates = {a.sf, b.sf, c.sf};
		    gen  = GenExamples.listOfSurfaceForms(candidates);
		
		HashMap<Form,FormValuePair[]> hm = new HashMap<Form,FormValuePair[]>();
		FormValuePair[] step1 = {new FormValuePair(b.sf,1)};	
		hm.put(a.sf, step1);
		FormValuePair[] step2 = {new FormValuePair(a.sf,1), new FormValuePair(c.sf,1)};	
		hm.put(b.sf, step2);
		FormValuePair[] step3 = {new FormValuePair(b.sf,1)};	
		hm.put(c.sf, step3);

		Topology candidateset = new Topology(MapFormExamples.equals(hm));
	
		//-------------
		System.out.println("Neighbourhood:");
		Vector<Candidate> all = gen.allCandidates(new Form());
		Vector<Candidate> neig = new Vector<Candidate>();
		for (Candidate x : all){
			System.out.print(x+":");
			neig = candidateset.allNeighborsOf(x);
			for (Candidate y : neig) {
				System.out.print(y+" ");
			}
			System.out.println("");
		}

		//-------------
		// constraints:
		Constraint c1 = ConstraintExamples.equal("noB", "B", 1);
		Constraint c2 = ConstraintExamples.equal("noC", "C", 1); 
		
		//-------------
		// hierarchy:
		Hierarchy h = new Hierarchy();
		h.type="OT";
		h.addConstraintWithKvalue(c1, 2);
		h.addConstraintWithKvalue(c2, 1);
		h.kvalue2rank();

		//-------------
		// print out tableau:
		System.out.println();
		System.out.println("Tableau:");
		System.out.println("    " + c1.name() + " | " + c2.name());
		System.out.println(a.sf.string() + " : " +
				c1.value(a).value()+ " | " +
				c2.value(a).value()+ " ");
		System.out.println(b.sf.string() + " : " +
				c1.value(b).value()+ " | " +
				c2.value(b).value()+ " ");
		System.out.println(c.sf.string() + " : " +
				c1.value(c).value()+ " | " +
				c2.value(c).value()+ " ");		

		//-------------
		// run experiment:
		System.out.println();
		System.out.println("Random walk:");
		
		for (int i = 0; i < 100; i++) {
			Temperature t = RandomWalks.randomWalk(b, 
					candidateset, 
					h, 
					RulesOfMovingExamples.simulatedAnnealing(), 
					CoolingScheduleExamples.saot(5, -2, 1, 3, 0, 0.1)
					);
			System.out.println("Run nr. "+i+" from "+b.sf.string()+
					" has returned output "+t.output.sf.string()+
					" while performaning "+t.iterations+" iterations.");
		}
		
	}		 
}

