Skip to content

Commit db6d9e4

Browse files
committed
Modified to use one property for both input and output, to ensure they are read together.
1 parent 1a98698 commit db6d9e4

File tree

7 files changed

+161
-152
lines changed

7 files changed

+161
-152
lines changed

BlackBox/BlackBox/BlackBox.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Threading;
4+
using System.Linq;
45

56
namespace BlackBoxModeling
67
{
@@ -18,6 +19,20 @@ public abstract class BlackBox
1819
public Thread RunThread { get; set; }
1920
public Dictionary<string, object> Input { get { return input; } }
2021
public Dictionary<string, object> Output { get { return output; } }
22+
public Dictionary<string, object> InputAndOuput
23+
{
24+
get
25+
{
26+
lock(processingLock )
27+
{
28+
var i = new Dictionary<string, object>(input);
29+
var o = new Dictionary<string, object>(output);
30+
return i.Concat(o).ToDictionary(p => p.Key, p => p.Value);
31+
}
32+
33+
}
34+
}
35+
private static Object processingLock = new object();
2136

2237
//Constructors
2338
public BlackBox() : this("Undefined")
@@ -39,12 +54,14 @@ public void Start()
3954
{
4055
while (RunThread.IsAlive)
4156
{
42-
Run();
57+
lock(processingLock)
58+
Run();
4359
Thread.Sleep(TimeInterval_ms);
4460
timeCurrent_ms += TimeInterval_ms;
4561
}
4662
});
47-
RunThread.IsBackground = true;
63+
RunThread.Name = "BlackBoxRun";
64+
//RunThread.IsBackground = true;
4865

4966
//Start black box
5067
OnStarting?.Invoke(this, new EventArgs()); //trigger pre-start event

KnowProdContBlackBox/KnowProdCont_BlackBox.Tests/PolicyLearnerTests.cs

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,12 @@ public void Learn_LogicOperators(int iterations)
123123
KnowInstance bool1_StayOn = prod1.Get(bool1_On, bool1_On);
124124
KnowInstance bool1_SwitchOff = prod1.Get(bool1_On, bool1_Off);
125125
KnowInstance bool1_SwitchOn = prod1.Get(bool1_Off, bool1_On);
126-
idManager.SetName(bool1_On.ID, "On");
127-
idManager.SetName(bool1_Off.ID, "Off");
128-
idManager.SetName(bool1_StayOff.ID, "Stay Off");
129-
idManager.SetName(bool1_StayOn.ID, "Stay On");
130-
idManager.SetName(bool1_SwitchOff.ID, "Switch Off");
131-
idManager.SetName(bool1_SwitchOn.ID, "Switch On");
126+
idManager.SetName(bool1_On.ID, "True");
127+
idManager.SetName(bool1_Off.ID, "False");
128+
idManager.SetName(bool1_StayOff.ID, "Stay False");
129+
idManager.SetName(bool1_StayOn.ID, "Stay True");
130+
idManager.SetName(bool1_SwitchOff.ID, "True to False");
131+
idManager.SetName(bool1_SwitchOn.ID, "False to True");
132132
#endregion
133133
#region bool2
134134
KnowInstance bool2_On = prod2.Get(disc2.GetBin(5.0).BinID);
@@ -137,26 +137,26 @@ public void Learn_LogicOperators(int iterations)
137137
KnowInstance bool2_StayOn = prod2.Get(bool2_On, bool2_On);
138138
KnowInstance bool2_SwitchOff = prod2.Get(bool2_On, bool2_Off);
139139
KnowInstance bool2_SwitchOn = prod2.Get(bool2_Off, bool2_On);
140-
idManager.SetName(bool2_On.ID, "On");
141-
idManager.SetName(bool2_Off.ID, "Off");
142-
idManager.SetName(bool2_StayOff.ID, "Stay Off");
143-
idManager.SetName(bool2_StayOn.ID, "Stay On");
144-
idManager.SetName(bool2_SwitchOff.ID, "Switch Off");
145-
idManager.SetName(bool2_SwitchOn.ID, "Switch On");
140+
idManager.SetName(bool2_On.ID, "True");
141+
idManager.SetName(bool2_Off.ID, "False");
142+
idManager.SetName(bool2_StayOff.ID, "Stay False");
143+
idManager.SetName(bool2_StayOn.ID, "Stay True");
144+
idManager.SetName(bool2_SwitchOff.ID, "True to False");
145+
idManager.SetName(bool2_SwitchOn.ID, "False to True");
146146
#endregion
147147
#region boolxor
148148
KnowInstance xor_On = prodxor.Get(discxor.GetBin(5.0).BinID);
149149
KnowInstance xor_Off = prodxor.Get(discxor.GetBin(0.0).BinID);
150-
KnowInstance xor_StayedOff = prodxor.Get(xor_Off, xor_Off);
151-
KnowInstance xor_StayedOn = prodxor.Get(xor_On, xor_On);
150+
KnowInstance xor_StayOff = prodxor.Get(xor_Off, xor_Off);
151+
KnowInstance xor_StayOn = prodxor.Get(xor_On, xor_On);
152152
KnowInstance xor_SwitchedOff = prodxor.Get(xor_On, xor_Off);
153153
KnowInstance xor_SwitchedOn = prodxor.Get(xor_Off, xor_On);
154-
idManager.SetName(xor_On.ID, "On");
155-
idManager.SetName(xor_Off.ID, "Off");
156-
idManager.SetName(xor_StayedOff.ID, "Stayed Off");
157-
idManager.SetName(xor_StayedOn.ID, "Stayed On");
158-
idManager.SetName(xor_SwitchedOff.ID, "Switched Off");
159-
idManager.SetName(xor_SwitchedOn.ID, "Switched On");
154+
idManager.SetName(xor_On.ID, "True");
155+
idManager.SetName(xor_Off.ID, "False");
156+
idManager.SetName(xor_StayOff.ID, "Stay False");
157+
idManager.SetName(xor_StayOn.ID, "Stay True");
158+
idManager.SetName(xor_SwitchedOff.ID, "True to False");
159+
idManager.SetName(xor_SwitchedOn.ID, "False to True");
160160
#endregion
161161

