Skip to content

Commit b5e6ccc

Browse files
authored
Merge pull request #118 from SemGuS-git/kjcjohnson/sexpr-term-annotations
Add option for term annotations in s-expression format
2 parents 8956eeb + 25b5082 commit b5e6ccc

7 files changed

Lines changed: 213 additions & 69 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
--format
2+
sexpr
3+
--term-annotations
4+
--
5+
data/perfect-prop-3a.sem

IntegrationTests/tests/test-sexpr-annotations.txt

Lines changed: 50 additions & 0 deletions
Large diffs are not rendered by default.

SemgusParser/HandlerFlags.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ private HandlerFlags(InvocationContext ctx, HandlerFlagsFactory fac)
4444
/// </summary>
4545
public bool LegacySymbols => _fac.LegacySymbols.GetFlag(_ctx);
4646

47+
/// <summary>
48+
/// Whether or not the S-expression format should include term annotations
49+
/// </summary>
50+
public bool TermAnnotations => _fac.TermAnnotations.GetFlag(_ctx);
51+
4752
/// <summary>
4853
/// Class for configuring and creating handler flags
4954
/// </summary>
@@ -59,6 +64,11 @@ public class HandlerFlagsFactory
5964
/// </summary>
6065
public readonly CommandFlag LegacySymbols = new("legacy-symbols", defaultValue: true, isHidden: true);
6166

67+
/// <summary>
68+
/// Whether or not to output term annotations for the S-expression output
69+
/// </summary>
70+
public readonly CommandFlag TermAnnotations = new("term-annotations", defaultValue: false, isHidden: true);
71+
6272
/// <summary>
6373
/// Creates a new HandlerFlagsFactory and configures it for the given command
6474
/// </summary>
@@ -67,6 +77,7 @@ public HandlerFlagsFactory(Command command)
6777
{
6878
command.AddFlag(FunctionEvents);
6979
command.AddFlag(LegacySymbols);
80+
command.AddFlag(TermAnnotations);
7081
}
7182

7283
/// <summary>

SemgusParser/Program.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ private static SemgusParser GetParser(string input, bool test, out string friend
228228
break;
229229

230230
case OutputFormat.Sexpr:
231-
handler = new SexprHandler(writer);
231+
handler = new SexprHandler(writer, hf);
232232
break;
233233

234234
default:

SemgusParser/Sexpr/SexprHandler.cs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,20 @@ internal class SexprHandler : ISemgusProblemHandler
1717
{
1818
private readonly ISexprWriter _sw;
1919

20-
public SexprHandler(TextWriter writer)
20+
/// <summary>
21+
/// Flags for the processing
22+
/// </summary>
23+
private readonly HandlerFlags _flags;
24+
25+
/// <summary>
26+
/// Creates a new S-expression handler for the given writer and options
27+
/// </summary>
28+
/// <param name="writer">Underlying s-expression writer</param>
29+
/// <param name="flags">Processing flags</param>
30+
public SexprHandler(TextWriter writer, HandlerFlags flags)
2131
{
2232
_sw = new SexprWriter(writer);
33+
_flags = flags;
2334
}
2435

2536
public void OnCheckSynth(SmtContext smtCtx, SemgusContext semgusCtx)
@@ -53,7 +64,7 @@ public void OnCheckSynth(SmtContext smtCtx, SemgusContext semgusCtx)
5364
_sw.WriteKeyword("symbols");
5465
_sw.Write(chc.Symbols);
5566
_sw.WriteKeyword("constraint");
56-
_sw.Write(chc.Constraint);
67+
_sw.Write(chc.Constraint, _flags.TermAnnotations);
5768
_sw.WriteKeyword("constructor");
5869
_sw.WriteConstructor(chc.Binder);
5970
});
@@ -69,7 +80,7 @@ public void OnCheckSynth(SmtContext smtCtx, SemgusContext semgusCtx)
6980
_sw.WriteList(() =>
7081
{
7182
_sw.WriteSymbol("constraint");
72-
_sw.Write(constraint);
83+
_sw.Write(constraint, _flags.TermAnnotations);
7384
});
7485
}
7586

@@ -145,7 +156,7 @@ public void OnFunctionDefinition(SmtContext ctx, SmtFunction function, SmtFuncti
145156
_sw.WriteKeyword("rank");
146157
_sw.Write(rank);
147158
_sw.WriteKeyword("definition");
148-
_sw.Write(lambda);
159+
_sw.Write(lambda, _flags.TermAnnotations);
149160
});
150161
}
151162

