Skip to content

Commit

Permalink
Datum Parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jmjrawlings committed Aug 14, 2024
1 parent 83b9ccf commit af85c10
Show file tree
Hide file tree
Showing 28 changed files with 632 additions and 402 deletions.
4 changes: 2 additions & 2 deletions src/MiniZinc.Client/MiniZincProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,8 @@ public void Dispose()
public override string ToString() => CommandString;

private MiniZincResult Result(
in DataNode? objectiveValue = null,
in DataNode? objectiveBoundValue = null,
in Datum? objectiveValue = null,
in Datum? objectiveBoundValue = null,
string? error = null
)
{
Expand Down
8 changes: 4 additions & 4 deletions src/MiniZinc.Client/MiniZincResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,18 +74,18 @@ public sealed record MiniZincResult
/// <summary>
/// Text content of the message
/// </summary>
public required DataNode? Objective { get; init; }
public required Datum? Objective { get; init; }

/// <summary>
/// Upper or lower bound (solver-dependent)
/// </summary>
public required DataNode? ObjectiveBound { get; init; }
public required Datum? ObjectiveBound { get; init; }

/// <summary>
/// Absolute Gap to optimality
/// `abs(objective - bound)`
/// </summary>
public required DataNode? AbsoluteGapToOptimality { get; init; }
public required Datum? AbsoluteGapToOptimality { get; init; }

/// <summary>
/// Relative Gap to optimality
Expand All @@ -98,7 +98,7 @@ public sealed record MiniZincResult
/// the previous iteration
/// `objective[i] - objective[i-1]`
/// </summary>
public required DataNode? AbsoluteIterationGap { get; init; }
public required Datum? AbsoluteIterationGap { get; init; }

/// <summary>
/// Relative difference between this iteration and
Expand Down
19 changes: 19 additions & 0 deletions src/MiniZinc.Parser/Data/BoolDatum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace MiniZinc.Parser;

public sealed class BoolDatum(bool value) : MiniZincDatum
{
public bool Value => value;

public static implicit operator bool(BoolDatum expr) => expr.Value;

public override bool Equals(object? obj)
{
if (obj is not bool other)
return false;
if (!value.Equals(other))
return false;
return true;
}

public override string ToString() => Value.ToString();
}
3 changes: 3 additions & 0 deletions src/MiniZinc.Parser/Data/BoolSet.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace MiniZinc.Parser;

public sealed class BoolSet(List<bool> values) : SetDatum<bool>(values) { }
3 changes: 0 additions & 3 deletions src/MiniZinc.Parser/Data/BoolSetData.cs

This file was deleted.

156 changes: 0 additions & 156 deletions src/MiniZinc.Parser/Data/DataNode.cs

This file was deleted.

83 changes: 83 additions & 0 deletions src/MiniZinc.Parser/Data/Datum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
namespace MiniZinc.Parser;

using System.Text.Json;
using System.Text.Json.Nodes;

/// <summary>
/// The values that that appear in MiniZinc data files or
/// syntax.
/// </summary>
public abstract class MiniZincDatum
{
public string Write(WriteOptions? options = null)
{
var writer = new Writer(options);
writer.WriteValue(this);
var mzn = writer.ToString();
return mzn;
}

public static readonly MiniZincDatum Empty = new EmptyDatum();

public static readonly MiniZincDatum True = new BoolDatum(true);

public static readonly MiniZincDatum False = new BoolDatum(false);

public static MiniZincDatum Float(decimal f) => new FloatDatum(f);

public static MiniZincDatum Int(int i) => new IntDatum(i);

public static MiniZincDatum String(string s) => new StringDatum(s);

public static MiniZincDatum FromJson(JsonNode? node)
{
switch (node)
{
case JsonArray array:
return FromJson((JsonNode?)array);
case JsonObject obj:
return FromJson((JsonNode?)obj);
case JsonValue val:
return FromJson((JsonNode?)val);
default:
return Empty;
}
}

public static MiniZincDatum FromJson(JsonObject obj)
{
Dictionary<string, MiniZincDatum> dict = [];
foreach (var (key, node) in obj)
{
var value = FromJson(node);
dict[key] = value;
}

var data = new RecordDatum(dict);
return data;
}

public static MiniZincDatum FromJson(JsonArray array)
{
List<MiniZincDatum> items = [];
foreach (var node in array)
{
var item = FromJson(node);
items.Add(item);
}
var data = new DatumArray(items);
return data;
}

public static MiniZincDatum FromJson(JsonValue node) =>
node.GetValueKind() switch
{
JsonValueKind.Null => Empty,
JsonValueKind.True => True,
JsonValueKind.False => False,
JsonValueKind.Number when node.TryGetValue<decimal>(out var dec) => Float(dec),
JsonValueKind.Number when node.TryGetValue<int>(out var i) => Int(i),
JsonValueKind.String => String(node.GetValue<string>()),
_ => throw new ArgumentException($"Could not parse {node} as a datum")
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

using System.Collections;

public abstract class ArrayData<T>(List<T> values) : DataNode, IReadOnlyList<T>
public abstract class ArrayDatum<T>(List<T> values) : Datum, IReadOnlyList<T>
{
public override DatumKind Kind => DatumKind.Array;

public IEnumerator<T> GetEnumerator() => values.GetEnumerator();

IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
Expand All @@ -12,7 +14,7 @@ public abstract class ArrayData<T>(List<T> values) : DataNode, IReadOnlyList<T>

public T this[int index] => values[index];

public bool Equals(ArrayData<T>? other)
public bool Equals(ArrayDatum<T>? other)
{
if (other is null)
return false;
Expand All @@ -34,17 +36,17 @@ public bool Equals(ArrayData<T>? other)
return true;
}

public override bool Equals(object? obj) => Equals(obj as ArrayData<T>);
public override bool Equals(object? obj) => Equals(obj as ArrayDatum<T>);
}

public sealed class IntArrayData(List<int> list) : ArrayData<int>(list) { }
public sealed class IntArray(List<int> list) : ArrayDatum<int>(list) { }

public sealed class FloatArrayData(List<decimal> list) : ArrayData<decimal>(list) { }
public sealed class FloatArray(List<decimal> list) : ArrayDatum<decimal>(list) { }

public sealed class BoolArrayData(List<bool> list) : ArrayData<bool>(list) { }
public sealed class BoolArray(List<bool> list) : ArrayDatum<bool>(list) { }

public sealed class StringArrayData(List<string> list) : ArrayData<string>(list) { }
public sealed class StringArray(List<string> list) : ArrayDatum<string>(list) { }

public sealed class ArrayData(List<DataNode> list) : ArrayData<DataNode>(list) { }
public sealed class DatumArray(List<Datum> list) : ArrayDatum<Datum>(list) { }

public sealed class TupleData(List<DataNode> list) : ArrayData<DataNode>(list) { }
public sealed class DatumTuple(List<Datum> list) : ArrayDatum<Datum>(list) { }
6 changes: 6 additions & 0 deletions src/MiniZinc.Parser/Data/EmptyDatum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace MiniZinc.Parser;

public sealed class EmptyDatum : MiniZincDatum
{
public override bool Equals(object? obj) => obj is EmptyDatum;
}
19 changes: 19 additions & 0 deletions src/MiniZinc.Parser/Data/FloatDatum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
namespace MiniZinc.Parser;

public sealed class FloatDatum(decimal value) : MiniZincDatum
{
public decimal Value => value;

public static implicit operator decimal(FloatDatum expr) => expr.Value;

public override bool Equals(object? obj)
{
if (obj is not decimal other)
return false;
if (!value.Equals(other))
return false;
return true;
}

public override string ToString() => Value.ToString();
}
Loading

0 comments on commit af85c10

Please sign in to comment.