Skip to content

Commit 06a20a6

Browse files
committed
Outline of theory of sequences
1 parent 78de212 commit 06a20a6

3 files changed

Lines changed: 174 additions & 1 deletion

File tree

Semgus-Lib/Model/Smt/SmtCommonIdentifiers.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public static class SmtCommonIdentifiers
1717
public static SmtIdentifier BitVectorsTheoryId { get; } = new("BitVectors");
1818
public static SmtIdentifier BitVectorsExtensionId { get; } = new("BitVectors", "extension");
1919
public static SmtIdentifier ArraysExTheoryId { get; } = new("ArraysEx");
20+
public static SmtIdentifier SequencesTheoryId { get; } = new("Sequences");
2021

2122
public static SmtSortIdentifier BoolSortId { get; } = new("Bool");
2223
public static SmtSortIdentifier IntSortId { get; } = new("Int");
@@ -34,6 +35,7 @@ public SmtSortIdentifier this[int size]
3435
}
3536
}
3637
public static SmtIdentifier ArraySortPrimaryId { get; } = new("Array");
38+
public static SmtIdentifier SeqSortPrimaryId { get; } = new("Seq");
3739

3840
public static SmtIdentifier AndFunctionId { get; } = new("and");
3941
public static SmtIdentifier OrFunctionId { get; } = new("or");

Semgus-Lib/Model/Smt/SmtContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ public SmtContext()
6565
SmtIntsTheory.Instance,
6666
SmtStringsTheory.Instance,
6767
SmtBitVectorsTheory.Instance,
68-
SmtArraysExTheory.Instance
68+
SmtArraysExTheory.Instance,
69+
SmtSequencesTheory.Instance
6970
};
7071