SemgusParser/Sexpr/SexprWriterExtensions.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ public static void WriteConstructor(this ISexprWriter writer, SmtMatchBinder bin
130130
/// </summary>
131131
/// <param name="writer">Writer to write to</param>
132132
/// <param name="term">Term to write</param>
133-
public static void Write(this ISexprWriter writer, SmtTerm term)
133+
public static void Write(this ISexprWriter writer, SmtTerm term, bool includeTermAnnotations)
134134
{
135135
writer.WriteList(() =>
136136
{
137137
writer.WriteSymbol("term");
138-
term.Accept(new SmtTermWriter(writer));
138+
term.Accept(new SmtTermWriter(writer, includeTermAnnotations));
139139
});
140140
}
141141

@@ -284,7 +284,7 @@ public static void Write(this ISexprWriter sw, SmtAttributeValue attrval)
284284
sw.WriteKeyword(attrval.KeywordValue!.Name);
285285
break;
286286
case SmtAttributeValue.AttributeType.Literal:
287-
sw.Write(attrval.LiteralValue!);
287+
sw.Write(attrval.LiteralValue!, includeTermAnnotations: false);
288288
break;
289289
case SmtAttributeValue.AttributeType.List:
290290
sw.WriteList(attrval.ListValue!, se => sw.Write(se));

SemgusParser/Sexpr/SmtTermWriter.cs

Lines changed: 128 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -11,80 +11,138 @@ namespace Semgus.Parser.Sexpr
1111
{
1212
internal class SmtTermWriter : ISmtTermVisitor<ISexprWriter>
1313
{
14+
/// <summary>
15+
/// The writer to write with
16+
/// </summary>
1417
private readonly ISexprWriter _sw;
1518

16-
public SmtTermWriter(ISexprWriter sw)
19+
/// <summary>
20+
/// Whether or not to include term annotations
21+
/// </summary>
22+
private readonly bool _includeTermAnnotations;
23+
24+
/// <summary>
25+
/// Creates a new SmtTermWriter
26+
/// </summary>
27+
/// <param name="sw">The underlying S-expression writer</param>
28+
/// <param name="includeTermAnnotations">Whether or not annotations should be included on terms</param>
29+
public SmtTermWriter(ISexprWriter sw, bool includeTermAnnotations)
1730
{
1831
_sw = sw;
32+
_includeTermAnnotations = includeTermAnnotations;
33+
}
34+
35+
/// <summary>
36+
/// Wraps an annotation block around the current term, if necessary
37+
/// </summary>
38+
/// <param name="term">Term to write annotations for, if any</param>
39+
/// <param name="inner">Action to call for writing the term</param>
40+
private void MaybeWriteAnnotations(SmtTerm term, Action inner)
41+
{
42+
if (_includeTermAnnotations && term.Annotations != null && term.Annotations.Count > 0)
43+
{
44+
_sw.WriteList(() =>
45+
{
46+
_sw.WriteSymbol("annotated");
47+
inner();
48+
foreach (var ann in term.Annotations)
49+
{
50+
_sw.WriteString(ann.Keyword.Name);
51+
_sw.Write(ann.Value);
52+
}
53+
});
54+
}
55+
else
56+
{
57+
inner();
58+
}
1959
}
2060

2161
public ISexprWriter VisitBitVectorLiteral(SmtBitVectorLiteral bitVectorLiteral)
2262
{
23-
_sw.WriteBitVector(bitVectorLiteral.Value);
63+
MaybeWriteAnnotations(bitVectorLiteral, () =>
64+
{
65+
_sw.WriteBitVector(bitVectorLiteral.Value);
66+
});
2467
return _sw;
2568
}
2669

2770
public ISexprWriter VisitDecimalLiteral(SmtDecimalLiteral decimalLiteral)
2871
{
29-
_sw.WriteDecimal(decimalLiteral.Value);
72+
MaybeWriteAnnotations(decimalLiteral, () =>
73+
{
74+
_sw.WriteDecimal(decimalLiteral.Value);
75+
});
3076
return _sw;
3177
}
3278

3379
public ISexprWriter VisitExistsBinder(SmtExistsBinder existsBinder)
3480
{
35-
_sw.WriteList(() =>
81+
MaybeWriteAnnotations(existsBinder, () =>
3682
{
37-
_sw.WriteSymbol("exists");
38-
_sw.WriteKeyword("bindings");
39-
_sw.WriteList(existsBinder.NewScope.LocalBindings, b => _sw.Write(b.Id));
40-
_sw.WriteKeyword("binding-sorts");
41-
_sw.WriteList(existsBinder.NewScope.LocalBindings, b => _sw.Write(b.Sort.Name));
42-
_sw.WriteKeyword("child");
43-
existsBinder.Child.Accept(this);
83+
_sw.WriteList(() =>
84+
{
85+
_sw.WriteSymbol("exists");
86+
_sw.WriteKeyword("bindings");
87+
_sw.WriteList(existsBinder.NewScope.LocalBindings, b => _sw.Write(b.Id));
88+
_sw.WriteKeyword("binding-sorts");
89+
_sw.WriteList(existsBinder.NewScope.LocalBindings, b => _sw.Write(b.Sort.Name));
90+
_sw.WriteKeyword("child");
91+
existsBinder.Child.Accept(this);
92+
});
4493
});
4594
return _sw;
4695
}
4796

4897
public ISexprWriter VisitForallBinder(SmtForallBinder forallBinder)
4998
{
50-
_sw.WriteList(() =>
99+
MaybeWriteAnnotations(forallBinder, () =>
51100
{
52-
_sw.WriteSymbol("forall");
53-
_sw.WriteKeyword("bindings");
54-
_sw.WriteList(forallBinder.NewScope.LocalBindings, b => _sw.Write(b.Id));
55-
_sw.WriteKeyword("binding-sorts");
56-
_sw.WriteList(forallBinder.NewScope.LocalBindings, b => _sw.Write(b.Sort.Name));
57-
_sw.WriteKeyword("child");
58-
forallBinder.Child.Accept(this);
101+
_sw.WriteList(() =>
102+
{
103+
_sw.WriteSymbol("forall");
104+
_sw.WriteKeyword("bindings");
105+
_sw.WriteList(forallBinder.NewScope.LocalBindings, b => _sw.Write(b.Id));
106+
_sw.WriteKeyword("binding-sorts");
107+
_sw.WriteList(forallBinder.NewScope.LocalBindings, b => _sw.Write(b.Sort.Name));
108+
_sw.WriteKeyword("child");
109+
forallBinder.Child.Accept(this);
110+
});
59111
});
60112
return _sw;
61113
}
62114

63115
public ISexprWriter VisitFunctionApplication(SmtFunctionApplication functionApplication)
64116
{
65-
_sw.WriteList(() =>
117+
MaybeWriteAnnotations(functionApplication, () =>
66118
{
67-
_sw.WriteSymbol("application");
68-
_sw.Write(functionApplication.Definition.Name);
69-
_sw.WriteKeyword("argument-sorts");
70-
_sw.WriteList(functionApplication.Rank.ArgumentSorts, s => _sw.Write(s.Name));
71-
_sw.WriteKeyword("arguments");
72-
_sw.WriteList(functionApplication.Arguments, a => a.Accept(this));
73-
_sw.WriteKeyword("return-sort");
74-
_sw.Write(functionApplication.Rank.ReturnSort.Name);
119+
_sw.WriteList(() =>
120+
{
121+
_sw.WriteSymbol("application");
122+
_sw.Write(functionApplication.Definition.Name);
123+
_sw.WriteKeyword("argument-sorts");
124+
_sw.WriteList(functionApplication.Rank.ArgumentSorts, s => _sw.Write(s.Name));
125+
_sw.WriteKeyword("arguments");
126+
_sw.WriteList(functionApplication.Arguments, a => a.Accept(this));
127+
_sw.WriteKeyword("return-sort");
128+
_sw.Write(functionApplication.Rank.ReturnSort.Name);
129+
});
75130
});
76131
return _sw;
77132
}
78133

79134
public ISexprWriter VisitLambdaBinder(SmtLambdaBinder lambdaBinder)
80135
{
81-
_sw.WriteList(() =>
136+
MaybeWriteAnnotations(lambdaBinder, () =>
82137
{
83-
_sw.WriteSymbol("lambda");
84-
_sw.WriteKeyword("arguments");
85-
_sw.WriteList(lambdaBinder.ArgumentNames, an => _sw.Write(an));
86-
_sw.WriteKeyword("body");
87-
lambdaBinder.Child.Accept(this);
138+
_sw.WriteList(() =>
139+
{
140+
_sw.WriteSymbol("lambda");
141+
_sw.WriteKeyword("arguments");
142+
_sw.WriteList(lambdaBinder.ArgumentNames, an => _sw.Write(an));
143+
_sw.WriteKeyword("body");
144+
lambdaBinder.Child.Accept(this);
145+
});
88146
});
89147
return _sw;
90148
}
@@ -96,59 +154,68 @@ public ISexprWriter VisitLetBinder(SmtLetBinder letBinder)
96154

97155
public ISexprWriter VisitMatchBinder(SmtMatchBinder matchBinder)
98156
{
99-
_sw.WriteList(() =>
157+
MaybeWriteAnnotations(matchBinder, () =>
100158
{
101-
_sw.WriteSymbol("binder");
102-
_sw.WriteKeyword("operator");
103-
if (matchBinder.Constructor is null)
104-
{
105-
_sw.WriteNil();
106-
}
107-
else
159+
_sw.WriteList(() =>
108160
{
109-
_sw.Write(matchBinder.Constructor.Name);
110-
}
111-
_sw.WriteKeyword("arguments");
112-
_sw.WriteList(matchBinder.Bindings, b => _sw.Write(b.Binding.Id));
113-
_sw.WriteKeyword("child");
114-
matchBinder.Child.Accept(this);
161+
_sw.WriteSymbol("binder");
162+
_sw.WriteKeyword("operator");
163+
if (matchBinder.Constructor is null)
164+
{
165+
_sw.WriteNil();
166+
}
167+
else
168+
{
169+
_sw.Write(matchBinder.Constructor.Name);
170+
}
171+
_sw.WriteKeyword("arguments");
172+
_sw.WriteList(matchBinder.Bindings, b => _sw.Write(b.Binding.Id));
173+
_sw.WriteKeyword("child");
174+
matchBinder.Child.Accept(this);
175+
});
115176
});
116177
return _sw;
117178
}
118179

119180
public ISexprWriter VisitMatchGrouper(SmtMatchGrouper matchGrouper)
120181
{
121-
_sw.WriteList(() =>
182+
MaybeWriteAnnotations(matchGrouper, () =>
122183
{
123-
_sw.WriteSymbol("match");
124-
_sw.WriteKeyword("term");
125-
matchGrouper.Term.Accept(this);
126-
_sw.WriteKeyword("binders");
127-
_sw.WriteList(matchGrouper.Binders, b => b.Accept(this));
184+
_sw.WriteList(() =>
185+
{
186+
_sw.WriteSymbol("match");
187+
_sw.WriteKeyword("term");
188+
matchGrouper.Term.Accept(this);
189+
_sw.WriteKeyword("binders");
190+
_sw.WriteList(matchGrouper.Binders, b => b.Accept(this));
191+
});
128192
});
129193
return _sw;
130194
}
131195

132196
public ISexprWriter VisitNumeralLiteral(SmtNumeralLiteral numeralLiteral)
133197
{
134-
_sw.WriteNumeral(numeralLiteral.Value);
198+
MaybeWriteAnnotations(numeralLiteral, () => { _sw.WriteNumeral(numeralLiteral.Value); });
135199
return _sw;
136200
}
137201

138202
public ISexprWriter VisitStringLiteral(SmtStringLiteral stringLiteral)
139203
{
140-
_sw.WriteString(stringLiteral.Value);
204+
MaybeWriteAnnotations(stringLiteral, () => { _sw.WriteString(stringLiteral.Value); });
141205
return _sw;
142206
}
143207

144208
public ISexprWriter VisitVariable(SmtVariable variable)
145209
{
146-
_sw.WriteList(() =>
210+
MaybeWriteAnnotations(variable, () =>
147211
{
148-
_sw.WriteSymbol("variable");
149-
_sw.Write(variable.Name);
150-
_sw.WriteKeyword("sort");
151-
_sw.Write(variable.Sort.Name);
212+
_sw.WriteList(() =>
213+
{
214+
_sw.WriteSymbol("variable");
215+
_sw.Write(variable.Name);
216+
_sw.WriteKeyword("sort");
217+
_sw.Write(variable.Sort.Name);
218+
});
152219
});
153220
return _sw;
154221
}

0 commit comments

Comments
 (0)