162162
//Decision Trees (detailed and simple)

KnowProdContBlackBox/KnowProdCont_BlackBox/DiscreteBlackBox.cs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,34 +31,25 @@ public int TimeInterval_ms {
3131
return this.blackBox.TimeInterval_ms;
3232
}
3333
}
34-
public Dictionary<string, Bin> Input
34+
public Dictionary<string, Bin> InputAndOutput
3535
{
3636
get
3737
{
38-
Dictionary<string, Bin> dict = new Dictionary<string, Bin>();
39-
foreach (var input in blackBox.Input.ToList())
40-
{
41-
Discretizer disc = Discretizers[input.Key];
42-
double value = Convert.ToDouble(blackBox.Input[input.Key]);
43-
Bin bin = disc.GetBin(value);
44-
dict[input.Key] = bin;
45-
}
46-
return dict;
38+
return ConvertToBin(blackBox.InputAndOuput);
4739
}
4840
}
49-
public Dictionary<string, Bin> Output
41+
public List<string> InputNames
5042
{
5143
get
5244
{
53-
Dictionary<string, Bin> dict = new Dictionary<string, Bin>();
54-
foreach (var output in blackBox.Output.ToList())
55-
{
56-
Discretizer disc = Discretizers[output.Key];
57-
double value = Convert.ToDouble(blackBox.Output[output.Key]);
58-
Bin bin = disc.GetBin(value);
59-
dict[output.Key] = bin;
60-
}
61-
return dict;
45+
return blackBox.Input.Keys.ToList();
46+
}
47+
}
48+
public List<string> OutputNames
49+
{
50+
get
51+
{
52+
return blackBox.Output.Keys.ToList();
6253
}
6354
}
6455
public event EventHandler OnStarting
@@ -80,9 +71,9 @@ public DiscreteBlackBox(BlackBox blackBox, IdManager idManager)
8071

8172
//Create a discretizer for each input and output
8273
foreach (var inputName in blackBox.Input.Keys)
83-
Discretizers.Add(inputName, new Discretizer() { GenerateIdDelegate = idManager.GenerateId });
74+
Discretizers.Add(inputName, new Discretizer(idManager.GenerateId));
8475
foreach (var outputName in blackBox.Output.Keys)
85-
Discretizers.Add(outputName, new Discretizer() { GenerateIdDelegate = idManager.GenerateId });
76+
Discretizers.Add(outputName, new Discretizer(idManager.GenerateId));
8677

