Ironically I mentioned this concept in my post "What if..." and here's an
article that describes just what I was mentioning.
Now I've been thinking about this kind of idea for a while now and have some code.
Namespace Logic.Model
{
[DataContract]
[Serializable]
public abstract class CellUnit : ICellUnit
{
[DataMember]
protected String DomainName { private set; get; }
[DataMember]
protected Integrator _integrator;
protected object LockNode = new object();
protected object LockNotifier = new object();
protected EventArgs eventArgs;
[DataMember]
protected ILogicBuilder newLogic;
[DataMember]
public Guid ID { set; get; }
[DataMember]
public bool Status { set; get; }
protected PassedParameter passedData;
public CellUnit()
{
ID = Guid.NewGuid();
_integrator = Integrator.GetIntegrator();
eventArgs = new EventArgs();
newLogic = LogicBuilder.GetLogicBuilder();
}
public CellUnit(string _domain)
:base()
{
DomainName = _domain;
}
public virtual void Notifier(Object sender, PassedParameter data)
{
if (Monitor.TryEnter(LockNotifier))
{
passedData = data;
Worker();
Monitor.Exit(LockNotifier);
}
}
protected abstract void Worker();
protected abstract bool TestLogic();
public abstract void ProcessFailState(bool output);
[DataMember]
public ICellUnit ElsePath { set; get; }
[DataMember]
public Boolean BuildElsePath { set; get; }
[DataMember]
public StateChanged FailureNotification { set; get; }
[DataMember]
public ICellUnit ContinuationPath { set; get; }
}
So the idea is to encompass any kind of processing within a wrapper that determines if it's successful and stores the outputs of such processing if needed. This acts as a wrapper that triggers the process if the integration of inputs qualifies it to do so. The integration can be boolean or a weighted output that integrates to some higher-level process, say a learning algorithm.
The Worker method is a cached delegate from a reflected invocation of some processing code, it could be anything.
Here's more code that extends the ability of the above class where it inherits from CellUnit.
namespace Logic.Model
{
public abstract class CodeUnit : CellUnit, ICodelUnit
{
[DataMember]
public List<IEncodingLogic> Inputs { set; get; }
[DataMember]
public Facet OutPut { set; get; }
[DataMember]
public bool WeightedLogic
{
set
{
_weightedLogic = value;
}
get
{
return _weightedLogic;
}
}
private bool _weightedLogic;
public CodeUnit(bool propagate = false)
{
Initializer();
OutPut.PropagateData = propagate;
}
public CodeUnit(String _domain, bool propagate = false)
:base(_domain)
{
Initializer();
OutPut.PropagateData = propagate;
}
public CodeUnit(SpikeCoder spikeCode, bool propagate = false)
{
Initializer();
OutPut.CodedFacet = spikeCode;
OutPut.PropagateData = propagate;
WeightedLogic = true;
}
public CodeUnit(SpikeCoder spikeCode, String _domain, bool propagate = false)
: base(_domain)
{
Initializer();
OutPut.PropagateData = propagate;
OutPut.CodedFacet = spikeCode;
WeightedLogic = true;
}
private void Initializer()
{
Inputs = new List<IEncodingLogic>();
OutPut = new Facet();
}
public void AddEncoding(EncodingLogic coder)
{
OutPut.Notify += Notifier;
Inputs.Add(coder);
}
public void AddEncoding(List<EncodingLogic> coders)
{
foreach (EncodingLogic aCoder in coders)
OutPut.Notify += Notifier;
Inputs.AddRange(coders);
}
public void AddEncoding(EncodingLogic[] coders)
{
foreach (EncodingLogic aCoder in coders)
OutPut.Notify += Notifier;
Inputs.AddRange(coders);
}
public void RemoveNotifier(EncodingLogic aCoder)
{
OutPut.Notify -= Notifier;
Inputs.Remove(aCoder);
}
public void RemoveNotifier()
{
foreach (EncodingLogic aCoder in Inputs)
{
OutPut.Notify -= Notifier;
}
Inputs.Clear();
}
protected override bool TestLogic()
{
if (WeightedLogic)
return _integrator.Integrate(Inputs, OutPut.CodedFacet.RuleWeight);
else
return _integrator.Integrate(Inputs);
}
public override void ProcessFailState(bool output)
{
if (output && ContinuationPath != null)
ContinuationPath.Notifier(this, OutPut.PropagateData ? OutPut.Data : null);
else if (!output && ElsePath != null)
ElsePath.Notifier(this, OutPut.PropagateData ? OutPut.Data : null);
else if (!output && BuildElsePath && ElsePath == null)
ElsePath = newLogic.BuildLogic(this);
else if (FailureNotification != null)
FailureNotification(this, OutPut.PropagateData ? OutPut.Data : null);
}
}
And here's yet a more complex extension called a "Threshold" whose worker evaluates vectors:
namespace Logic.Model
{
[DataContract]
[Serializable]
public class Threshold : CodeUnit
{
[DataMember]
public Object CurrentData { set; get; }
[DataMember]
public IBoundary Boundary { set; get; }
[DataMember]
public double Error { set; get; }
public Threshold(IBoundary bounded, bool propagate = false)
:base(propagate)
{
Boundary = bounded;
}
public Threshold(IBoundary bounded, SpikeCoder spikeCoder, bool propagate = false)
:base(spikeCoder, propagate)
{
Boundary = bounded;
}
public Threshold(IBoundary bounded, string _domain, bool propagate = false)
: base(_domain, propagate)
{
Boundary = bounded;
}
public Threshold(IBoundary bounded, SpikeCoder spikeCode, String _domain, bool propagate = false)
:base(spikeCode, _domain, propagate)
{
Boundary = bounded;
}
protected virtual bool TestThreshold(object input)
{
throw new NotImplementedException();
return false;
}
protected virtual void CalculateError(object input)
{
throw new NotImplementedException();
}
protected override void Worker()
{
if (Monitor.TryEnter(LockNode))
{
try
{
if (TestLogic())
{
if (OutPut.PropagateData)
OutPut.Data.Parameter = CurrentData;
OutPut.State = Boundary.Equals(CurrentData);
if (!OutPut.State)
CalculateError(CurrentData);
ProcessFailState(OutPut.State);
}
}
catch { }
finally
{
Monitor.Exit(LockNode);
}
}
}
}
Here's an extension of "Threshold" called a "Harness" whose function or process can be anything:
namespace Logic.Model
{
[DataContract]
[Serializable]
public class Harness : Threshold
{
Delegate aProcess;
dynamic[] injectData;
[DataMember]
public dynamic Assignment { set; get; }
[DataMember]
public String InitiatorMethod { set; get; }
[DataMember]
public List<dynamic> ParameterSet { set; get; }
[DataMember]
public bool ExtractParameters { set; get; }
[DataMember]
public dynamic ParameterSource { set; get; }
[DataMember]
public String ExtractMethodCall { set; get; }
[DataMember]
public Boolean StoreAssignmentResultant { set; get; }
[DataMember]
public Boolean ApplyPropagatedData { set; get; }
[DataMember]
public AddParameter HowToApplyPropagatedData { set; get; }
[DataMember]
public List<PassedParameter> AcceptedList { set; get; }
[DataMember]
public List<PassedParameter> ExceptionList { set; get; }
public Harness(IBoundary bounded, bool propagate = false)
:base(bounded, propagate)
{
BasicSetUp();
}
private void BasicSetUp()
{
ParameterSet = new List<dynamic>();
HowToApplyPropagatedData = AddParameter.addOn;
}
public Harness(IBoundary bounded, object assignee, string methodCall, object extractor, string extractMethod, bool propagate = false)
:base(bounded, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSource = extractor;
ExtractMethodCall = extractMethod;
}
public Harness(IBoundary bounded, object assignee, string methodCall, dynamic[] parameterSet, bool propagate = false)
: base(bounded, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSet.AddRange(parameterSet);
}
public Harness(IBoundary bounded, string _domain, bool propagate = false)
: base(bounded, _domain, propagate)
{
BasicSetUp();
}
public Harness(IBoundary bounded, string _domain, object assignee, string methodCall, object extractor, string extractMethod, bool propagate = false)
: base(bounded, _domain, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSource = extractor;
ExtractMethodCall = extractMethod;
}
public Harness(IBoundary bounded, string _domain, object assignee, string methodCall, dynamic[] parameterSet, bool propagate = false)
: base(bounded, _domain, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSet.AddRange(parameterSet);
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, bool propagate = false)
: base(bounded, spikeCode, propagate)
{
BasicSetUp();
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, object assignee, string methodCall, object extractor, string extractMethod, bool propagate = false)
: base(bounded, spikeCode, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSource = extractor;
ExtractMethodCall = extractMethod;
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, object assignee, string methodCall, dynamic[] parameterSet, bool propagate = false)
: base(bounded, spikeCode, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSet.AddRange(parameterSet);
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, string _domain, bool propagate = false)
: base(bounded, spikeCode, _domain, propagate)
{
BasicSetUp();
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, string _domain, object assignee, string methodCall, object extractor, string extractMethod, bool propagate = false)
: base(bounded, spikeCode, _domain, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSource = extractor;
ExtractMethodCall = extractMethod;
}
public Harness(SpikeCoder spikeCode, IBoundary bounded, string _domain, object assignee, string methodCall, dynamic[] parameterSet, bool propagate = false)
: base(bounded, spikeCode, _domain, propagate)
{
BasicSetUp();
MethodCallSetUp(assignee, methodCall);
ParameterSet.AddRange(parameterSet);
}
private void MethodCallSetUp(Type assignee, string methodCall)
{
}
private void MethodCallSetUp(dynamic assignee, string methodCall)
{
Assignment = assignee;
InitiatorMethod = methodCall;
aProcess = Delegate.CreateDelegate(Assignment.GetType(), injectData, methodCall);
}
protected override void Worker()
{
if (Monitor.TryEnter(LockNode))
{
try
{
if (TestLogic())
{
ExecuteAndStore();
AddPassedData();
dynamic result = aProcess;
if (StoreAssignmentResultant)
CurrentData = result;
if (OutPut.PropagateData)
OutPut.Data.Parameter = CurrentData;
OutPut.State = Boundary.Equals(result);
ProcessFailState(OutPut.State);
}
}
catch { }
finally
{
Monitor.Exit(LockNode);
}
}
}
private dynamic[] InjectedDataArray()
{
List<dynamic> result = new List<dynamic>();
switch(HowToApplyPropagatedData)
{
case AddParameter.AddPropagetedOnly:
result.AddRange(AcceptedList.Select(x => x.Parameter).ToArray());
break;
case AddParameter.AddPropagetedAsArray:
result.Add(AcceptedList.Select(x => x.Parameter).ToArray());
break;
case AddParameter.addOn:
result.AddRange(ParameterSet);
result.AddRange(AcceptedList.Select(x => x.Parameter).ToArray());
break;
case AddParameter.NoPropagatedData:
result.AddRange(ParameterSet);
break;
case AddParameter.AddAllDiscretely:
result.AddRange(AcceptedList.Select(x => x.Parameter).ToArray());
result.Add(ParameterSet);
break;
case AddParameter.AddAllAsArrays:
result.Add(AcceptedList.Select(x => x.Parameter).ToArray());
result.Add(ParameterSet);
break;
}
return result.ToArray();
}
private void AddPassedData()
{
if (ApplyPropagatedData)
{
PassedParameter foundParam = null;
CheckParameterList(foundParam);
switch (HowToApplyPropagatedData)
{
case AddParameter.AddPropagetedOnly:
if (foundParam != null)
foundParam.Parameter = passedData.Parameter;
else
AcceptedList.Add(passedData);
break;
}
}
}
protected void CheckParameterList(PassedParameter foundParam)
{
if (ExceptionList.Any(x => x.ID.Equals(passedData.ID))) return;
foundParam = AcceptedList.Where(x => x.ID.Equals(passedData.ID)).FirstOrDefault();
}
public void ExecuteAndStore()
{
if (ExtractParameters)
{
ParameterSet.Clear();
MethodInfo parametrs = ParameterSource.GetType().GetMethod(ExtractMethodCall);
ParameterSet.AddRange((dynamic[])parametrs.Invoke(ParameterSource, null));
}
}
}
With this idea, you can build pipelines of any kind and integrate processes seamlessly without having to hard code it. This allows for automation where a machine can build pipelines as well. Combine this with an episodic memory along with some other secret sauce and a machine should be able to integrate processes based on context and experience level. So think of it as something like genetic algorithms but the algorithm is not modified, however, the machine does remember what algorithms worked given a certain situation and what other algorithms were needed.