Skip to content

Commit

Permalink
Value types
Browse files Browse the repository at this point in the history
  • Loading branch information
jmjrawlings committed Jul 28, 2024
1 parent 6689dc5 commit 781fbb0
Show file tree
Hide file tree
Showing 12 changed files with 330 additions and 81 deletions.
56 changes: 0 additions & 56 deletions src/MiniZinc.Client/SolveResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,62 +126,6 @@ public abstract record SolveResult<T>
SolveStatus.Unsatisfiable => true,
_ => false
};

/// <summary>
/// Get the solution assigned to the given variable
/// </summary>
/// <param name="id">Name of the model variable</param>
/// <exception cref="Exception">The variable does not exists or was not of the expected type</exception>
public U Get<U>(string id)
where U : ExpressionSyntax
{
if (TryGet<U>(id) is not { } value)
throw new KeyNotFoundException($"Result did not contain a solution for \"{id}\"");

return value;
}

public ValueSyntax? TryGet(string id) => Data.Values.GetValueOrDefault(id);

/// <summary>
/// Try to get the solution assigned to the given variable
/// </summary>
/// <param name="id">Name of the model variable</param>
public U? TryGet<U>(string id)
where U : ExpressionSyntax
{
var value = TryGet(id);
if (value is null)
return null;

if (value is not U u)
throw new Exception();

return u;
}

public ExpressionSyntax this[string name] => Get<ExpressionSyntax>(name);

/// Get the int solution for the given variable
public int GetInt(string id) => Get<IntLiteralSyntax>(id).Value;

/// Get the bool solution for the given variable
public bool GetBool(string id) => Get<BoolLiteralSyntax>(id).Value;

/// Get the float solution for the given variable
public decimal GetFloat(string id) => Get<FloatLiteralSyntax>(id).Value;

/// Get the array solution for the given variable
public IEnumerable<U> GetArray1D<U>(string id)
{
var array = Get<Array1dSyntax>(id);
foreach (var node in array.Elements)
{
if (node is not ValueSyntax<U> literal)
throw new Exception();
yield return literal.Value;
}
}
}

public sealed record SolveResult : SolveResult<IntOrFloat> { }
Expand Down
2 changes: 1 addition & 1 deletion src/MiniZinc.Client/SolverProcess.cs
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ private void OnSolutionOutput(SolutionOutput o)
goto send;
}

_data.Values.TryGetValue("_objective", out var objectiveNode);
_data.TryGetValue("_objective", out var objectiveNode);
switch (objectiveNode)
{
case null:
Expand Down
83 changes: 77 additions & 6 deletions src/MiniZinc.Parser/DataSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
/// Data is different from a <see cref="ModelSyntax"/> in that it can only
/// contain assignments of the form `$name = $expr;`
/// </remarks>
public sealed class DataSyntax(Dictionary<string, ValueSyntax> values)
: IEquatable<IReadOnlyDictionary<string, ValueSyntax>>
public sealed class DataSyntax(Dictionary<string, ValueSyntax> dict)
: IEquatable<IReadOnlyDictionary<string, ValueSyntax>>,
IReadOnlyDictionary<string, ValueSyntax>
{
public IReadOnlyDictionary<string, ValueSyntax> Values => values;

public string Write(WriteOptions? options = null)
{
var writer = new Writer(options);
Expand All @@ -30,6 +29,11 @@ public override string ToString()
return mzn;
}

IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}

public bool Equals(IReadOnlyDictionary<string, ValueSyntax>? other)
{
if (other is null)
Expand All @@ -39,7 +43,7 @@ public bool Equals(IReadOnlyDictionary<string, ValueSyntax>? other)
return true;

// TODO - faster/better
foreach (var kv in values)
foreach (var kv in dict)
{
var name = kv.Key;
var a = kv.Value;
Expand All @@ -57,18 +61,85 @@ public bool Equals(IReadOnlyDictionary<string, ValueSyntax>? other)
foreach (var kv in other)
{
var name = kv.Key;
if (!values.ContainsKey(name))
if (!dict.ContainsKey(name))
return false;
}

return true;
}

public IEnumerator<KeyValuePair<string, ValueSyntax>> GetEnumerator() => dict.GetEnumerator();

public override bool Equals(object? obj)
{
if (!Equals(obj as IReadOnlyDictionary<string, ExpressionSyntax>))
return false;

return true;
}

/// <summary>
/// Get the solution assigned to the given variable
/// </summary>
/// <param name="id">Name of the model variable</param>
/// <exception cref="Exception">The variable does not exists or was not of the expected type</exception>
public U Get<U>(string id)
where U : ExpressionSyntax
{
if (TryGet<U>(id) is not { } value)
throw new KeyNotFoundException($"Result did not contain a solution for \"{id}\"");

return value;
}

public ValueSyntax? TryGet(string id) => dict.GetValueOrDefault(id);

/// <summary>
/// Try to get the solution assigned to the given variable
/// </summary>
/// <param name="id">Name of the model variable</param>
public U? TryGet<U>(string id)
where U : ExpressionSyntax
{
var value = TryGet(id);
if (value is null)
return null;

if (value is not U u)
throw new Exception();

return u;
}

public bool ContainsKey(string key) => dict.ContainsKey(key);

public bool TryGetValue(string key, out ValueSyntax value) => dict.TryGetValue(key, out value);

public ValueSyntax this[string name] => Get<ValueSyntax>(name);

public IEnumerable<string> Keys => dict.Keys;
public IEnumerable<ValueSyntax> Values => dict.Values;

/// Get the int solution for the given variable
public int GetInt(string id) => Get<IntLiteralSyntax>(id);

/// Get the bool solution for the given variable
public bool GetBool(string id) => Get<BoolLiteralSyntax>(id);

/// Get the float solution for the given variable
public decimal GetFloat(string id) => Get<FloatLiteralSyntax>(id);

/// Get the array solution for the given variable
public IEnumerable<U> GetArray1D<U>(string id)
{
var array = Get<Array1dValueSyntax>(id);
foreach (var node in array.Values)
{
if (node is not ValueSyntax<U> literal)
throw new Exception();
yield return literal.Value;
}
}

public int Count { get; }
}
2 changes: 2 additions & 0 deletions src/MiniZinc.Parser/Expressions/IdentifierSyntax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ public IdentifierSyntax(in Token token)
public string Name => Start.StringValue;

public override string ToString() => Start.ToString();

public static implicit operator string(IdentifierSyntax f) => f.Name;
}
Loading

0 comments on commit 781fbb0

Please sign in to comment.