From 580efdcaef4a3b22ee088c504e684b28b4bf27bd Mon Sep 17 00:00:00 2001 From: Markus Alexander Kuppe Date: Wed, 11 Oct 2023 14:03:14 -0700 Subject: [PATCH] Add Java module override for SequencesExt!Suffixes --- modules/tlc2/overrides/SequencesExt.java | 35 ++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/modules/tlc2/overrides/SequencesExt.java b/modules/tlc2/overrides/SequencesExt.java index e8fd683..cda42aa 100644 --- a/modules/tlc2/overrides/SequencesExt.java +++ b/modules/tlc2/overrides/SequencesExt.java @@ -535,4 +535,39 @@ public static Value SelectLastInSubSeq(final Value s, final Value f, final Value } return IntValue.ValZero; } + + /* + Suffixes(s) == + (**************************************************************************) + (* The set of suffixes of the sequence s, including the empty sequence. *) + (**************************************************************************) + { SubSeq(s, l, Len(s)) : l \in 1..Len(s) } \cup {<<>>} + */ + @TLAPlusOperator(identifier = "Suffixes", module = "SequencesExt", warn = false) + public static Value Suffixes(final Value s) { + final TupleValue seq = (TupleValue) s.toTuple(); + if (seq == null) { + throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR, + new String[] { "first", "Suffixes", "sequence", Values.ppr(s.toString()) }); + } + + final Value[] vals = new Value[seq.elems.length + 1]; + + // \cup {<<>>} + vals[0] = TupleValue.EmptyTuple; + + // Add the elements in reverse order to implicitly normalize the SetEnumValue. + for (int i = seq.elems.length - 1; i >= 0; i--) { + final Value[] suffix = new Value[seq.elems.length - i]; + System.arraycopy(seq.elems, i, suffix, 0, seq.elems.length - i); + + vals[seq.elems.length - i] = new TupleValue(suffix); + } + + // Decided against calling "normalize" as a safeguard, even though "vals" will + // be normalized. This is because "normalize," albeit performing a single pass + // over "vals" for a normalized input, still compares elements, which can be + // expensive: return new SetEnumValue(vals, false).normalize(); + return new SetEnumValue(vals, true); + } }