namespace BayesServer.HelpSamples
{
using BayesServer.Data;
using BayesServer.Inference;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading;
public static class JsonReaderExample
{
private const string HairLengthName = "Hair Length";
private const string HeightName = "Height";
static void Main(string[] args)
{
var network = new Network();
network.Load(@"IdentificationExtended.bayes");
JsonStringExample(network);
JsonStreamExample(network);
}
private sealed class Person
{
public string HairLength
{
get; set;
}
public double Height
{
get; set;
}
}
private sealed class JsonEvidenceMapper
{
private Variable hairLength;
private Variable height;
public JsonEvidenceMapper(Network network)
{
if (network == null)
throw new ArgumentNullException("network");
this.hairLength = network.Variables[HairLengthName, true];
this.height = network.Variables[HeightName, true];
}
public void SetEvidence(IEvidence evidence, Person person)
{
evidence.SetState(this.hairLength.States[person.HairLength, true]);
evidence.Set(this.height, person.Height);
}
}
private static void JsonStringExample(Network network)
{
var jsonPerson1 = "{\"HairLength\": \"Medium\",\"Height\": 110}";
var jsonPerson2 = "{\"HairLength\": \"Long\",\"Height\": 88}";
var hairLength = network.Variables[HairLengthName, true];
var height = network.Variables[HeightName, true];
var evidenceMapper = new JsonEvidenceMapper(network);
var evidence = new Evidence(network);
{
var person1 = JsonConvert.DeserializeObject<Person>(jsonPerson1);
evidenceMapper.SetEvidence(evidence, person1);
PrintPersonEvidence(evidence, hairLength, height);
}
{
var person2 = JsonConvert.DeserializeObject<Person>(jsonPerson2);
evidenceMapper.SetEvidence(evidence, person2);
PrintPersonEvidence(evidence, hairLength, height);
}
}
private class JsonEvidenceReaderCommand<T> : IEvidenceReaderCommand
{
private Action<IEvidence, T> setEvidence;
private Func<Stream> newStream;
public JsonEvidenceReaderCommand(Action<IEvidence, T> setEvidence, Func<Stream> newStream)
{
if (setEvidence == null)
throw new ArgumentNullException("setEvidence");
if (newStream == null)
throw new ArgumentNullException("newStream");
this.setEvidence = setEvidence;
this.newStream = newStream;
}
public IEvidenceReader ExecuteReader()
{
return new JsonEvidenceReader<T>(this.setEvidence, this.newStream());
}
}
private class JsonEvidenceReader<T> : IEvidenceReader
{
private Stream stream;
private IEnumerator<T> enumerator;
private Action<IEvidence, T> setEvidence;
private const int DisposedTrue = -1;
private const int DisposedFalse = 0;
private int disposed = DisposedFalse;
public JsonEvidenceReader(Action<IEvidence, T> setEvidence, Stream stream)
{
if (stream == null)
throw new ArgumentNullException("stream");
if (setEvidence == null)
throw new ArgumentNullException("setEvidence");
this.stream = stream;
this.enumerator = EnumerateJson<T>(this.stream).GetEnumerator();
this.setEvidence = setEvidence;
}
public void Dispose()
{
Dispose(true);
}
private void Dispose(bool disposing)
{
if (Interlocked.Exchange(ref this.disposed, DisposedTrue) == DisposedFalse)
{
if(this.stream != null)
{
this.stream.Close();
this.stream = null;
}
}
}
~JsonEvidenceReader()
{
Dispose(false);
GC.SuppressFinalize(this);
}
public bool Read(IEvidence evidence, IReadOptions readOptions)
{
if (this.disposed == DisposedTrue)
{
throw new ObjectDisposedException(this.GetType().Name);
}
var result = this.enumerator.MoveNext();
if (result)
{
this.setEvidence(evidence, this.enumerator.Current);
}
return result;
}
}
private static IEnumerable<TResult> EnumerateJson<TResult>(Stream stream)
{
var serializer = new JsonSerializer();
using (var reader = new StreamReader(stream))
{
using (var jsonReader = new JsonTextReader(reader))
{
jsonReader.SupportMultipleContent = true;
while (jsonReader.Read())
{
yield return serializer.Deserialize<TResult>(jsonReader);
}
}
}
}
private static Stream GetJsonStream()
{
var jsonString = "{\"HairLength\":\"Long\",\"Height\":100.0}{\"HairLength\":\"Medium\",\"Height\":120.0}{\"HairLength\":\"Medium\",\"Height\":99.0}";
return new MemoryStream(Encoding.UTF8.GetBytes(jsonString));
}
private static void JsonStreamExample(Network network)
{
var mapper = new JsonEvidenceMapper(network);
var evidenceReaderCommand = new JsonEvidenceReaderCommand<Person>(
(evidence, p) => mapper.SetEvidence(evidence, p),
() => GetJsonStream()
);
TestEvidenceReader(network, evidenceReaderCommand);
}
private static void TestEvidenceReader(Network network, IEvidenceReaderCommand evidenceReaderCommand)
{
var readOptions = new ReadOptions();
var hairLength = network.Variables[HairLengthName, true];
var height = network.Variables[HeightName, true];
var testEvidence = new Evidence(network);
using (var evidenceReader = evidenceReaderCommand.ExecuteReader())
{
while (evidenceReader.Read(testEvidence, readOptions))
{
PrintPersonEvidence(testEvidence, hairLength, height);
}
}
}
private static void PrintPersonEvidence(IEvidence evidence, Variable hairLength, Variable height)
{
Console.WriteLine("Person...");
Console.WriteLine("\t" + hairLength.States[evidence.GetState(hairLength).Value].Name);
Console.WriteLine("\t" + evidence.Get(height).Value);
}
}
}