Skip to content

Commit d4a5f45

Browse files
committed
Improve error-messages for bogus inputs to Fold operators.
[Feature]
1 parent 857abc3 commit d4a5f45

File tree

4 files changed

+59
-10
lines changed

4 files changed

+59
-10
lines changed

modules/tlc2/overrides/Functions.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,32 @@ public static Value antiFunction(final Value f) {
107107
}
108108

109109
@TLAPlusOperator(identifier = "FoldFunction", module = "Functions", warn = false)
110-
public static Value foldFunction(final OpValue op, final Value base, final Applicable fun) {
111-
return foldFunctionOnSet(op, base, fun, (Enumerable) fun.getDomain());
110+
public static Value foldFunction(final OpValue op, final Value base, final Value fun) {
111+
// Can assume type of OpValue because tla2sany.semantic.Generator.java will
112+
// make sure that the first parameter is a binary operator.
113+
114+
if (!(fun instanceof Applicable)) {
115+
throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR,
116+
new String[] { "third", "FoldFunction", "function", Values.ppr(fun.toString()) });
117+
}
118+
return foldFunctionOnSet(op, base, fun, ((Applicable) fun).getDomain());
112119
}
113120

114121
@TLAPlusOperator(identifier = "FoldFunctionOnSet", module = "Functions", warn = false)
115-
public static Value foldFunctionOnSet(final OpValue op, final Value base, final Applicable fun, final Enumerable subdomain) {
122+
public static Value foldFunctionOnSet(final OpValue op, final Value base, final Value v3, final Value v4) {
123+
// Can assume type of OpValue because tla2sany.semantic.Generator.java will
124+
// make sure that the first parameter is a binary operator.
125+
126+
if (!(v3 instanceof Applicable)) {
127+
throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR,
128+
new String[] { "third", "FoldFunctionOnSet", "function", Values.ppr(v3.toString()) });
129+
}
130+
final Applicable fun = (Applicable) v3;
131+
if (!(v4 instanceof Enumerable)) {
132+
throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR,
133+
new String[] { "fourth", "FoldFunctionOnSet", "set", Values.ppr(v4.toString()) });
134+
}
135+
final Enumerable subdomain = (Enumerable) v4;
116136

117137
// FoldFunction base is second operand.
118138
final Value[] args = new Value[2];

modules/tlc2/overrides/SequencesExt.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,19 @@ private static Value longestCommonPrefix(final StringValue first, final ValueVec
168168
}
169169

170170
@TLAPlusOperator(identifier = "FoldSeq", module = "SequencesExt", warn = false)
171-
public static Value foldSeq(final OpValue op, final Value base, final TupleValue tv) {
171+
public static Value foldSeq(final OpValue op, final Value base, final Value tv) {
172172
return Functions.foldFunction(op, base, tv);
173173
}
174174

175175
@TLAPlusOperator(identifier = "FoldLeft", module = "SequencesExt", warn = false)
176176
public static Value foldLeft(final OpValue op, final Value base, final Value val) {
177-
177+
// Can assume type of OpValue because tla2sany.semantic.Generator.java will
178+
// make sure that the first parameter is a binary operator.
179+
178180
final TupleValue tv = (TupleValue) val.toTuple();
179181
if (tv == null) {
180-
throw new EvalException(EC.TLC_MODULE_ONE_ARGUMENT_ERROR,
181-
new String[] { "FoldLeft", "sequence", Values.ppr(val.toString()) });
182+
throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR,
183+
new String[] { "third", "FoldLeft", "sequence", Values.ppr(val.toString()) });
182184
}
183185

184186
// FoldLeft base is left (first) operand.
@@ -196,11 +198,13 @@ public static Value foldLeft(final OpValue op, final Value base, final Value val
196198

197199
@TLAPlusOperator(identifier = "FoldRight", module = "SequencesExt", warn = false)
198200
public static Value foldRight(final OpValue op, final Value val, final Value base) {
199-
201+
// Can assume type of OpValue because tla2sany.semantic.Generator.java will
202+
// make sure that the first parameter is a binary operator.
203+
200204
final TupleValue tv = (TupleValue) val.toTuple();
201205
if (tv == null) {
202-
throw new EvalException(EC.TLC_MODULE_ONE_ARGUMENT_ERROR,
203-
new String[] { "FoldRight", "sequence", Values.ppr(val.toString()) });
206+
throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR,
207+
new String[] { "second", "FoldRight", "sequence", Values.ppr(val.toString()) });
204208
}
205209

206210
// FoldRight base is right (second) operand.

tests/FunctionsTests.tla

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ ASSUME FoldFunctionOnSet(LAMBDA x,y: {x} \cup y, {}, [n \in 1..9999 |-> n], {})
4343

4444
ASSUME FoldFunctionOnSet(LAMBDA x,y: {x} \cup y, {}, [n \in 1..9999 |-> n], 2..9998) = 2..9998
4545

46+
ASSUME AssertError(
47+
"The third argument of FoldFunction should be a function, but instead it is:\nTRUE",
48+
FoldFunction(+, 23, TRUE))
49+
50+
ASSUME AssertError(
51+
"The fourth argument of FoldFunctionOnSet should be a set, but instead it is:\nTRUE",
52+
FoldFunctionOnSet(+, 23, <<>>, TRUE))
53+
54+
ASSUME AssertError(
55+
"The third argument of FoldFunctionOnSet should be a function, but instead it is:\nTRUE",
56+
FoldFunctionOnSet(+, 23, TRUE, {}))
57+
4658
\* AntiFunction
4759
ASSUME AntiFunction(<<"a", "b", "c">>) = [a |-> 1, b |-> 2, c |-> 3]
4860

tests/SequencesExtTests.tla

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,19 @@ ASSUME FoldSeq( LAMBDA e, acc: acc + 1, 0, <<1,1,1,1,1>>) = 5
103103
ASSUME FoldLeft( LAMBDA acc, e: acc + 1, 0, <<1,1,1,1,1>>) = 5
104104
ASSUME FoldRight(LAMBDA e, acc: acc + 1, <<1,1,1,1,1>>, 0) = 5
105105

106+
ASSUME AssertError(
107+
"The second argument of FoldRight should be a sequence, but instead it is:\nTRUE",
108+
FoldRight(+, TRUE, 23))
109+
110+
ASSUME AssertError(
111+
"The third argument of FoldLeft should be a sequence, but instead it is:\nTRUE",
112+
FoldLeft(+, 23, TRUE))
113+
114+
\* Error comes from Functions!FoldFunctionOnSet
115+
ASSUME AssertError(
116+
"The third argument of FoldFunction should be a function, but instead it is:\nTRUE",
117+
FoldSeq(+, 23, TRUE))
118+
106119
-----------------------------------------------------------------------------
107120

108121
ASSUME LongestCommonPrefix({<<>>}) = <<>>

0 commit comments

Comments
 (0)