7172
_extensions = new HashSet<ISmtExtension>()
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
using Semgus.Model.Smt.Terms;
2+
3+
using System;
4+
using System.Collections.Generic;
5+
using System.Diagnostics.CodeAnalysis;
6+
using System.Linq;
7+
using System.Text;
8+
using System.Threading.Tasks;
9+
10+
using static Semgus.Model.Smt.SmtCommonIdentifiers;
11+
12+
namespace Semgus.Model.Smt.Theories
13+
{
14+
/// <summary>
15+
/// The (non-standard) theory of sequences
16+
/// https://cvc5.github.io/docs-ci/docs-main/theories/sequences.html
17+
/// </summary>
18+
internal class SmtSequencesTheory : ISmtTheory
19+
{
20+
/// <summary>
21+
/// A singleton theory instance
22+
/// </summary>
23+
public static SmtSequencesTheory Instance { get; } = new();
24+
25+
/// <summary>
26+
/// Underlying sequence sort
27+
/// </summary>
28+
internal sealed class SeqSort : SmtSort
29+
{
30+
/// <summary>
31+
/// Cache of instantiated sorts. We need this since sorts are compared by reference
32+
/// </summary>
33+
private static readonly IDictionary<SmtSortIdentifier, SeqSort> _sortCache
34+
= new Dictionary<SmtSortIdentifier, SeqSort>();
35+
36+
/// <summary>
37+
/// The sort used for the sequence element values
38+
/// </summary>
39+
public SmtSort ElementSort { get; private set; }
40+
41+
/// <summary>
42+
/// This sort's parameters
43+
/// </summary>
44+
public override IEnumerable<SmtSort> Parameters
45+
{
46+
get => new SmtSort[] { ElementSort };
47+
}
48+
49+
/// <summary>
50+
/// Constructs a new seq sort with the given element type
51+
/// </summary>
52+
/// <param name="elementSort">Sort for sequence elements</param>
53+
private SeqSort(SmtSortIdentifier elementSort) :
54+
base(new(new SmtIdentifier(SeqSortPrimaryId.Symbol), elementSort))
55+
{
56+
ElementSort = new UnresolvedParameterSort(elementSort);
57+
IsParametric = true;
58+
Arity = 1;
59+
}
60+
61+
/// <summary>
62+
/// Constructs a new seq sort with the given (possibly concrete) element type
63+
/// </summary>
64+
/// <param name="elementSort">Sort for sequence elements</param>
65+
internal SeqSort(SmtSort elementSort)
66+
: base(new(SeqSortPrimaryId, elementSort.Name))
67+
{
68+
ElementSort = elementSort;
69+
IsSortParameter = elementSort.IsSortParameter;
70+
Arity = 1;
71+
}
72+
73+
/// <summary>
74+
/// Gets the seq sort for the given element sort
75+
/// </summary>
76+
/// <param name="element">The id of the element sort</param>
77+
/// <returns>The seq sort for the given element sort</returns>
78+
public static SeqSort GetSort(SmtSortIdentifier element)
79+
{
80+
if (_sortCache.TryGetValue(element, out SeqSort? sort))
81+
{
82+
return sort;
83+
}
84+
else
85+
{
86+
sort = new SeqSort(element);
87+
_sortCache.Add(element, sort);
88+
return sort;
89+
}
90+
}
91+
92+
/// <summary>
93+
/// Updates this sort with the resolved parameteric sorts
94+
/// </summary>
95+
/// <param name="resolved">Resolved parameters. Must have arity 1</param>
96+
public override void UpdateForResolvedParameters(IList<SmtSort> resolved)
97+
{
98+
if (resolved.Count != 1)
99+
{
100+
throw new InvalidOperationException("Got list of resolved sorts not of length 1!");
101+
}
102+
103+
ElementSort = resolved[0];
104+
}
105+
}
106+
107+
/// <summary>
108+
/// This theory's name
109+
/// </summary>
110+
public SmtIdentifier Name { get; } = SequencesTheoryId;
111+
112+
#region Deprecated
113+
public IReadOnlyDictionary<SmtIdentifier, IApplicable> Functions { get; }
114+
#endregion
115+
116+
/// <summary>
117+
/// The primary (i.e., non-indexed) sort symbols (e.g., "Seq")
118+
/// </summary>
119+
public IReadOnlySet<SmtIdentifier> PrimarySortSymbols { get; }
120+
121+
/// <summary>
122+
/// The primary (i.e., non-indexed) function symbols
123+
/// </summary>
124+
public IReadOnlySet<SmtIdentifier> PrimaryFunctionSymbols { get; }
125+
126+
/// <summary>
127+
/// Constructs an instance of the theory of sequences
128+
/// </summary>
129+
/// <param name="core">Reference to the core theory</param>
130+
private SmtSequencesTheory()
131+
{
132+
SmtSourceBuilder sb = new(this);
133+
var usf = new SmtSort.UniqueSortFactory();
134+
var elementSort = usf.Next();
135+
var seqSort = new SeqSort(elementSort);
136+
137+
Functions = sb.Functions;
138+
PrimaryFunctionSymbols = sb.PrimaryFunctionSymbols;
139+
PrimarySortSymbols = new HashSet<SmtIdentifier>() { SeqSortPrimaryId };
140+
}
141+
142+
/// <summary>
143+
/// Looks up a sort symbol in this theory
144+
/// </summary>
145+
/// <param name="sortId">The sort ID</param>
146+
/// <param name="resolvedSort">The resolved sort</param>
147+
/// <returns>True if successfully gotten</returns>
148+
public bool TryGetSort(SmtSortIdentifier sortId, [NotNullWhen(true)] out SmtSort? resolvedSort)
149+
{
150+
if (sortId.Arity == 1 && sortId.Name == SeqSortPrimaryId)
151+
{
152+
resolvedSort = SeqSort.GetSort(sortId.Parameters[0]);
153+
return true;
154+
}
155+
resolvedSort = default;
156+
return false;
157+
}
158+
159+
/// <summary>
160+
/// Looks up a function in this theory
161+
/// </summary>
162+
/// <param name="functionId">The function ID to look up</param>
163+
/// <param name="resolvedFunction">The resolved function</param>
164+
/// <returns>True if successfully gotten</returns>
165+
public bool TryGetFunction(SmtIdentifier functionId, [NotNullWhen(true)] out IApplicable? resolvedFunction)
166+
{
167+
return Functions.TryGetValue(functionId, out resolvedFunction);
168+
}
169+
}
170+
}

0 commit comments

Comments
 (0)