8778
//Create a sampling thread for each input and output
8879
foreach (string inputName in blackBox.Input.Keys)
@@ -107,6 +98,24 @@ private void BlackBox_OnStarting(object sender, EventArgs e)
10798
foreach (Thread t in learningThreads.Values)
10899
t.Start();
109100
}
101+
private Dictionary<string, Bin> ConvertToBin(Dictionary<string, object> ioState)
102+
{
103+
var inputStateConverted = new Dictionary<string, Bin>();
104+
foreach (var io in ioState)
105+
{
106+
string ioName = io.Key;
107+
108+
if (io.Value != null)
109+
{
110+
double value = Convert.ToDouble(io.Value);
111+
Bin bin = this.Discretizers[ioName].GetBin(value);
112+
inputStateConverted[ioName] = bin;
113+
}else
114+
inputStateConverted[ioName] = null;
115+
}
116+
117+
return inputStateConverted;
118+
}
110119
private Thread CreateLearningThread(string source, string name)
111120
{
112121
//Get discretizer and value
@@ -125,7 +134,7 @@ private Thread CreateLearningThread(string source, string name)
125134
}
126135

127136
//Create the background sampling thread
128-
Thread samplingThread = new Thread
137+
Thread learningThread = new Thread
129138
(delegate ()
130139
{
131140
while (Thread.CurrentThread.IsAlive)
@@ -135,14 +144,12 @@ private Thread CreateLearningThread(string source, string name)
135144

136145
//Sample the value twice as fast as the black box changes
137146
Thread.Sleep(blackBox.TimeInterval_ms / 2);
138-
139-
//If discretizers' sizes are not changing, slow down sampling
140-
// - Not yet implemented
141147
}
142148
});
143-
samplingThread.IsBackground = true;
149+
learningThread.Name = "DiscreteBlackBoxSampling";
150+
//samplingThread.IsBackground = true;
144151

145-
return samplingThread;
152+
return learningThread;
146153
}
147154
}
148155
}

KnowProdContBlackBox/KnowProdCont_BlackBox/Interpreter.cs

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class Interpreter
1919
//Properties
2020
public Queue<Dictionary<string, KnowInstance>> MemoryInput { get; set; } = new Queue<Dictionary<string, KnowInstance>>();
2121
public Queue<Dictionary<string, KnowInstance>> MemoryOutput { get; set; } = new Queue<Dictionary<string, KnowInstance>>();
22+
public Queue<Dictionary<string, KnowInstance>> MemoryIOState { get; set; } = new Queue<Dictionary<string, KnowInstance>>();
2223
public int MemorySize { get; set; } = 20;
2324

2425
//Properties - Inner black box
@@ -40,14 +41,14 @@ public List<string> InputNames
4041
{
4142
get
4243
{
43-
return prodBlackBox.Input.Keys.ToList();
44+
return prodBlackBox.InputNames; ;
4445
}
4546
}
4647
public List<string> OutputNames
4748
{
4849
get
4950
{
50-
return prodBlackBox.Output.Keys.ToList();
51+
return prodBlackBox.OutputNames;
5152
}
5253
}
5354
public event EventHandler OnStarting
@@ -89,64 +90,55 @@ private Thread CreateSamplingThread()
8990
{
9091
while (Thread.CurrentThread.IsAlive)
9192
{
92-
//Sample values of inputs and outputs
93-
var inputState = prodBlackBox.Input.ToDictionary(d => d.Key, d => (KnowInstance)d.Value);
94-
var outputState = prodBlackBox.Output.ToDictionary(d => d.Key, d => (KnowInstance)d.Value);
93+
//Get state of inputs and outputs
94+
var ioState = prodBlackBox.InputAndOutput;
9595

96-
//Check for nulls (not identified) //Note: this should never happen but it does, so there is a bug somewhere.
97-
bool validStates = true;
98-
if (inputState.Select(p => p.Value).Contains(null))
99-
validStates = false;
100-
if (outputState.Select(p => p.Value).Contains(null))
101-
validStates = false;
102-
103-
//Add to memory
104-
if (validStates)
105-
AddToMemory(inputState, outputState);
96+
//Save to memory
97+
AddToMemory(ioState);
10698

10799
//Send through interpreter
108-
var inputStateInter = Interpret(_prevInputState, inputState);
109-
var outputStateInter = Interpret(_prevOutputState, outputState);
110-
111-
//Check for nulls (not identified) //Note: this should never happen but it does, so there is a bug somewhere.
112-
validStates = true;
113-
if (inputStateInter.Select(p => p.Value).Contains(null))
114-
validStates = false;
115-
if (outputStateInter.Select(p => p.Value).Contains(null))
116-
validStates = false;
117-
118-
//Add to memory
119-
if (validStates)
120-
AddToMemory(inputStateInter, outputStateInter);
121-
122-
100+
var ioStateInter = Interpret(_prevIOState, ioState);
123101

124102
//Update prev state
125-
_prevInputState = inputState;
126-
_prevOutputState = outputState;
103+
_prevIOState = ioState;
127104

128105
//Wait until next sample time
129106
Thread.Sleep(prodBlackBox.TimeInterval_ms);
130107
}
131108
});
132-
samplingThread.IsBackground = true;
109+
samplingThread.Name = "InterpreterSampling";
110+
//samplingThread.IsBackground = true;
133111

