|
25 | 25 | * Markus Alexander Kuppe - initial API and implementation |
26 | 26 | ******************************************************************************/ |
27 | 27 |
|
| 28 | +import java.util.ArrayList; |
| 29 | + |
28 | 30 | import org.apache.commons.lang3.StringUtils; |
29 | 31 |
|
30 | 32 | import tla2sany.semantic.ExprOrOpArgNode; |
@@ -535,6 +537,64 @@ public static Value SelectLastInSubSeq(final Value s, final Value f, final Value |
535 | 537 | } |
536 | 538 | return IntValue.ValZero; |
537 | 539 | } |
| 540 | + |
| 541 | + @TLAPlusOperator(identifier = "RemoveFirst", module = "SequencesExt", warn = false) |
| 542 | + public static Value removeFirst(final Value s, final Value e) { |
| 543 | + final TupleValue seq = (TupleValue) s.toTuple(); |
| 544 | + if (seq == null) { |
| 545 | + throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR, |
| 546 | + new String[] { "first", "RemoveFirst", "sequence", Values.ppr(s.toString()) }); |
| 547 | + } |
| 548 | + |
| 549 | + final ArrayList<Value> val = new ArrayList<>(seq.elems.length); |
| 550 | + |
| 551 | + boolean found = false; |
| 552 | + for (int i = 0; i < seq.elems.length; i++) { |
| 553 | + if (!found && seq.elems[i].equals(e)) { |
| 554 | + found = true; |
| 555 | + } else { |
| 556 | + val.add(seq.elems[i]); |
| 557 | + } |
| 558 | + } |
| 559 | + |
| 560 | + return new TupleValue(val.toArray(Value[]::new)); |
| 561 | + } |
| 562 | + |
| 563 | + @TLAPlusOperator(identifier = "RemoveFirstMatch", module = "SequencesExt", warn = false) |
| 564 | + public static Value removeFirstMatch(final Value s, final Value test) { |
| 565 | + final TupleValue seq = (TupleValue) s.toTuple(); |
| 566 | + if (seq == null) { |
| 567 | + throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR, |
| 568 | + new String[] { "first", "RemoveFirstMatch", "sequence", Values.ppr(s.toString()) }); |
| 569 | + } |
| 570 | + if (!(test instanceof Applicable)) { |
| 571 | + throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR, |
| 572 | + new String[] { "second", "RemoveFirstMatch", "function", Values.ppr(test.toString()) }); |
| 573 | + } |
| 574 | + final Applicable ftest = (Applicable) test; |
| 575 | + final Value[] args = new Value[1]; |
| 576 | + |
| 577 | + final ArrayList<Value> val = new ArrayList<>(seq.elems.length); |
| 578 | + |
| 579 | + boolean found = false; |
| 580 | + for (int i = 0; i < seq.elems.length; i++) { |
| 581 | + if (!found) { |
| 582 | + args[0] = seq.elems[i]; |
| 583 | + final Value bval = ftest.apply(args, EvalControl.Clear); |
| 584 | + if (!(bval instanceof IBoolValue)) { |
| 585 | + throw new EvalException(EC.TLC_MODULE_ARGUMENT_ERROR, new String[] { "second", "RemoveFirstMatch", |
| 586 | + "boolean-valued function", Values.ppr(test.toString()) }); |
| 587 | + } |
| 588 | + if (((BoolValue) bval).val) { |
| 589 | + found = true; |
| 590 | + continue; |
| 591 | + } |
| 592 | + } |
| 593 | + val.add(seq.elems[i]); |
| 594 | + } |
| 595 | + |
| 596 | + return new TupleValue(val.toArray(Value[]::new)); |
| 597 | + } |
538 | 598 |
|
539 | 599 | /* |
540 | 600 | Suffixes(s) == |
|
0 commit comments