Free cookie consent management tool by TermsFeed Policy Generator

source: branches/3.1/sources/HeuristicLab.Core/OperatorBase.cs @ 2498

Last change on this file since 2498 was 76, checked in by swagner, 17 years ago

Fixed ticket #68

  • removed aliases again after an operator has been executed
File size: 18.7 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2008 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.Xml;
26
27namespace HeuristicLab.Core {
28  public abstract class OperatorBase : ConstrainedItemBase, IOperator {
29    private string myName;
30    public string Name {
31      get { return myName; }
32      set {
33        if (myName != value) {
34          myName = value;
35          OnNameChanged();
36        }
37      }
38    }
39    public virtual string Description {
40      get { return "No operator description available."; }
41    }
42
43    protected bool myCanceled;
44    public bool Canceled {
45      get { return myCanceled; }
46    }
47    private bool myBreakpoint;
48    public bool Breakpoint {
49      get { return myBreakpoint; }
50      set {
51        if (value != myBreakpoint) {
52          myBreakpoint = value;
53          OnBreakpointChanged();
54        }
55      }
56    }
57
58    private List<IOperator> mySubOperators;
59    public virtual IList<IOperator> SubOperators {
60      get { return mySubOperators.AsReadOnly(); }
61    }
62    private Dictionary<string, IVariableInfo> myVariableInfos;
63    public virtual ICollection<IVariableInfo> VariableInfos {
64      get { return myVariableInfos.Values; }
65    }
66    private Dictionary<string, IVariable> myVariables;
67    public virtual ICollection<IVariable> Variables {
68      get { return myVariables.Values; }
69    }
70
71    protected OperatorBase() {
72      myName = this.GetType().Name;
73      myCanceled = false;
74      myBreakpoint = false;
75      mySubOperators = new List<IOperator>();
76      myVariableInfos = new Dictionary<string, IVariableInfo>();
77      myVariables = new Dictionary<string, IVariable>();
78    }
79
80    public override object Clone(IDictionary<Guid, object> clonedObjects) {
81      OperatorBase clone = (OperatorBase)base.Clone(clonedObjects);
82      clone.myName = Name;
83      clone.mySubOperators.Clear();
84      for (int i = 0; i < SubOperators.Count; i++)
85        clone.AddSubOperator((IOperator)Auxiliary.Clone(SubOperators[i], clonedObjects));
86      clone.myVariableInfos.Clear();
87      foreach (IVariableInfo variableInfo in myVariableInfos.Values)
88        clone.AddVariableInfo((IVariableInfo)Auxiliary.Clone(variableInfo, clonedObjects));
89      clone.myVariables.Clear();
90      foreach (IVariable variable in myVariables.Values)
91        clone.AddVariable((IVariable)Auxiliary.Clone(variable, clonedObjects));
92      return clone;
93    }
94
95    public override IView CreateView() {
96      return new OperatorBaseView(this);
97    }
98
99    #region SubOperator Methods
100    public virtual void AddSubOperator(IOperator subOperator) {
101      mySubOperators.Add(subOperator);
102      OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
103    }
104    public virtual bool TryAddSubOperator(IOperator subOperator) {
105      mySubOperators.Add(subOperator);
106      if (IsValid()) {
107        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
108        return true;
109      } else {
110        mySubOperators.RemoveAt(mySubOperators.Count - 1);
111        return false;
112      }
113    }
114    public virtual bool TryAddSubOperator(IOperator subOperator, out ICollection<IConstraint> violatedConstraints) {
115      mySubOperators.Add(subOperator);
116      if (IsValid(out violatedConstraints)) {
117        OnSubOperatorAdded(subOperator, mySubOperators.Count - 1);
118        return true;
119      } else {
120        mySubOperators.RemoveAt(mySubOperators.Count - 1);
121        return false;
122      }
123    }
124    public virtual void AddSubOperator(IOperator subOperator, int index) {
125      mySubOperators.Insert(index, subOperator);
126      OnSubOperatorAdded(subOperator, index);
127    }
128    public virtual bool TryAddSubOperator(IOperator subOperator, int index) {
129      mySubOperators.Insert(index, subOperator);
130      if (IsValid()) {
131        OnSubOperatorAdded(subOperator, index);
132        return true;
133      } else {
134        mySubOperators.RemoveAt(index);
135        return false;
136      }
137    }
138    public virtual bool TryAddSubOperator(IOperator subOperator, int index, out ICollection<IConstraint> violatedConstraints) {
139      mySubOperators.Insert(index, subOperator);
140      if (IsValid(out violatedConstraints)) {
141        OnSubOperatorAdded(subOperator, index);
142        return true;
143      } else {
144        mySubOperators.RemoveAt(index);
145        return false;
146      }
147    }
148    public virtual void RemoveSubOperator(int index) {
149      IOperator op = mySubOperators[index];
150      mySubOperators.RemoveAt(index);
151      OnSubOperatorRemoved(op, index);
152    }
153    public virtual bool TryRemoveSubOperator(int index) {
154      IOperator op = mySubOperators[index];
155      mySubOperators.RemoveAt(index);
156      if (IsValid()) {
157        OnSubOperatorRemoved(op, index);
158        return true;
159      } else {
160        mySubOperators.Insert(index, op);
161        return false;
162      }
163    }
164    public virtual bool TryRemoveSubOperator(int index, out ICollection<IConstraint> violatedConstraints) {
165      IOperator op = mySubOperators[index];
166      mySubOperators.RemoveAt(index);
167      if (IsValid(out violatedConstraints)) {
168        OnSubOperatorRemoved(op, index);
169        return true;
170      } else {
171        mySubOperators.Insert(index, op);
172        return false;
173      }
174    }
175    #endregion
176
177    #region VariableInfo Methods
178    public virtual IVariableInfo GetVariableInfo(string formalName) {
179      IVariableInfo info;
180      if (myVariableInfos.TryGetValue(formalName, out info))
181        return info;
182      else
183        return null;
184    }
185    public virtual void AddVariableInfo(IVariableInfo variableInfo) {
186      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
187      OnVariableInfoAdded(variableInfo);
188    }
189    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo) {
190      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
191      if (IsValid()) {
192        OnVariableInfoAdded(variableInfo);
193        return true;
194      } else {
195        myVariableInfos.Remove(variableInfo.FormalName);
196        return false;
197      }
198    }
199    public virtual bool TryAddVariableInfo(IVariableInfo variableInfo, out ICollection<IConstraint> violatedConstraints) {
200      myVariableInfos.Add(variableInfo.FormalName, variableInfo);
201      if (IsValid(out violatedConstraints)) {
202        OnVariableInfoAdded(variableInfo);
203        return true;
204      } else {
205        myVariableInfos.Remove(variableInfo.FormalName);
206        return false;
207      }
208    }
209    public virtual void RemoveVariableInfo(string formalName) {
210      IVariableInfo variableInfo;
211      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
212        myVariableInfos.Remove(formalName);
213        OnVariableInfoRemoved(variableInfo);
214      }
215    }
216    public virtual bool TryRemoveVariableInfo(string formalName) {
217      IVariableInfo variableInfo;
218      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
219        myVariableInfos.Remove(formalName);
220        if (IsValid()) {
221          OnVariableInfoRemoved(variableInfo);
222          return true;
223        } else {
224          myVariableInfos.Add(formalName, variableInfo);
225          return false;
226        }
227      }
228      return true;
229    }
230    public virtual bool TryRemoveVariableInfo(string formalName, out ICollection<IConstraint> violatedConstraints) {
231      IVariableInfo variableInfo;
232      if (myVariableInfos.TryGetValue(formalName, out variableInfo)) {
233        myVariableInfos.Remove(formalName);
234        if (IsValid(out violatedConstraints)) {
235          OnVariableInfoRemoved(variableInfo);
236          return true;
237        } else {
238          myVariableInfos.Add(formalName, variableInfo);
239          return false;
240        }
241      }
242      violatedConstraints = new List<IConstraint>();
243      return true;
244    }
245    #endregion
246
247    #region Variable Methods
248    public virtual IVariable GetVariable(string name) {
249      IVariable variable;
250      if (myVariables.TryGetValue(name, out variable))
251        return variable;
252      else
253        return null;
254    }
255    public virtual void AddVariable(IVariable variable) {
256      myVariables.Add(variable.Name, variable);
257      variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
258      variable.NameChanged += new EventHandler(Variable_NameChanged);
259      OnVariableAdded(variable);
260    }
261    public virtual bool TryAddVariable(IVariable variable) {
262      myVariables.Add(variable.Name, variable);
263      if (IsValid()) {
264        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
265        variable.NameChanged += new EventHandler(Variable_NameChanged);
266        OnVariableAdded(variable);
267        return true;
268      } else {
269        myVariableInfos.Remove(variable.Name);
270        return false;
271      }
272    }
273    public virtual bool TryAddVariable(IVariable variable, out ICollection<IConstraint> violatedConstraints) {
274      myVariables.Add(variable.Name, variable);
275      if (IsValid(out violatedConstraints)) {
276        variable.NameChanging += new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
277        variable.NameChanged += new EventHandler(Variable_NameChanged);
278        OnVariableAdded(variable);
279        return true;
280      } else {
281        myVariableInfos.Remove(variable.Name);
282        return false;
283      }
284    }
285    public virtual void RemoveVariable(string name) {
286      IVariable variable;
287      if (myVariables.TryGetValue(name, out variable)) {
288        variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
289        variable.NameChanged -= new EventHandler(Variable_NameChanged);
290        myVariables.Remove(name);
291        OnVariableRemoved(variable);
292      }
293    }
294    public virtual bool TryRemoveVariable(string name) {
295      IVariable variable;
296      if (myVariables.TryGetValue(name, out variable)) {
297        myVariables.Remove(name);
298        if (IsValid()) {
299          variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
300          variable.NameChanged -= new EventHandler(Variable_NameChanged);
301          OnVariableRemoved(variable);
302          return true;
303        } else {
304          myVariables.Add(name, variable);
305          return false;
306        }
307      }
308      return true;
309    }
310    public virtual bool TryRemoveVariable(string name, out ICollection<IConstraint> violatedConstraints) {
311      IVariable variable;
312      if (myVariables.TryGetValue(name, out variable)) {
313        myVariables.Remove(name);
314        if (IsValid(out violatedConstraints)) {
315          variable.NameChanging -= new EventHandler<NameChangingEventArgs>(Variable_NameChanging);
316          variable.NameChanged -= new EventHandler(Variable_NameChanged);
317          OnVariableRemoved(variable);
318          return true;
319        } else {
320          myVariables.Add(name, variable);
321          return false;
322        }
323      }
324      violatedConstraints = new List<IConstraint>();
325      return true;
326    }
327    private void Variable_NameChanging(object sender, NameChangingEventArgs e) {
328      e.Cancel = myVariables.ContainsKey(e.Name);
329    }
330    private void Variable_NameChanged(object sender, EventArgs e) {
331      IVariable variable = (IVariable)sender;
332      string oldName = null;
333      foreach (KeyValuePair<string, IVariable> element in myVariables) {
334        if (element.Value == variable)
335          oldName = element.Key;
336      }
337      myVariables.Remove(oldName);
338      myVariables.Add(variable.Name, variable);
339    }
340    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup) where T : class, IItem {
341      return GetVariableValue<T>(formalName, scope, recursiveLookup, true);
342    }
343    public T GetVariableValue<T>(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) where T : class, IItem {
344      return (T)GetVariableValue(formalName, scope, recursiveLookup, throwOnError);
345    }
346    public IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup) {
347      return GetVariableValue(formalName, scope, recursiveLookup, true);
348    }
349    public virtual IItem GetVariableValue(string formalName, IScope scope, bool recursiveLookup, bool throwOnError) {
350      IVariableInfo info = GetVariableInfo(formalName);
351      if (info.Local) {
352        IVariable variable;
353        if (myVariables.TryGetValue(info.ActualName, out variable))
354          return variable.Value;
355        else {
356          if (throwOnError)
357            throw new ArgumentException("Variable " + info.ActualName + " not found");
358          else
359            return null;
360        }
361      } else {
362        return scope.GetVariableValue(formalName, recursiveLookup, throwOnError);
363      }
364    }
365    #endregion
366
367    public virtual IOperation Execute(IScope scope) {
368      myCanceled = false;
369
370      foreach (IVariableInfo variableInfo in VariableInfos)
371        scope.AddAlias(variableInfo.FormalName, variableInfo.ActualName);
372
373      IOperation next = Apply(scope);
374
375      foreach (IVariableInfo variableInfo in VariableInfos)
376        scope.RemoveAlias(variableInfo.FormalName);
377
378      OnExecuted();
379      return next;
380    }
381    public virtual void Abort() {
382      myCanceled = true;
383    }
384
385    public virtual IOperation Apply(IScope scope) {
386      return null;
387    }
388
389    public event EventHandler NameChanged;
390    protected virtual void OnNameChanged() {
391      if (NameChanged != null) {
392        NameChanged(this, new EventArgs());
393      }
394    }
395    public event EventHandler BreakpointChanged;
396    protected virtual void OnBreakpointChanged() {
397      if (BreakpointChanged != null) {
398        BreakpointChanged(this, new EventArgs());
399      }
400    }
401    public event EventHandler<OperatorIndexEventArgs> SubOperatorAdded;
402    protected virtual void OnSubOperatorAdded(IOperator subOperator, int index) {
403      if (SubOperatorAdded != null)
404        SubOperatorAdded(this, new OperatorIndexEventArgs(subOperator, index));
405    }
406    public event EventHandler<OperatorIndexEventArgs> SubOperatorRemoved;
407    protected virtual void OnSubOperatorRemoved(IOperator subOperator, int index) {
408      if (SubOperatorRemoved != null)
409        SubOperatorRemoved(this, new OperatorIndexEventArgs(subOperator, index));
410    }
411    public event EventHandler<VariableInfoEventArgs> VariableInfoAdded;
412    protected virtual void OnVariableInfoAdded(IVariableInfo variableInfo) {
413      if (VariableInfoAdded != null)
414        VariableInfoAdded(this, new VariableInfoEventArgs(variableInfo));
415    }
416    public event EventHandler<VariableInfoEventArgs> VariableInfoRemoved;
417    protected virtual void OnVariableInfoRemoved(IVariableInfo variableInfo) {
418      if (VariableInfoRemoved != null)
419        VariableInfoRemoved(this, new VariableInfoEventArgs(variableInfo));
420    }
421    public event EventHandler<VariableEventArgs> VariableAdded;
422    protected virtual void OnVariableAdded(IVariable variable) {
423      if (VariableAdded != null)
424        VariableAdded(this, new VariableEventArgs(variable));
425    }
426    public event EventHandler<VariableEventArgs> VariableRemoved;
427    protected virtual void OnVariableRemoved(IVariable variable) {
428      if (VariableRemoved != null)
429        VariableRemoved(this, new VariableEventArgs(variable));
430    }
431    public event EventHandler Executed;
432    protected virtual void OnExecuted() {
433      if (Executed != null) {
434        Executed(this, new EventArgs());
435      }
436    }
437
438    #region Persistence Methods
439    public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid,IStorable> persistedObjects) {
440      XmlNode node = base.GetXmlNode(name, document, persistedObjects);
441      XmlAttribute nameAttribute = document.CreateAttribute("Name");
442      nameAttribute.Value = Name;
443      node.Attributes.Append(nameAttribute);
444      if (Breakpoint) {
445        XmlAttribute breakpointAttribute = document.CreateAttribute("Breakpoint");
446        breakpointAttribute.Value = Breakpoint.ToString();
447        node.Attributes.Append(breakpointAttribute);
448      }
449      XmlNode subOperatorsNode = document.CreateNode(XmlNodeType.Element, "SubOperators", null);
450      for (int i = 0; i < SubOperators.Count; i++)
451        subOperatorsNode.AppendChild(PersistenceManager.Persist(SubOperators[i], document, persistedObjects));
452      node.AppendChild(subOperatorsNode);
453      XmlNode infosNode = document.CreateNode(XmlNodeType.Element, "VariableInfos", null);
454      foreach (IVariableInfo info in myVariableInfos.Values)
455        infosNode.AppendChild(PersistenceManager.Persist(info, document, persistedObjects));
456      node.AppendChild(infosNode);
457      XmlNode variablesNode = document.CreateNode(XmlNodeType.Element, "Variables", null);
458      foreach (IVariable variable in myVariables.Values)
459        variablesNode.AppendChild(PersistenceManager.Persist(variable, document, persistedObjects));
460      node.AppendChild(variablesNode);
461      return node;
462    }
463    public override void Populate(XmlNode node, IDictionary<Guid,IStorable> restoredObjects) {
464      base.Populate(node, restoredObjects);
465      myName = node.Attributes["Name"].Value;
466      if (node.Attributes["Breakpoint"] != null)
467        myBreakpoint = bool.Parse(node.Attributes["Breakpoint"].Value);
468      XmlNode subOperatorsNode = node.SelectSingleNode("SubOperators");
469      for (int i = 0; i < subOperatorsNode.ChildNodes.Count; i++)
470        AddSubOperator((IOperator)PersistenceManager.Restore(subOperatorsNode.ChildNodes[i], restoredObjects));
471      XmlNode infosNode = node.SelectSingleNode("VariableInfos");
472      myVariableInfos.Clear();
473      foreach (XmlNode infoNode in infosNode.ChildNodes)
474        AddVariableInfo((IVariableInfo)PersistenceManager.Restore(infoNode, restoredObjects));
475      XmlNode variablesNode = node.SelectSingleNode("Variables");
476      myVariables.Clear();
477      foreach (XmlNode variableNode in variablesNode.ChildNodes)
478        AddVariable((IVariable)PersistenceManager.Restore(variableNode, restoredObjects));
479    }
480    #endregion
481  }
482}
Note: See TracBrowser for help on using the repository browser.