134112
return samplingThread;
135113
}
136-
private void AddToMemory(Dictionary<string, KnowInstance> inputState, Dictionary<string, KnowInstance> outputState)
114+
//private void AddToMemory(Dictionary<string, KnowInstance> inputState, Dictionary<string, KnowInstance> outputState)
115+
//{
116+
// //Check memory length
117+
// if (MemoryInput.Count == MemorySize)
118+
// {
119+
// MemoryInput.Dequeue();
120+
// MemoryOutput.Dequeue();
121+
// }
122+
123+
// //Add the new item
124+
// MemoryInput.Enqueue(inputState);
125+
// MemoryOutput.Enqueue(outputState);
126+
127+
// //Trigger event
128+
// OnAddedToMemory?.Invoke(this, new AddedToMemoryEventArgs(inputState, outputState));
129+
//}
130+
private void AddToMemory(Dictionary<string, KnowInstance> ioState)
137131
{
138132
//Check memory length
139-
if (MemoryInput.Count == MemorySize)
140-
{
141-
MemoryInput.Dequeue();
142-
MemoryOutput.Dequeue();
143-
}
133+
if (MemoryIOState.Count == MemorySize)
134+
MemoryIOState.Dequeue();
144135

145136
//Add the new item
146-
MemoryInput.Enqueue(inputState);
147-
MemoryOutput.Enqueue(outputState);
137+
MemoryIOState.Enqueue(ioState);
148138

149139
//Trigger event
140+
var inputState = ioState.Where(p => InputNames.Contains(p.Key)).ToDictionary(p => p.Key, p => p.Value);
141+
var outputState = ioState.Where(p => OutputNames.Contains(p.Key)).ToDictionary(p => p.Key, p => p.Value);
150142
OnAddedToMemory?.Invoke(this, new AddedToMemoryEventArgs(inputState, outputState));
151143
}
152144
private Dictionary<string, KnowInstance> Interpret(Dictionary<string, KnowInstance> state1, Dictionary<string, KnowInstance> state2)
@@ -173,7 +165,7 @@ private Dictionary<string, KnowInstance> Interpret(Dictionary<string, KnowInstan
173165

174166
return ioInterpretation;
175167
}
176-
168+
177169
//Events
178170
public event EventHandler<AddedToMemoryEventArgs> OnAddedToMemory;
179171
public class AddedToMemoryEventArgs : EventArgs
@@ -193,5 +185,6 @@ public AddedToMemoryEventArgs(Dictionary<string, KnowInstance> inputState, Dicti
193185
//Methods - cache
194186
private Dictionary<string, KnowInstance> _prevInputState = null;
195187
private Dictionary<string, KnowInstance> _prevOutputState = null;
188+
private Dictionary<string, KnowInstance> _prevIOState = null;
196189
}
197190
}

KnowProdContBlackBox/KnowProdCont_BlackBox/KnowInstanceWithMetaData.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ public string AdditionalNotes
6161
//Constructor
6262
public KnowInstanceWithMetaData(KnowInstance knowInstance, IdManager idManager)
6363
{
64+
//Check parameters are not null
65+
if (knowInstance == null)
66+
throw new ArgumentNullException("knowInstance");
67+
if (idManager == null)
68+
throw new ArgumentNullException("idManager");
69+
70+
//Save
6471
this.InnerKnowInstance = knowInstance;
6572
this.InnerIdManager = idManager;
6673
}

0 commit comments

Comments
 (0)