/*
* Copyright 2007-2010 Lawrence Beadle & Tom Castle
* Licensed under GNU General Public License
*
* This file is part of Epoch X - (The Genetic Programming Analysis Software)
*
* Epoch X 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 3 of the License, or
* (at your option) any later version.
*
* Epoch X 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.
*
* You should have received a copy of the GNU General Public License
* along with Epoch X. If not, see <http://www.gnu.org/licenses/>.
*/
package org.epochx.semantics;
import java.util.ArrayList;
import java.util.List;
import org.epochx.epox.Node;
import org.epochx.gp.model.GPModel;
import org.epochx.gp.representation.GPCandidateProgram;
/**
*
*/
public abstract class GPSemanticModel extends GPModel {
private boolean doStateCheckedCrossover;
private boolean doStateCheckedMutation;
private SemanticModule semanticModule;
public GPSemanticModel() {
doStateCheckedCrossover = false;
doStateCheckedMutation = false;
semanticModule = null;
}
public List<Node> getTerminals() {
List<Node> fullSyntax = super.getSyntax();
List<Node> terminals = new ArrayList<Node>();
for(Node test: fullSyntax) {
if(test.getArity()==0) {
terminals.add(test);
}
}
return terminals;
}
public List<Node> getFunctions() {
List<Node> fullSyntax = super.getSyntax();
List<Node> terminals = new ArrayList<Node>();
for(Node test: fullSyntax) {
if(test.getArity()!=0) {
terminals.add(test);
}
}
return terminals;
}
/**
* Returns whether to run the crossover state checker
* @return TRUE if the crossover state checker should be run
*/
public boolean getStateCheckedCrossover() {
return doStateCheckedCrossover;
}
/**
* Sets whether to run the crossover state checker
* @param runStateCheck TRUE if the crossover state checker should be run
*/
public void setStateCheckedCrossover(boolean doStateCheckedCrossover) {
this.doStateCheckedCrossover = doStateCheckedCrossover;
}
public boolean getStateCheckedMutation() {
return doStateCheckedMutation;
}
public void setStateCheckedMutation(boolean doStateCheckedMutation) {
this.doStateCheckedMutation = doStateCheckedMutation;
}
/**
* Returns the semantic module associated with this problem
* @return The associate Semantic module
*/
public SemanticModule getSemanticModule() {
return this.semanticModule;
}
/**
* Sets the semantic module for this run
* @param semMod The desired semantic module to use
*/
public void setSemanticModule(SemanticModule semMod) {
this.semanticModule = semMod;
}
/**
* Performs semantic equivalence check to determine whether the crossover
* should be accepted or not.
*/
public boolean acceptCrossover(GPCandidateProgram[] parents,
GPCandidateProgram[] children) {
boolean equal = false;
if (doStateCheckedCrossover) {
// pull out semantic module and check its not null
SemanticModule semMod = getSemanticModule();
if(semMod==null) {
throw new IllegalArgumentException("Semantic module undefined for semantically driven crossover.");
}
//start semantic module
// TODO find a better way of doing this
if(semMod instanceof BooleanSemanticModule) {
((BooleanSemanticModule) semMod).start();
}
// check behaviours
Representation p1Rep = semMod.codeToBehaviour(parents[0]);
Representation p2Rep = semMod.codeToBehaviour(parents[1]);
Representation c1Rep = semMod.codeToBehaviour(children[0]);
Representation c2Rep = semMod.codeToBehaviour(children[1]);
if(c1Rep.equals(p1Rep) || c1Rep.equals(p2Rep)) {
equal = true;
}
if(c2Rep.equals(p1Rep) || c2Rep.equals(p2Rep)) {
equal = true;
}
// stop semantic module
// TODO find a better way of doing this
if(semMod instanceof BooleanSemanticModule) {
((BooleanSemanticModule) semMod).stop();
}
}
return !equal;
}
/**
* Performs semantic equivalence check to determine whether the mutation
* should be accepted or not.
*/
public boolean acceptMutation(GPCandidateProgram parent,
GPCandidateProgram child) {
boolean equal = false;
if (doStateCheckedMutation) {
// pull out semantic module and check its not null
SemanticModule semMod = getSemanticModule();
if(semMod==null) {
throw new IllegalArgumentException("Semantic module undefine for semantically driven mutation.");
}
//start semantic module
// TODO find a better way of doing this
if(semMod instanceof BooleanSemanticModule) {
((BooleanSemanticModule) semMod).start();
}
// check behaviours
Representation p1Rep = semMod.codeToBehaviour(parent);
Representation c1Rep = semMod.codeToBehaviour(child);
if(c1Rep.equals(p1Rep)) {
equal = true;
}
// stop semantic module
// TODO find a better way of doing this
if(semMod instanceof BooleanSemanticModule) {
((BooleanSemanticModule) semMod).stop();
}
}
return !equal;
}
}