#region License Information
/* HeuristicLab
* Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
*
* This file is part of HeuristicLab.
*
* HeuristicLab 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.
*
* HeuristicLab 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 HeuristicLab. If not, see .
*/
#endregion
using HeuristicLab.Encodings.SymbolicExpressionTreeEncoding;
using System.Collections.Generic;
using System;
using System.Linq;
using HeuristicLab.Core;
namespace HeuristicLab.Problems.ArtificialAnt {
public class ArtificialAntExpressionGrammar : Item, ISymbolicExpressionGrammar {
private class EmptySymbol : Symbol { }
public ArtificialAntExpressionGrammar()
: base() {
}
#region ISymbolicExpressionGrammar Members
private EmptySymbol startSymbol = new EmptySymbol();
public Symbol StartSymbol {
get { return startSymbol; }
}
private static List allSymbols = new List() {
new IfFoodAhead(),
new Prog2(),
new Prog3(),
new Move(),
new Left(),
new Right()
};
private Dictionary>> allowedSymbols = new Dictionary>>() {
{
typeof(EmptySymbol),
new Dictionary>()
{
{ 0, allSymbols},
}
}, {
typeof(IfFoodAhead),
new Dictionary>()
{
{ 0, allSymbols},
{ 1, allSymbols}
}
},
{
typeof(Prog2),
new Dictionary>()
{
{ 0, allSymbols},
{ 1, allSymbols}
}
},
{
typeof(Prog3),
new Dictionary>()
{
{ 0, allSymbols},
{ 1, allSymbols},
{ 2, allSymbols}
}
},
};
public IEnumerable AllowedSymbols(Symbol parent, int argumentIndex) {
return allowedSymbols[parent.GetType()][argumentIndex];
}
private Dictionary minLength = new Dictionary() {
{typeof(EmptySymbol), 1},
{typeof(IfFoodAhead), 3},
{typeof(Prog2), 3},
{typeof(Prog3), 4},
{typeof(Move), 1},
{typeof(Left), 1},
{typeof(Right), 1}
};
public int MinimalExpressionLength(Symbol start) {
return minLength[start.GetType()];
}
private Dictionary maxLength = new Dictionary() {
{typeof(EmptySymbol), int.MaxValue},
{typeof(IfFoodAhead), int.MaxValue},
{typeof(Prog2), int.MaxValue},
{typeof(Prog3), int.MaxValue},
{typeof(Move), 1},
{typeof(Left), 1},
{typeof(Right), 1}
};
public int MaximalExpressionLength(Symbol start) {
return maxLength[start.GetType()];
}
private Dictionary minDepth = new Dictionary() {
{typeof(EmptySymbol), 1},
{typeof(IfFoodAhead), 1},
{typeof(Prog2), 1},
{typeof(Prog3), 1},
{typeof(Move), 0},
{typeof(Left), 0},
{typeof(Right), 0}
};
public int MinimalExpressionDepth(Symbol start) {
return minDepth[start.GetType()];
}
private Dictionary subTrees = new Dictionary() {
{typeof(EmptySymbol), 1},
{typeof(IfFoodAhead), 2},
{typeof(Prog2), 2},
{typeof(Prog3), 3},
{typeof(Move), 0},
{typeof(Left), 0},
{typeof(Right), 0}
};
public int MinSubTrees(Symbol start) {
return subTrees[start.GetType()];
}
public int MaxSubTrees(Symbol start) {
return subTrees[start.GetType()];
}
#endregion
#region ISymbolicExpressionGrammar Members
public bool IsValidExpression(SymbolicExpressionTree expression) {
if (expression.Root.Symbol != StartSymbol) return false;
return IsValidExpression(expression.Root);
}
#endregion
private bool IsValidExpression(SymbolicExpressionTreeNode root) {
if (root.SubTrees.Count < MinSubTrees(root.Symbol)) return false;
if (root.SubTrees.Count > MaxSubTrees(root.Symbol)) return false;
for (int i = 0; i < root.SubTrees.Count; i++) {
if (!AllowedSymbols(root.Symbol, i).Contains(root.SubTrees[i].Symbol)) return false;
if (!IsValidExpression(root.SubTrees[i])) return false;
}
return true;
}
}
}