@@ -192,6 +192,8 @@ private bool TryResolveRank(SmtContext ctx, [NotNullWhen(true)] out SmtFunctionR
192192 var retSort = template . ReturnSort ;
193193 if ( retSort . IsSortParameter )
194194 {
195+ TraverseAndResolveTemplate ( ctx , retSort , resolvedParameters , out _ ) ;
196+
195197 if ( resolvedParameters . TryGetValue ( retSort , out SmtSort ? resRetSort ) )
196198 {
197199 // Case: the return value is a parameter we know about
@@ -229,6 +231,54 @@ private bool TryResolveRank(SmtContext ctx, [NotNullWhen(true)] out SmtFunctionR
229231 return template . Validator ( rank ) ;
230232 }
231233
234+ /// <summary>
235+ /// Traverses the template and resolves parameters inside it, from already resolved pieces
236+ /// </summary>
237+ /// <param name="ctx">The SMT context</param>
238+ /// <param name="template">The template to match</param>
239+ /// <param name="resolvedParameters">Dictionary of templates to resolved parameters</param>
240+ /// <param name="resolved">The resolved sort</param>
241+ /// <returns>True if successfully resolved</returns>
242+ internal static bool TraverseAndResolveTemplate ( SmtContext ctx , SmtSort template , IDictionary < SmtSort , SmtSort > resolvedParameters , [ NotNullWhen ( true ) ] out SmtSort ? resolved )
243+ {
244+ if ( ! template . IsSortParameter )
245+ {
246+ resolved = template ;
247+ return true ;
248+ }
249+ else if ( resolvedParameters . TryGetValue ( template , out resolved ) )
250+ {
251+ return true ;
252+ }
253+ else if ( template . Arity == 0 )
254+ {
255+ // An unresolved parameter! Resolution failed.
256+ resolved = default ;
257+ return false ;
258+ }
259+ else
260+ {
261+ List < SmtSortIdentifier > paramIds = new ( ) ;
262+ foreach ( var parameter in template . Parameters )
263+ {
264+ if ( ! TraverseAndResolveTemplate ( ctx , parameter , resolvedParameters , out resolved ) )
265+ {
266+ resolved = default ;
267+ return false ;
268+ }
269+ paramIds . Add ( resolved . Name ) ;
270+ }
271+ if ( ! ctx . TryGetSortDeclaration ( new ( template . Name . Name , paramIds . ToArray ( ) ) , out var sort , out string ? _ ) )
272+ {
273+ resolved = default ;
274+ return false ;
275+ }
276+ resolvedParameters . Add ( template , sort ) ;
277+ resolved = sort ;
278+ return true ;
279+ }
280+ }
281+
232282 /// <summary>
233283 /// Match a template sort and parameters against a concrete sort
234284 /// </summary>
0 commit comments