using System.Collections.Generic; namespace HeuristicLab.Problems.ProgramSynthesis { using System; using System.Linq; using HeuristicLab.Common; using HeuristicLab.Core; using HeuristicLab.Data; using HeuristicLab.Optimization; using HeuristicLab.Parameters; using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; using HeuristicLab.PluginInfrastructure; [Item("PlushEncoding", "Describes an linear push (Plush) encoding.")] [StorableClass] public class PlushEncoding : Encoding { public PlushEncoding() : this("Plush") { } public PlushEncoding(string name) : base(name) { InitParameters(); SolutionCreator = new PlushCreator(); RegisterParameterEvents(); DiscoverOperators(); } [StorableConstructor] public PlushEncoding(bool deserializing) : base(deserializing) { } public PlushEncoding(PlushEncoding original, Cloner cloner) : base(original, cloner) { minLengthParameter = cloner.Clone(original.minLengthParameter); maxLengthParameter = cloner.Clone(original.maxLengthParameter); maxCloseParameter = cloner.Clone(original.maxCloseParameter); closeBiasLevelParameter = cloner.Clone(original.closeBiasLevelParameter); instructionsParameter = cloner.Clone(original.instructionsParameter); ercOptionsParameter = cloner.Clone(original.ercOptionsParameter); inInstructionProbabilityParameter = cloner.Clone(original.inInstructionProbabilityParameter); RegisterParameterEvents(); } [StorableHook(HookType.AfterDeserialization)] private void AfterDeserialization() { InitParameters(); RegisterParameterEvents(); DiscoverOperators(); } public override IDeepCloneable Clone(Cloner cloner) { return new PlushEncoding(this, cloner); } private void InitParameters() { if (!Parameters.ContainsKey(Name + ".MinLength")) { minLengthParameter = new FixedValueParameter(Name + ".MinLength", new IntValue(0)); Parameters.Add(minLengthParameter); } if (!Parameters.ContainsKey(Name + ".MaxLength")) { maxLengthParameter = new FixedValueParameter(Name + ".MaxLength", new IntValue(100)); Parameters.Add(maxLengthParameter); } if (!Parameters.ContainsKey(Name + ".MaxClose")) { maxCloseParameter = new FixedValueParameter(Name + ".MaxClose", new IntValue(3)); Parameters.Add(maxCloseParameter); } if (!Parameters.ContainsKey(Name + ".CloseBiasLevel")) { closeBiasLevelParameter = new FixedValueParameter(Name + ".CloseBiasLevel", new DoubleValue(3d)); Parameters.Add(closeBiasLevelParameter); } if (!Parameters.ContainsKey(Name + ".Instructions")) { instructionsParameter = new ValueParameter(Name + ".Instructions"); Parameters.Add(instructionsParameter); } if (!Parameters.ContainsKey(Name + ".ErcOptions")) { ercOptionsParameter = new ValueParameter(Name + ".ErcOptions"); Parameters.Add(ercOptionsParameter); } if (!Parameters.ContainsKey(Name + ".InInstructionProbability")) { inInstructionProbabilityParameter = new FixedValueParameter(Name + ".InInstructionProbability", new PercentValue(0.1)); Parameters.Add(inInstructionProbabilityParameter); } } #region events private void OnMinLengthParameterChanged() { RegisterMinLengthParameterEvents(); ConfigureOperators(Operators); } private void OnMaxLengthParameterChanged() { RegisterMaxLengthParameterEvents(); ConfigureOperators(Operators); } private void OnMaxCloseParameterChanged() { RegisterMaxCloseParameterEvents(); ConfigureOperators(Operators); } private void OnCloseBiasLevelParameterChanged() { RegisterCloseBiasLevelParameterEvents(); ConfigureOperators(Operators); } private void OnErcOptionsParameterChanged() { RegisterErcOptionsParameterEvents(); ConfigureOperators(Operators); } private void OnInstructionsParameterChanged() { RegisterInstructionsParameterEvents(); ConfigureOperators(Operators); } private void OnInInstructionProbabilityParameterChanged() { RegisterInInstructionProbabilityParameterEvents(); ConfigureOperators(Operators); } private void RegisterParameterEvents() { RegisterMinLengthParameterEvents(); RegisterMaxLengthParameterEvents(); RegisterMaxCloseParameterEvents(); RegisterCloseBiasLevelParameterEvents(); RegisterErcOptionsParameterEvents(); RegisterInstructionsParameterEvents(); RegisterInInstructionProbabilityParameterEvents(); } private void RegisterMinLengthParameterEvents() { MinLengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); MinLengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterMaxLengthParameterEvents() { MaxLengthParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); MaxLengthParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterMaxCloseParameterEvents() { MaxCloseParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); MaxCloseParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterCloseBiasLevelParameterEvents() { CloseBiasLevelParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); CloseBiasLevelParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterInInstructionProbabilityParameterEvents() { InInstructionProbabilityParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); InInstructionProbabilityParameter.Value.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterErcOptionsParameterEvents() { ErcOptionsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); } private void RegisterInstructionsParameterEvents() { InstructionsParameter.ValueChanged += (o, s) => ConfigureOperators(Operators); } #endregion #region Encoding Parameters [Storable] private IValueParameter minLengthParameter; public IValueParameter MinLengthParameter { get { return minLengthParameter; } set { if (value == null) throw new ArgumentNullException("Min length parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("Min length parameter value must not be null."); if (minLengthParameter == value) return; if (minLengthParameter != null) Parameters.Remove(minLengthParameter); minLengthParameter = value; Parameters.Add(minLengthParameter); OnMinLengthParameterChanged(); } } [Storable] private IValueParameter maxLengthParameter; public IValueParameter MaxLengthParameter { get { return maxLengthParameter; } set { if (value == null) throw new ArgumentNullException("Max length parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("Max length parameter value must not be null."); if (maxLengthParameter == value) return; if (maxLengthParameter != null) Parameters.Remove(maxLengthParameter); maxLengthParameter = value; Parameters.Add(maxLengthParameter); OnMaxLengthParameterChanged(); } } [Storable] private IValueParameter maxCloseParameter; public IValueParameter MaxCloseParameter { get { return maxCloseParameter; } set { if (value == null) throw new ArgumentNullException("Max close parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("Max close parameter value must not be null."); if (maxCloseParameter == value) return; if (maxCloseParameter != null) Parameters.Remove(maxCloseParameter); maxCloseParameter = value; Parameters.Add(maxCloseParameter); OnMaxCloseParameterChanged(); } } [Storable] private IValueParameter closeBiasLevelParameter; public IValueParameter CloseBiasLevelParameter { get { return closeBiasLevelParameter; } set { if (value == null) throw new ArgumentNullException("Close bias level parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("Close bias level parameter value must not be null."); if (closeBiasLevelParameter == value) return; if (closeBiasLevelParameter != null) Parameters.Remove(closeBiasLevelParameter); closeBiasLevelParameter = value; Parameters.Add(closeBiasLevelParameter); OnCloseBiasLevelParameterChanged(); } } [Storable] private IValueParameter inInstructionProbabilityParameter; public IValueParameter InInstructionProbabilityParameter { get { return inInstructionProbabilityParameter; } set { if (value == null) throw new ArgumentNullException("In instruciton probability parameter must not be null."); if (value.Value == null) throw new ArgumentNullException("In instruciton probability parameter value must not be null."); if (inInstructionProbabilityParameter == value) return; if (inInstructionProbabilityParameter != null) Parameters.Remove(inInstructionProbabilityParameter); inInstructionProbabilityParameter = value; Parameters.Add(inInstructionProbabilityParameter); OnInInstructionProbabilityParameterChanged(); } } [Storable] private IValueParameter instructionsParameter; public IValueParameter InstructionsParameter { get { return instructionsParameter; } set { if (value == null) throw new ArgumentNullException("Instructions paramter must not be null"); if (instructionsParameter == value) return; if (instructionsParameter != null) Parameters.Remove(instructionsParameter); instructionsParameter = value; Parameters.Add(instructionsParameter); OnInstructionsParameterChanged(); } } [Storable] private IValueParameter ercOptionsParameter; public IValueParameter ErcOptionsParameter { get { return ercOptionsParameter; } set { if (value == null) throw new ArgumentNullException("ErcOptions paramter must not be null"); if (ercOptionsParameter == value) return; if (ercOptionsParameter != null) Parameters.Remove(ercOptionsParameter); ercOptionsParameter = value; Parameters.Add(ercOptionsParameter); OnErcOptionsParameterChanged(); } } public IExpressionsConfiguration Instructions { get { return InstructionsParameter.Value; } set { InstructionsParameter.Value = value; } } public ErcOptions ErcOptions { get { return ErcOptionsParameter.Value; } set { ErcOptionsParameter.Value = value; } } public int MinLength { get { return MinLengthParameter.Value.Value; } set { MinLengthParameter.Value.Value = value; } } public int MaxLength { get { return MaxLengthParameter.Value.Value; } set { MaxLengthParameter.Value.Value = value; } } public int MaxClose { get { return MaxCloseParameter.Value.Value; } set { MaxCloseParameter.Value.Value = value; } } public double InInstructionProbability { get { return InInstructionProbabilityParameter.Value.Value; } set { InInstructionProbabilityParameter.Value.Value = value; } } #endregion #region Operator Discovery private static readonly IEnumerable EncodingSpecificOperatorTypes; static PlushEncoding() { EncodingSpecificOperatorTypes = new List() { typeof (IPlushOperator), typeof (IPlushCreator), typeof (IPlushCrossover), typeof (IPlushManipulator), }; } private void DiscoverOperators() { var assembly = typeof(IPlushOperator).Assembly; var discoveredTypes = ApplicationManager.Manager.GetTypes(EncodingSpecificOperatorTypes, assembly, true, false, false); var operators = discoveredTypes.Select(t => (IOperator)Activator.CreateInstance(t)); var newOperators = operators.Except(Operators, new TypeEqualityComparer()).ToList(); ConfigureOperators(newOperators); foreach (var @operator in newOperators) AddOperator(@operator); } #endregion public override void ConfigureOperators(IEnumerable operators) { ConfigureCreators(operators.OfType()); ConfigureCrossovers(operators.OfType()); ConfigureManipulators(operators.OfType()); } private void ConfigureCreators(IEnumerable creators) { foreach (var creator in creators) { creator.PlushVectorParameter.ActualName = Name; creator.MinLengthParameter.ActualName = MinLengthParameter.Name; creator.MaxLengthParameter.ActualName = MaxLengthParameter.Name; creator.MaxCloseParameter.ActualName = MaxCloseParameter.Name; creator.CloseBiasLevelParameter.ActualName = CloseBiasLevelParameter.Name; creator.ErcOptionsParameter.ActualName = ErcOptionsParameter.Name; creator.InstructionsParameter.ActualName = InstructionsParameter.Name; creator.InInstructionProbabilityParameter.ActualName = InInstructionProbabilityParameter.Name; } } private void ConfigureCrossovers(IEnumerable crossovers) { foreach (var crossover in crossovers) { crossover.ChildParameter.ActualName = Name; crossover.ParentsParameter.ActualName = Name; } } private void ConfigureManipulators(IEnumerable manipulators) { foreach (var manipulator in manipulators) { manipulator.PlushVectorParameter.ActualName = Name; manipulator.PlushVectorParameter.Hidden = true; manipulator.ErcOptionsParameter.ActualName = ErcOptionsParameter.Name; manipulator.InstructionsParameter.ActualName = InstructionsParameter.Name; manipulator.InInstructionProbabilityParameter.ActualName = InInstructionProbabilityParameter.Name; } } } public static class IndividualExtensionMethods { public static PlushVector PlushVector(this Individual individual) { var encoding = individual.GetEncoding(); return individual.PlushVector(encoding.Name); } public static PlushVector PlushVector(this Individual individual, string name) { return (PlushVector)individual[name]; } } }