Skip to content

Commit 4a53904

Browse files
committed
Resolve parameteric sorts in ranks, and ArraysEx functions
1 parent 884868e commit 4a53904

3 files changed

Lines changed: 105 additions & 3 deletions

File tree

Semgus-Lib/Model/Smt/SmtFunction.cs

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,22 @@ private bool TryResolveRank([NotNullWhen(true)] out SmtFunctionRank? rank, SmtFu
153153
}
154154
else
155155
{
156-
resolvedParameters.Add(templateSort, concreteSort);
156+
// Template sorts (that are a parameter) are allowed to have arity 0.
157+
// The whole template will just be matched with the concrete sort.
158+
// Otherwise, we want to make sure the arities match.
159+
if (!(templateSort.IsSortParameter && templateSort.Arity == 0)
160+
&& templateSort.Arity != concreteSort.Arity)
161+
{
162+
rank = default;
163+
return false;
164+
}
165+
166+
// Recursively match the template and match parameter sorts
167+
if (!TraverseAndMatchTemplate(templateSort, concreteSort, resolvedParameters))
168+
{
169+
rank = default;
170+
return false;
171+
}
157172
templateSort = concreteSort;
158173
}
159174
}
@@ -212,6 +227,62 @@ private bool TryResolveRank([NotNullWhen(true)] out SmtFunctionRank? rank, SmtFu
212227
return template.Validator(rank);
213228
}
214229

230+
/// <summary>
231+
/// Match a template sort and parameters against a concrete sort
232+
/// </summary>
233+
/// <param name="template">Template sort to match</param>
234+
/// <param name="concrete">Concrete sort to match against</param>
235+
/// <param name="resolvedParameters">Dictionary of resolved parameters</param>
236+
/// <returns>True if successfully resolves, false if not</returns>
237+
private static bool TraverseAndMatchTemplate(SmtSort template, SmtSort concrete, IDictionary<SmtSort, SmtSort> resolvedParameters)
238+
{
239+
// Template can be a parameter, and concrete can be whatever
240+
if (template.IsSortParameter)
241+
{
242+
if (resolvedParameters.TryGetValue(template, out var resolved))
243+
{
244+
if (resolved != concrete)
245+
{
246+
return false;
247+
}
248+
}
249+
else
250+
{
251+
resolvedParameters.Add(template, concrete);
252+
}
253+
254+
if (template.Arity == 0 && concrete.Arity > 0)
255+
{
256+
return true;
257+
}
258+
}
259+
260+
// Otherwise, arities must match, so we can traverse
261+
if (template.Arity != concrete.Arity)
262+
{
263+
return false;
264+
}
265+
266+
if (template.IsSortParameter)
267+
{
268+
foreach (var (tempParam, concParam) in template.Parameters.Zip(concrete.Parameters))
269+
{
270+
if (!TraverseAndMatchTemplate(tempParam, concParam, resolvedParameters))
271+
{
272+
return false;
273+
}
274+
}
275+
}
276+
else
277+
{
278+
if (template != concrete)
279+
{
280+
return false;
281+
}
282+
}
283+
return true;
284+
}
285+
215286
/// <summary>
216287
/// Returns a string describing available ranks
217288
/// </summary>

Semgus-Lib/Model/Smt/SmtSort.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public SmtSort(SmtSortIdentifier name)
4747
/// <param name="resolved">Resolved parameters. Should have same length as arity</param>
4848
public virtual void UpdateForResolvedParameters(IList<SmtSort> resolved) { }
4949

50+
/// <summary>
51+
/// This sort's parameters
52+
/// </summary>
53+
public virtual IEnumerable<SmtSort> Parameters { get; } = Enumerable.Empty<SmtSort>();
54+
5055
/// <summary>
5156
/// An arbitrary generic sort
5257
/// </summary>

Semgus-Lib/Model/Smt/Theories/SmtArraysExTheory.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ internal sealed class ArraySort : SmtSort
4242
/// </summary>
4343
public SmtSort ValueSort { get; private set; }
4444

45+
/// <summary>
46+
/// This sort's parameters
47+
/// </summary>
48+
public override IEnumerable<SmtSort> Parameters
49+
{
50+
get => new SmtSort[] { IndexSort, ValueSort };
51+
}
52+
4553
/// <summary>
4654
/// Constructs a new array sort with the given parameters
4755
/// </summary>
@@ -55,6 +63,20 @@ private ArraySort(SmtSortIdentifier indexSort, SmtSortIdentifier valueSort) :
5563
Arity = 2;
5664
}
5765

66+
/// <summary>
67+
/// Constructs an array sort with specific sort objects
68+
/// </summary>
69+
/// <param name="indexSort">The sort for the index</param>
70+
/// <param name="valueSort">The sort for the value</param>
71+
internal ArraySort(SmtSort indexSort, SmtSort valueSort)
72+
: base(new(ArraySortPrimaryId, indexSort.Name, valueSort.Name))
73+
{
74+
IndexSort = indexSort;
75+
ValueSort = valueSort;
76+
IsSortParameter = indexSort.IsSortParameter || valueSort.IsSortParameter;
77+
Arity = 2;
78+
}
79+
5880
/// <summary>
5981
/// Gets the array sort for the given index and value sorts
6082
/// </summary>
@@ -117,8 +139,12 @@ public override void UpdateForResolvedParameters(IList<SmtSort> resolved)
117139
private SmtArraysExTheory()
118140
{
119141
SmtSourceBuilder sb = new(this);
120-
sb.AddOnTheFlyFn("select");
121-
sb.AddOnTheFlyFn("store");
142+
var usf = new SmtSort.UniqueSortFactory();
143+
var valueSort = usf.Next();
144+
var indexSort = usf.Next();
145+
var arraySort = new ArraySort(indexSort, valueSort);
146+
sb.AddFn("select", valueSort, arraySort, indexSort);
147+
sb.AddFn("store", arraySort, arraySort, indexSort, valueSort);
122148

123149
Functions = sb.Functions;
124150
PrimaryFunctionSymbols = sb.PrimaryFunctionSymbols;

0 commit comments

Comments
 (0)