@@ -535,4 +535,39 @@ public static Value SelectLastInSubSeq(final Value s, final Value f, final Value
535535 }
536536 return IntValue .ValZero ;
537537 }
538+
539+ /*
540+ Suffixes(s) ==
541+ (**************************************************************************)
542+ (* The set of suffixes of the sequence s, including the empty sequence. *)
543+ (**************************************************************************)
544+ { SubSeq(s, l, Len(s)) : l \in 1..Len(s) } \cup {<<>>}
545+ */
546+ @ TLAPlusOperator (identifier = "Suffixes" , module = "SequencesExt" , warn = false )
547+ public static Value Suffixes (final Value s ) {
548+ final TupleValue seq = (TupleValue ) s .toTuple ();
549+ if (seq == null ) {
550+ throw new EvalException (EC .TLC_MODULE_ARGUMENT_ERROR ,
551+ new String [] { "first" , "Suffixes" , "sequence" , Values .ppr (s .toString ()) });
552+ }
553+
554+ final Value [] vals = new Value [seq .elems .length + 1 ];
555+
556+ // \cup {<<>>}
557+ vals [0 ] = TupleValue .EmptyTuple ;
558+
559+ // Add the elements in reverse order to implicitly normalize the SetEnumValue.
560+ for (int i = seq .elems .length - 1 ; i >= 0 ; i --) {
561+ final Value [] suffix = new Value [seq .elems .length - i ];
562+ System .arraycopy (seq .elems , i , suffix , 0 , seq .elems .length - i );
563+
564+ vals [seq .elems .length - i ] = new TupleValue (suffix );
565+ }
566+
567+ // Decided against calling "normalize" as a safeguard, even though "vals" will
568+ // be normalized. This is because "normalize," albeit performing a single pass
569+ // over "vals" for a normalized input, still compares elements, which can be
570+ // expensive: return new SetEnumValue(vals, false).normalize();
571+ return new SetEnumValue (vals , true );
572+ }
538573}
0 commit comments