From 486f6e370a61f72d9db347a10572cfdeb9945ac7 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 9 Jan 2024 23:01:12 +0100 Subject: [PATCH 01/73] move utility method from ProofIrrelevancyProperty to new dedicated class EqualityUtils and make it more general --- .../key/logic/equality/EqualityUtils.java | 33 +++++++++++++++++++ .../equality/ProofIrrelevancyProperty.java | 31 ++--------------- 2 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java new file mode 100644 index 00000000000..37d80cc1629 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java @@ -0,0 +1,33 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.logic.equality; + +import de.uka.ilkd.key.logic.Term; + +public class EqualityUtils { + + /** + * Computes the hashcode of an iterable of terms modulo a given property using the elements' + * {@link TermEqualsModProperty} implementation. + * + * @param iter iterable of terms + * @return combined hashcode + */ + public static int hashCodeModPropertyOfIterable(TermProperty property, + Iterable iter) { + // adapted from Arrays.hashCode + if (iter == null) { + return 0; + } + + int result = 1; + + for (Term element : iter) { + result = 31 * result + (element == null ? 0 + : element.hashCodeModProperty(property)); + } + + return result; + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index f652c25f1c0..a600ae7aa87 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -113,7 +113,9 @@ public int hashCodeModThisProperty(Term term) { // part from TermImpl if (hashcode2 == -1) { // compute into local variable first to be thread-safe. - hashcode2 = Objects.hash(term.op(), hashCodeIterable(term.subs()), + hashcode2 = Objects.hash(term.op(), + EqualityUtils.hashCodeModPropertyOfIterable(PROOF_IRRELEVANCY_PROPERTY, + term.subs()), EqualsModProofIrrelevancyUtil.hashCodeIterable(term.boundVars()), term.javaBlock()); if (hashcode2 == -1) { hashcode2 = 0; @@ -129,32 +131,5 @@ public int hashCodeModThisProperty(Term term) { } } return hashcode2; - // throw new UnsupportedOperationException( - // "Hashing of terms modulo term proof-irrelevancy not yet implemented!"); - } - - // -------------------------- Utility methods --------------------------------- // - - /** - * Compute the hashcode mod proof irrelevancy of an iterable of terms using the elements' - * {@link TermEqualsModProperty} implementation. - * - * @param iter iterable of terms - * @return combined hashcode - */ - public static int hashCodeIterable(Iterable iter) { - // adapted from Arrays.hashCode - if (iter == null) { - return 0; - } - - int result = 1; - - for (Term element : iter) { - result = 31 * result + (element == null ? 0 - : element.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY)); - } - - return result; } } From 756d79c820cef5a7410c6bd43e3e47043e0f157a Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 9 Jan 2024 23:03:25 +0100 Subject: [PATCH 02/73] add implementations to hashCodeModProperty for IrrelevantTermLabelsProperty and TermLabelsProperty --- .../IrrelevantTermLabelsProperty.java | 28 +++++++++++++++++-- .../logic/equality/RenamingTermProperty.java | 6 ++++ .../logic/equality/TermLabelsProperty.java | 22 +++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 96d77707260..181cdbe485d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -80,9 +80,33 @@ public Boolean equalsModThisProperty(Term term, Object o) { return true; } + /** + * Computes the hash code of {@code term} while ignoring irrelevant labels. + * + * @param term the term to compute the hash code for + * @return the hash code + */ @Override public int hashCodeModThisProperty(Term term) { - throw new UnsupportedOperationException( - "Hashing of terms modulo irrelevant term labels not yet implemented!"); + // change 5 and 17 not to match TermImpl's implementation too much? + int hashcode = 5; + hashcode = hashcode * 17 + term.op().hashCode(); + hashcode = hashcode * 17 + EqualityUtils + .hashCodeModPropertyOfIterable(IRRELEVANT_TERM_LABELS_PROPERTY, term.subs()); + hashcode = hashcode * 17 + term.boundVars().hashCode(); + hashcode = hashcode * 17 + term.javaBlock().hashCode(); + + for (TermLabel label : term.getLabels()) { + hashcode += (label.isProofRelevant() ? 7 * label.hashCode() : 0); + } + +// final ImmutableArray termLabels = term.getLabels(); +// for (int i = 0, sz = termLabels.size(); i < sz; i++) { +// final TermLabel currentLabel = termLabels.get(i); +// if (currentLabel.isProofRelevant()) { +// hashcode += 7 * currentLabel.hashCode(); +// } +// } + return hashcode; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index 068e0c1cae5..b1c0441c08c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -52,6 +52,12 @@ public Boolean equalsModThisProperty(Term term, Object o) { ImmutableSLList.nil(), null); } + /** + * Computes the hash code of {@code term} modulo bound renaming. + * + * @param term the term to compute the hash code for + * @return the hash code + */ @Override public int hashCodeModThisProperty(Term term) { throw new UnsupportedOperationException( diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index a6f1ba57c4f..b81958fab38 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -61,9 +61,27 @@ public Boolean equalsModThisProperty(Term term, Object o) { return true; } + /** + * Computes the hash code of {@code term} while ignoring all term labels. + *

+ * Currently, the hash code is computed almost the same way as in TermImpl. This is also the + * case for labeled terms, + * as all term labels are ignored. + * + * @param term the term to compute the hash code for + * @return the hash code + */ @Override public int hashCodeModThisProperty(Term term) { - throw new UnsupportedOperationException( - "Hashing of terms modulo term labels not yet implemented!"); + // change 5 and 17 not to match TermImpl's implementation too much + int hashcode = 5; + hashcode = hashcode * 17 + term.op().hashCode(); + hashcode = hashcode * 17 + + EqualityUtils.hashCodeModPropertyOfIterable(TERM_LABELS_PROPERTY, term.subs()); + hashcode = hashcode * 17 + term.boundVars().hashCode(); + hashcode = hashcode * 17 + term.javaBlock().hashCode(); + + return hashcode; } + } From 8178953b398f1e6eb356783388944560c497dddf Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 23 Jan 2024 23:38:30 +0100 Subject: [PATCH 03/73] add wrapper of LinkedHashMap that uses equalsModProperty in equals method --- .../IrrelevantTermLabelsProperty.java | 8 - .../logic/equality/LinkedHashMapWrapper.java | 152 ++++++++++++++++++ .../logic/equality/TermLabelsProperty.java | 1 - 3 files changed, 152 insertions(+), 9 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 23c9e46021a..ff455e04078 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -86,7 +86,6 @@ public Boolean equalsModThisProperty(Term term1, Term term2) { */ @Override public int hashCodeModThisProperty(Term term) { - // change 5 and 17 not to match TermImpl's implementation too much? int hashcode = 5; hashcode = hashcode * 17 + term.op().hashCode(); hashcode = hashcode * 17 + EqualityUtils @@ -98,13 +97,6 @@ public int hashCodeModThisProperty(Term term) { hashcode += (label.isProofRelevant() ? 7 * label.hashCode() : 0); } -// final ImmutableArray termLabels = term.getLabels(); -// for (int i = 0, sz = termLabels.size(); i < sz; i++) { -// final TermLabel currentLabel = termLabels.get(i); -// if (currentLabel.isProofRelevant()) { -// hashcode += 7 * currentLabel.hashCode(); -// } -// } return hashcode; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java new file mode 100644 index 00000000000..2032a6ef5a1 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java @@ -0,0 +1,152 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.logic.equality; + +import java.util.Iterator; + +import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.util.LinkedHashMap; +import de.uka.ilkd.key.util.Pair; + + +public class LinkedHashMapWrapper { + private final LinkedHashMap map; + private final TermProperty property; + + public LinkedHashMapWrapper(TermProperty property) { + this.property = property; + map = new LinkedHashMap<>(); + } + + public LinkedHashMapWrapper(Term key, V value, TermProperty property) { + this(property); + put(key, value); + } + + public LinkedHashMapWrapper(Term[] keys, V[] values, TermProperty property) { + this(property); + putAll(keys, values); + } + + + public LinkedHashMapWrapper(Iterable keys, Iterable values, TermProperty property) { + this(property); + putAll(keys, values); + } + + public int size() { + return map.size(); + } + + public boolean isEmpty() { + return map.isEmpty(); + } + + public boolean containsKey(Term key) { + return map.containsKey(wrapTerm(key)); + } + + public V get(Term key) { + return map.get(wrapTerm(key)); + } + + public V put(Term key, V value) { + return map.put(wrapTerm(key), value); + } + + public void putAll(Term[] keys, V[] vals) { + for (int i = 0; i < keys.length; i++) { + if (i < vals.length) { + put(keys[i], vals[i]); + } else { + put(keys[i], null); + } + } + } + + public void putAll(Iterable keys, Iterable vals) { + Iterator itVals = vals.iterator(); + for (Term key : keys) { + if (itVals.hasNext()) { + put(key, itVals.next()); + } else { + put(key, null); + } + } + } + + public V remove(Term key) { + return map.remove(wrapTerm(key)); + } + + public boolean containsValue(V value) { + return map.containsValue(value); + } + + public Iterator> iterator() { + return new PairIterator<>(map); + } + + private TermWrapper wrapTerm(Term term) { + return new TermWrapper(term, property); + } + + + // ------------- wrapper class for terms + /** + * This class is used to wrap a term and override the {@code equals} and {@code hashCode} methods for use in a + * {@link LinkedHashMap}. + *

+ * The wrapped term is equipped with a {@link TermProperty} that is used for + * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)} and + * {@link TermEqualsModProperty#hashCodeModProperty(TermProperty)}. + * + * @param term The term to be wrapped + * @param property The {@link TermProperty} that is used in the {@code equals} and {@code hashCode} methods + */ + private record TermWrapper(Term term, TermProperty property) { + @Override + public boolean equals(Object obj) { + return term.equalsModProperty(obj, property); + } + + @Override + public int hashCode() { + return term.hashCodeModProperty(property); + } + } + + // ------------- class to iterate over internal map and unwrap terms + private static class PairIterator implements Iterator> { + + private final Iterator keyIt; + private final LinkedHashMap map; + private TermWrapper last = null; + + public PairIterator(final LinkedHashMap map) { + this.map = map; + keyIt = map.keySet().iterator(); + } + + @Override + public boolean hasNext() { + return keyIt.hasNext(); + } + + @Override + public Pair next() { + last = keyIt.next(); + return new Pair<>(last.term(), map.get(last)); + } + + @Override + public void remove() { + if (last != null) { + map.remove(last); + last = null; + } + } + + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 1f3e6fda99d..a32070a1196 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -71,7 +71,6 @@ public Boolean equalsModThisProperty(Term term1, Term term2) { */ @Override public int hashCodeModThisProperty(Term term) { - // change 5 and 17 not to match TermImpl's implementation too much int hashcode = 5; hashcode = hashcode * 17 + term.op().hashCode(); hashcode = hashcode * 17 From 0f7c1b5a8ad271ad2d53bec01b955ce0bea68a77 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 24 Jan 2024 16:35:18 +0100 Subject: [PATCH 04/73] move EqualityUtils and LinkedHashMapWrapper from equality to util --- .../ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java | 1 + .../uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java | 1 + .../de/uka/ilkd/key/logic/equality/TermLabelsProperty.java | 1 + .../uka/ilkd/key/logic/{equality => util}/EqualityUtils.java | 4 +++- .../key/logic/{equality => util}/LinkedHashMapWrapper.java | 4 +++- 5 files changed, 9 insertions(+), 2 deletions(-) rename key.core/src/main/java/de/uka/ilkd/key/logic/{equality => util}/EqualityUtils.java (86%) rename key.core/src/main/java/de/uka/ilkd/key/logic/{equality => util}/LinkedHashMapWrapper.java (96%) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index ff455e04078..eb15257aa24 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -5,6 +5,7 @@ import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.label.TermLabel; +import de.uka.ilkd.key.logic.util.EqualityUtils; import org.key_project.util.collection.ImmutableArray; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index 436137ac4cd..e0ba0a08699 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -8,6 +8,7 @@ import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.label.TermLabel; +import de.uka.ilkd.key.logic.util.EqualityUtils; import org.key_project.util.EqualsModProofIrrelevancy; import org.key_project.util.EqualsModProofIrrelevancyUtil; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index a32070a1196..f00f77b8302 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -4,6 +4,7 @@ package de.uka.ilkd.key.logic.equality; import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.util.EqualityUtils; import org.key_project.util.collection.ImmutableArray; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java similarity index 86% rename from key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java rename to key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java index 37d80cc1629..e149df04ef4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualityUtils.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java @@ -1,9 +1,11 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.logic.equality; +package de.uka.ilkd.key.logic.util; import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; +import de.uka.ilkd.key.logic.equality.TermProperty; public class EqualityUtils { diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java similarity index 96% rename from key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java rename to key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java index 2032a6ef5a1..e2a0bced01b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java @@ -1,11 +1,13 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.logic.equality; +package de.uka.ilkd.key.logic.util; import java.util.Iterator; import de.uka.ilkd.key.logic.Term; +import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; +import de.uka.ilkd.key.logic.equality.TermProperty; import de.uka.ilkd.key.util.LinkedHashMap; import de.uka.ilkd.key.util.Pair; From 868dc426ca6f0ececfe779f25b4814153c9b0c44 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 24 Jan 2024 18:05:37 +0100 Subject: [PATCH 05/73] add doc to LinkedHashMapWrapper --- .../key/logic/util/LinkedHashMapWrapper.java | 168 +++++++++++++++++- 1 file changed, 165 insertions(+), 3 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java index e2a0bced01b..060b6bb4b45 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java @@ -11,52 +11,148 @@ import de.uka.ilkd.key.util.LinkedHashMap; import de.uka.ilkd.key.util.Pair; - +/** + * This class is a wrapper for {@link LinkedHashMap} where the keys are {@link Term}s. + *

+ * Internally, the {@link Term}s are wrapped so that {@link TermEqualsModProperty} can be used for + * equality checks and + * hash codes instead of the usual {@code equals} and {@code hashCode} methods of {@link Term}. + * + * @param the type of the values in the wrapped LinkedHashMap + */ public class LinkedHashMapWrapper { + /** + * The wrapped {@link LinkedHashMap}. + */ private final LinkedHashMap map; + + /** + * The {@link TermProperty} that is used for equality checks and hash codes. + */ private final TermProperty property; + /** + * Constructs a new empty {@link LinkedHashMapWrapper}. + * + * @param property the {@link TermProperty} that is used internally for equality checks and hash + * codes + */ public LinkedHashMapWrapper(TermProperty property) { this.property = property; map = new LinkedHashMap<>(); } + /** + * Constructs a new {@link LinkedHashMapWrapper} and inserts the given key-value pair. + * + * @param key the key to be inserted + * @param value the value corresponding to {@code key} + * @param property the {@link TermProperty} that is used internally for equality checks and hash + * codes + */ public LinkedHashMapWrapper(Term key, V value, TermProperty property) { this(property); put(key, value); } + /** + * Constructs a new {@link LinkedHashMapWrapper} and inserts the given key-value pairs. + *

+ * The first key in {@code keys} is mapped to the first value in {@code values} etc. + * If there are more keys than values, the remaining keys are mapped to {@code null}. + * If there are more values than keys, the remaining values are ignored. + * + * @param keys the array of keys to be inserted + * @param values the array of values corresponding to the keys + * @param property the {@link TermProperty} that is used internally for equality checks and hash + * codes + */ public LinkedHashMapWrapper(Term[] keys, V[] values, TermProperty property) { this(property); putAll(keys, values); } - + /** + * Constructs a new {@link LinkedHashMapWrapper} and inserts the given key-value pairs. + *

+ * The first key in {@code keys} is mapped to the first value in {@code values} etc. + * If there are more keys than values, the remaining keys are mapped to {@code null}. + * If there are more values than keys, the remaining values are ignored. + * + * @param keys the iterable of keys to be inserted + * @param values the iterable of values corresponding to the keys + * @param property the {@link TermProperty} that is used internally for equality checks and hash + * codes + */ public LinkedHashMapWrapper(Iterable keys, Iterable values, TermProperty property) { this(property); putAll(keys, values); } + /** + * Returns the number of key-value pairs in this map. + * + * @return the number of key-value pairs in this map + */ public int size() { return map.size(); } + /** + * Returns true if this map contains no key-value pairs. + * + * @return true if this map contains no key-value pairs + */ public boolean isEmpty() { return map.isEmpty(); } + /** + * Returns true if this map contains a mapping for the specified key. + * + * @param key the key whose presence in this map is to be tested + * @return true if this map contains a mapping for the specified key + */ public boolean containsKey(Term key) { return map.containsKey(wrapTerm(key)); } + /** + * Returns the value to which the specified key is mapped, or {@code null} if this map contains + * no mapping for the key. + * + * @param key the key whose associated value is to be returned + * @return the value to which the specified key is mapped + */ public V get(Term key) { return map.get(wrapTerm(key)); } + /** + * Insert the given key-value pair into this map. + *

+ * If the map previously contained a mapping for the key, the old value is replaced by the given + * value. + * + * @param key the key to be inserted + * @param value the value corresponding to {@code key} + * @return the previous value associated with {@code key}, or {@code null} if there was no + * mapping for {@code key} + */ public V put(Term key, V value) { return map.put(wrapTerm(key), value); } + /** + * Inserts the given key-value pairs into this map. + *

+ * The first key in {@code keys} is mapped to the first value in {@code values} etc. + * If there are more keys than values, the remaining keys are mapped to {@code null}. + * If there are more values than keys, the remaining values are ignored. + * + * @param keys the array of keys to be inserted + * @param vals the array of values corresponding to the keys + */ public void putAll(Term[] keys, V[] vals) { for (int i = 0; i < keys.length; i++) { if (i < vals.length) { @@ -67,6 +163,16 @@ public void putAll(Term[] keys, V[] vals) { } } + /** + * Inserts the given key-value pairs into this map. + *

+ * The first key in {@code keys} is mapped to the first value in {@code values} etc. + * If there are more keys than values, the remaining keys are mapped to {@code null}. + * If there are more values than keys, the remaining values are ignored. + * + * @param keys the iterable of keys to be inserted + * @param vals the iterable of values corresponding to the keys + */ public void putAll(Iterable keys, Iterable vals) { Iterator itVals = vals.iterator(); for (Term key : keys) { @@ -78,18 +184,51 @@ public void putAll(Iterable keys, Iterable vals) { } } + /** + * Removes the mapping for the specified key from this map if present and returns the previously + * associated value. + * + * @param key the key whose mapping is to be removed from the map + * @return the previous value associated with {@code key}, or {@code null} if there was no + * mapping for {@code key} + */ public V remove(Term key) { return map.remove(wrapTerm(key)); } + /** + * Returns true if this map contains a mapping to the specified value. + * + * @param value the value whose presence in this map is to be tested + * @return true if this map contains a mapping to the specified value + */ public boolean containsValue(V value) { return map.containsValue(value); } + /** + * Returns an iterator over the key-value pairs in this map. + *

+ * The pairs in this iterator contain the unwrapped terms. + * + * @return an iterator over the key-value pairs in this map + */ public Iterator> iterator() { return new PairIterator<>(map); } + /** + * This helper method wraps a term in a {@link TermWrapper} with the {@link TermProperty} of + * this map. + *

+ * This is done so that {@link TermEqualsModProperty} can be used for equality checks and hash + * codes instead of the + * usual {@code equals} and {@code hashCode} methods of {@link Term} in the internal + * {@link LinkedHashMap}. + * + * @param term the term to be wrapped + * @return the wrapped term + */ private TermWrapper wrapTerm(Term term) { return new TermWrapper(term, property); } @@ -120,12 +259,35 @@ public int hashCode() { } // ------------- class to iterate over internal map and unwrap terms - private static class PairIterator implements Iterator> { + /** + * This class is used to iterate over the key-value pairs in the {@link LinkedHashMapWrapper}. + *

+ * The terms in the pairs are unwrapped before returning them. + * + * @param the type of the values in the {@link LinkedHashMapWrapper} + */ + private static class PairIterator implements Iterator> { + /** + * The iterator over the keys of the internal map. + */ private final Iterator keyIt; + + /** + * The internal map. + */ private final LinkedHashMap map; + + /** + * The last key-value pair that was returned by {@link #next()}. + */ private TermWrapper last = null; + /** + * Creates a new iterator over the key-value pairs in the {@link LinkedHashMapWrapper}. + * + * @param map the internal map of the {@link LinkedHashMapWrapper} to iterate over + */ public PairIterator(final LinkedHashMap map) { this.map = map; keyIt = map.keySet().iterator(); From 55577c82a56c132d0dddda9dc415a0509734b8a4 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 30 Jan 2024 19:26:01 +0100 Subject: [PATCH 06/73] change TermEqualsModProperty to EqualsModProperty and TermProperty to Property and use a type parameter --- .../uka/ilkd/key/logic/LabeledTermImpl.java | 6 +-- .../main/java/de/uka/ilkd/key/logic/Term.java | 4 +- .../java/de/uka/ilkd/key/logic/TermImpl.java | 6 +-- ...odProperty.java => EqualsModProperty.java} | 8 ++-- .../IrrelevantTermLabelsProperty.java | 6 +-- .../equality/ProofIrrelevancyProperty.java | 8 ++-- .../uka/ilkd/key/logic/equality/Property.java | 36 ++++++++++++++++++ .../key/logic/equality/RenamingProperty.java | 6 +-- .../logic/equality/TermLabelsProperty.java | 6 +-- .../ilkd/key/logic/equality/TermProperty.java | 37 ------------------- 10 files changed, 62 insertions(+), 61 deletions(-) rename key.core/src/main/java/de/uka/ilkd/key/logic/equality/{TermEqualsModProperty.java => EqualsModProperty.java} (79%) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermProperty.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java index 7db0022e77b..4325dcec3a9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java @@ -6,10 +6,10 @@ import java.util.Objects; import java.util.stream.Collectors; +import de.uka.ilkd.key.logic.equality.EqualsModProperty; import de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty; +import de.uka.ilkd.key.logic.equality.Property; import de.uka.ilkd.key.logic.equality.RenamingProperty; -import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; -import de.uka.ilkd.key.logic.equality.TermProperty; import de.uka.ilkd.key.logic.label.TermLabel; import de.uka.ilkd.key.logic.op.Operator; import de.uka.ilkd.key.logic.op.QuantifiableVariable; @@ -24,7 +24,7 @@ *

* * Two labeled terms are equal if they have equal term structure and equal annotations. In contrast, - * the method {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)} can be used to + * the method {@link EqualsModProperty#equalsModProperty(Object, Property)} can be used to * compare terms * while ignoring certain * given properties. E.g. by using {@link RenamingProperty#RENAMING_TERM_PROPERTY}, just the diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java index eb0cdf3c9dc..38bb53957d8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java @@ -3,7 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic; -import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; +import de.uka.ilkd.key.logic.equality.EqualsModProperty; import de.uka.ilkd.key.logic.label.TermLabel; import de.uka.ilkd.key.logic.op.Operator; import de.uka.ilkd.key.logic.op.QuantifiableVariable; @@ -40,7 +40,7 @@ * supported: {@link Term#execPostOrder(Visitor)} and {@link Term#execPreOrder(Visitor)}. */ public interface Term - extends SVSubstitute, Sorted, TermEqualsModProperty { + extends SVSubstitute, Sorted, EqualsModProperty { /** * The top operator (e.g., in "A and B" this is "and", in f(x,y) it is "f"). diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java index 8d4ac7486c1..6c5a1883c7e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java @@ -6,7 +6,7 @@ import java.util.concurrent.atomic.AtomicInteger; import de.uka.ilkd.key.java.PositionInfo; -import de.uka.ilkd.key.logic.equality.TermProperty; +import de.uka.ilkd.key.logic.equality.Property; import de.uka.ilkd.key.logic.label.TermLabel; import de.uka.ilkd.key.logic.op.Modality; import de.uka.ilkd.key.logic.op.Operator; @@ -339,7 +339,7 @@ protected int computeHashCode() { } @Override - public boolean equalsModProperty(Object o, TermProperty property) { + public boolean equalsModProperty(Object o, Property property) { if (!(o instanceof Term other)) { return false; } @@ -347,7 +347,7 @@ public boolean equalsModProperty(Object o, TermProperty property) { } @Override - public int hashCodeModProperty(TermProperty property) { + public int hashCodeModProperty(Property property) { return property.hashCodeModThisProperty(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermEqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java similarity index 79% rename from key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermEqualsModProperty.java rename to key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index 6d541d2e72b..6e29408ecb1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermEqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -7,9 +7,10 @@ * Interface to check for equality ignoring given properties and to compute according hash codes on * terms. * + * @param the type of the objects that are checked for equality or hashed * @author Tobias Reinhold */ -public interface TermEqualsModProperty { +public interface EqualsModProperty { /** * Checks whether this object is equal to {@code o} modulo the property described by @@ -19,7 +20,8 @@ public interface TermEqualsModProperty { * @param property the property to be ignored in the equality check * @return whether this object is equal to o */ - boolean equalsModProperty(Object o, TermProperty property); + + boolean equalsModProperty(Object o, Property property); /** * Computes the hash code according to the given ignored {@code property}. @@ -27,5 +29,5 @@ public interface TermEqualsModProperty { * @param property the ignored property according to which the hash code is computed * @return the hash code of this object */ - int hashCodeModProperty(TermProperty property); + int hashCodeModProperty(Property property); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 0909c508423..aefcdc2a635 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -10,10 +10,10 @@ /** * A property that can be used in - * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. * All irrelevant term labels are ignored in this equality check. */ -public class IrrelevantTermLabelsProperty implements TermProperty { +public class IrrelevantTermLabelsProperty implements Property { /** * The single instance of this property. */ @@ -25,7 +25,7 @@ public class IrrelevantTermLabelsProperty implements TermProperty { * can be accessed * through {@link IrrelevantTermLabelsProperty#IRRELEVANT_TERM_LABELS_PROPERTY} and is used as a * parameter for - * {@link TermProperty#equalsModThisProperty(Term, Term)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)}. */ private IrrelevantTermLabelsProperty() {} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index b7677d1946c..4c0f651e88e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -15,10 +15,10 @@ /** * A property that can be used in - * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. * All proof irrelevant attributes are ignored in this equality check. */ -public class ProofIrrelevancyProperty implements TermProperty { +public class ProofIrrelevancyProperty implements Property { /** * The single instance of this property. */ @@ -30,7 +30,7 @@ public class ProofIrrelevancyProperty implements TermProperty { * can be accessed * through {@link ProofIrrelevancyProperty#PROOF_IRRELEVANCY_PROPERTY} and is used as a * parameter for - * {@link TermProperty#equalsModThisProperty(Term, Term)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)}. */ private ProofIrrelevancyProperty() {} @@ -134,7 +134,7 @@ public int hashCodeModThisProperty(Term term) { /** * Compute the hashcode mod proof irrelevancy of an iterable of terms using the elements' - * {@link TermEqualsModProperty} implementation. + * {@link EqualsModProperty} implementation. * * @param iter iterable of terms * @return combined hashcode diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java new file mode 100644 index 00000000000..00ef16995fb --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java @@ -0,0 +1,36 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.logic.equality; + +/** + *

+ * This interface is used for equality checks and hashing modulo a certain property. + *

+ * Objects of classes implementing this interface are given to the methods in + * {@link EqualsModProperty} as parameters to unify equality checks and hashing modulo different + * properties. + * + * @param the type of the objects that are checked for equality or hashed + * @author Tobias Reinhold + */ +public interface Property { + /** + * Checks {@code t1} and {@code t2} for equality ignoring a certain property. + * + * @param t1 the first element of the equality check + * @param t2 the second element of the equality check + * @return whether {@code t1} and {@code t2} are equal ignoring a certain property + */ + Boolean equalsModThisProperty(T t1, T t2); + + /** + * Computes the hash code of {@code t} in a context where {@link this#equalsModThisProperty(T, + * T)} + * is used as an equality check, so that it can be used in, e.g., a HashMap. + * + * @param t the object to compute the hash code for + * @return the hash code of {@code t} ignoring a certain property + */ + int hashCodeModThisProperty(T t); +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java index ff5a8538ad4..b4d621cc163 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java @@ -17,10 +17,10 @@ /** * A property that can be used in - * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. * Renaming of variables is ignored in this equality check. */ -public class RenamingProperty implements TermProperty { +public class RenamingProperty implements Property { /** * The single instance of this property. */ @@ -30,7 +30,7 @@ public class RenamingProperty implements TermProperty { * This constructor is private as a single instance of this class should be shared. The instance * can be accessed * through {@link RenamingProperty#RENAMING_TERM_PROPERTY} and is used as a parameter for - * {@link TermProperty#equalsModThisProperty(Term, Term)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)}. */ private RenamingProperty() {} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 16e14dfc0f0..8b77aa01605 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -9,10 +9,10 @@ /** * A property that can be used in - * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. * All term labels are ignored in this equality check. */ -public class TermLabelsProperty implements TermProperty { +public class TermLabelsProperty implements Property { /** * The single instance of this property. */ @@ -22,7 +22,7 @@ public class TermLabelsProperty implements TermProperty { * This constructor is private as a single instance of this class should be shared. The instance * can be accessed * through {@link TermLabelsProperty#TERM_LABELS_PROPERTY} and is used as a parameter for - * {@link TermProperty#equalsModThisProperty(Term, Term)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property)}. */ private TermLabelsProperty() {} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermProperty.java deleted file mode 100644 index 2f6e41b3b6a..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermProperty.java +++ /dev/null @@ -1,37 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.logic.equality; - -import de.uka.ilkd.key.logic.Term; - -/** - *

- * This interface is used for equality checks and hashing modulo a certain property on terms. - *

- * Objects of classes implementing this interface are given to the methods in - * {@link TermEqualsModProperty} as parameters to unify equality checks and hashing modulo different - * properties. - * - * @author Tobias Reinhold - */ -public interface TermProperty { - /** - * Checks {@code term1} and {@code term2} for equality ignoring a certain property. - * - * @param term1 the first term to check for equality with {@code term2} - * @param term2 the second term to check for equality with {@code term1} - * @return whether {@code term1} and {@code term2} are equal ignoring a certain property - */ - Boolean equalsModThisProperty(Term term1, Term term2); - - /** - * Computes the hash code of the {@code term} in a context where - * {@link this#equalsModThisProperty(Term, Term)} is used as an equality check, so that it can - * be used in, e.g., a HashMap. - * - * @param term the term to compute the hash code for - * @return the hash code of {@code term} ignoring a certain property - */ - int hashCodeModThisProperty(Term term); -} From c590e1b03834f2065213bbce90537c0a34d0419e Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 21 Feb 2024 13:54:43 +0100 Subject: [PATCH 07/73] start implementation of JavaASTTreeWalker with internal stack --- .../key/java/visitor/JavaASTTreeWalker.java | 146 ++++++++++++++++++ .../uka/ilkd/key/java/visitor/TreeWalker.java | 27 ++++ 2 files changed, 173 insertions(+) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java create mode 100644 key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java new file mode 100644 index 00000000000..9930cbcfbab --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -0,0 +1,146 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.java.visitor; + +import de.uka.ilkd.key.java.NonTerminalProgramElement; +import de.uka.ilkd.key.java.SourceElement; + +public class JavaASTTreeWalker implements TreeWalker { + private SourceElement root; + + private SourceElement currentNode; + + @Override + public SourceElement getRoot() { + return root; + } + + @Override + public SourceElement getCurrentNode() { + return currentNode; + } + + @Override + public SourceElement firstChild() { + if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { + currentNode = ntpe.getChildAt(0); + return currentNode; + } + return null; + } + + @Override + public SourceElement lastChild() { + if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { + currentNode = ntpe.getChildAt(ntpe.getChildCount() - 1); + return currentNode; + } + return null; + } + + @Override + public SourceElement nextNode() { + return null; + } + + @Override + public SourceElement previousNode() { + return null; + } + + @Override + public SourceElement nextSibling() { + return null; + } + + @Override + public SourceElement previousSibling() { + return null; + } + + @Override + public SourceElement parentNode() { + return null; + } + + private record SourceElementChildIndexPair(SourceElement sourceElement, int childIndex) {} + + /** + * Class used to store pairs of {@link SourceElement}s and how many children of each have been + * already visited. + */ + private class Stack { + /** + * The array that is backing the stack. + */ + SourceElementChildIndexPair[] stack; + + /** + * The number of elements contained in the stack. + *

+ * {@code count} therefore points to the next free spot available in the {@code stack}. + */ + int count; + + /** + * Constructs a new {@link Stack} with an initial capacity of 16 elements. + */ + public Stack() { + final int standardInitialCapacity = 16; + stack = new SourceElementChildIndexPair[standardInitialCapacity]; + } + + /** + * Pushes a new element onto the stack. + * + * @param element the element to be pushed onto the stack + */ + void push(SourceElementChildIndexPair element) { + if (count >= stack.length) { + resizeStack(); + } + stack[count++] = element; + return; + } + + /** + * Removes and returns the topmost element of the stack. + * + * @return the topmost element of the stack + */ + SourceElementChildIndexPair pop() { + return stack[--count]; + } + + /** + * Returns the number of elements currently contained in the stack. + * + * @return the number of elements currently contained in the stack + */ + int size() { + return count; + } + + /** + * Empties the stack. + *

+ * {@code count} is simply set to 0. + */ + void reset() { + count = 0; + } + + /** + * Increases the capacity of the stack. + *

+ * Currently, the stack size is simply doubled. + */ + void resizeStack() { + SourceElementChildIndexPair[] newStack = + new SourceElementChildIndexPair[stack.length * 2]; + System.arraycopy(stack, 0, newStack, 0, count); + stack = newStack; + } + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java new file mode 100644 index 00000000000..e18aaea71ca --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -0,0 +1,27 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.java.visitor; + +import de.uka.ilkd.key.java.SourceElement; + +public interface TreeWalker { + SourceElement getRoot(); + + SourceElement getCurrentNode(); + + SourceElement firstChild(); + + SourceElement lastChild(); + + SourceElement nextNode(); + + SourceElement previousNode(); + + SourceElement nextSibling(); + + SourceElement previousSibling(); + + SourceElement parentNode(); // leave out or by using a stack storing pair of parent and index + // for sibling +} From 01809fb443b12040218bb3463d824d610f4474a1 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 5 Mar 2024 22:27:04 +0100 Subject: [PATCH 08/73] implement more methods of JavaASTTreeWalker --- .../key/java/visitor/JavaASTTreeWalker.java | 182 ++++++++++++++++-- 1 file changed, 161 insertions(+), 21 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java index 9930cbcfbab..714017105b4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -7,10 +7,26 @@ import de.uka.ilkd.key.java.SourceElement; public class JavaASTTreeWalker implements TreeWalker { + /** + * The root of the tree that is being walked. + */ private SourceElement root; + /** + * The node of the tree the walker is currently at. + */ private SourceElement currentNode; + /** + * The stack used to store the path from the root to the current node. + */ + private Stack stack; + + /** + * The index of the next child of {@code currentNode} to be visited. + */ + private int nextChildToVisitIndex; + @Override public SourceElement getRoot() { return root; @@ -24,7 +40,11 @@ public SourceElement getCurrentNode() { @Override public SourceElement firstChild() { if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { + // The index of the next child of the stored node to be visited is 1, as the first child + // at index 0 is visited. + stack.push(new NonTerminalProgramElementChildIndexPair(ntpe, 1)); currentNode = ntpe.getChildAt(0); + nextChildToVisitIndex = 0; return currentNode; } return null; @@ -33,7 +53,13 @@ public SourceElement firstChild() { @Override public SourceElement lastChild() { if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { + // The index of the next child of the stored node to be visited is childCount, as the + // last child at index childCount - 1 is visited. + // This signals that no more children are left to be visited. + stack.push( + new NonTerminalProgramElementChildIndexPair(ntpe, ntpe.getChildCount())); currentNode = ntpe.getChildAt(ntpe.getChildCount() - 1); + nextChildToVisitIndex = 0; return currentNode; } return null; @@ -51,30 +77,129 @@ public SourceElement previousNode() { @Override public SourceElement nextSibling() { + if (currentNode != root && !stack.empty()) { + final NonTerminalProgramElementChildIndexPair parent = stack.peek(); + final NonTerminalProgramElement parentNode = parent.getNonTerminalProgramElement(); + final int parentChildIndex = parent.getNextChildToVisitIndex(); + if (parentChildIndex < parentNode.getChildCount()) { + // The index of the next child of the parent on the stack that should be visited is + // increased by one + parent.setNextChildToVisitIndex(parentChildIndex + 1); + currentNode = parentNode.getChildAt(parentChildIndex); + nextChildToVisitIndex = 0; + return currentNode; + } + } return null; } @Override public SourceElement previousSibling() { + if (currentNode != root && !stack.empty()) { + final NonTerminalProgramElementChildIndexPair parent = stack.peek(); + final NonTerminalProgramElement parentNode = parent.getNonTerminalProgramElement(); + final int parentChildIndex = parent.getNextChildToVisitIndex(); + // parentChildIndex > 1 means that the current node is not the first child of its parent + // => it has a previous sibling + if (parentChildIndex > 1) { + // The index of the next child of the parent on the stack that should be visited is + // decreased by one + parent.setNextChildToVisitIndex(parentChildIndex - 1); + currentNode = parentNode.getChildAt(parentChildIndex - 2); + nextChildToVisitIndex = 0; + return currentNode; + } + } return null; } @Override public SourceElement parentNode() { - return null; + if (stack.empty()) { + return null; + } + final NonTerminalProgramElementChildIndexPair parent = stack.pop(); + currentNode = parent.getNonTerminalProgramElement(); + nextChildToVisitIndex = parent.getNextChildToVisitIndex(); + return currentNode; } - private record SourceElementChildIndexPair(SourceElement sourceElement, int childIndex) {} + + // ----------------- internal classes for easier handling of the tree ----------------- /** - * Class used to store pairs of {@link SourceElement}s and how many children of each have been - * already visited. + * A pair consisting of a {@link NonTerminalProgramElement} and how many children of it have + * already been visited. */ - private class Stack { + private static class NonTerminalProgramElementChildIndexPair { + /** + * The {@link NonTerminalProgramElement} of the pair. + */ + final NonTerminalProgramElement nonTerminalProgramElement; + + /** + * The index of the next child of {@code nonTerminalProgramElement} that should to be + * visited. + */ + int nextChildToVisitIndex; + + /** + * Constructs a new pair with the given {@code nonTerminalProgramElement} and index of the + * next child to be visited. + * + * @param nonTerminalProgramElement the {@link NonTerminalProgramElement} of the pair + * @param nextChildToVisitIndex the index of the next child of + * {@code nonTerminalProgramElement} that + * should to be visited + */ + NonTerminalProgramElementChildIndexPair(NonTerminalProgramElement nonTerminalProgramElement, + int nextChildToVisitIndex) { + this.nonTerminalProgramElement = nonTerminalProgramElement; + this.nextChildToVisitIndex = nextChildToVisitIndex; + } + + /** + * Sets the index of the next child of {@code nonTerminalProgramElement} that should to be + * visited. + * + * @param nextChildToVisitIndex the index of the next child of + * {@code nonTerminalProgramElement} that + * should to be visited + */ + void setNextChildToVisitIndex(int nextChildToVisitIndex) { + this.nextChildToVisitIndex = nextChildToVisitIndex; + } + + /** + * Returns the index of the next child of {@code nonTerminalProgramElement} that should to + * be visited. + * + * @return the index of the next child of {@code nonTerminalProgramElement} that should to + * be visited + */ + int getNextChildToVisitIndex() { + return nextChildToVisitIndex; + } + + /** + * Returns the {@link NonTerminalProgramElement} of the pair. + * + * @return the {@link NonTerminalProgramElement} of the pair + */ + NonTerminalProgramElement getNonTerminalProgramElement() { + return nonTerminalProgramElement; + } + } + + /** + * Class used to store pairs of {@link NonTerminalProgramElement}s and how many children of each + * have been already visited. + */ + private static class Stack { /** * The array that is backing the stack. */ - SourceElementChildIndexPair[] stack; + NonTerminalProgramElementChildIndexPair[] stack; /** * The number of elements contained in the stack. @@ -88,7 +213,7 @@ private class Stack { */ public Stack() { final int standardInitialCapacity = 16; - stack = new SourceElementChildIndexPair[standardInitialCapacity]; + stack = new NonTerminalProgramElementChildIndexPair[standardInitialCapacity]; } /** @@ -96,39 +221,54 @@ public Stack() { * * @param element the element to be pushed onto the stack */ - void push(SourceElementChildIndexPair element) { + void push(NonTerminalProgramElementChildIndexPair element) { if (count >= stack.length) { resizeStack(); } stack[count++] = element; - return; } /** - * Removes and returns the topmost element of the stack. + * Removes and returns the topmost element of the stack or {@code null} if the stack is + * empty. * - * @return the topmost element of the stack + * @return the topmost element of the stack or {@code null} if the stack is empty */ - SourceElementChildIndexPair pop() { + NonTerminalProgramElementChildIndexPair pop() { + if (count == 0) { + return null; + } return stack[--count]; } /** - * Returns the number of elements currently contained in the stack. + * Returns the topmost element of the stack without removing it or {@code null} if the stack + * is empty. * - * @return the number of elements currently contained in the stack + * @return the topmost element of the stack or {@code null} if the stack is empty */ - int size() { - return count; + NonTerminalProgramElementChildIndexPair peek() { + if (count == 0) { + return null; + } + return stack[count - 1]; + } + + /** + * Returns whether the stack is empty. + * + * @return {@code true} if the stack is empty, {@code false} otherwise + */ + boolean empty() { + return count == 0; } /** * Empties the stack. - *

- * {@code count} is simply set to 0. */ - void reset() { + void clear() { count = 0; + stack = new NonTerminalProgramElementChildIndexPair[stack.length]; } /** @@ -137,8 +277,8 @@ void reset() { * Currently, the stack size is simply doubled. */ void resizeStack() { - SourceElementChildIndexPair[] newStack = - new SourceElementChildIndexPair[stack.length * 2]; + NonTerminalProgramElementChildIndexPair[] newStack = + new NonTerminalProgramElementChildIndexPair[stack.length * 2]; System.arraycopy(stack, 0, newStack, 0, count); stack = newStack; } From de457ef048b8eae1bed3b3f873fb792598624c4e Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 12 Mar 2024 15:37:22 +0100 Subject: [PATCH 09/73] implement more parts of the JavaASTTreeWalker --- .../key/java/visitor/JavaASTTreeWalker.java | 29 ++++++++- .../uka/ilkd/key/java/visitor/TreeWalker.java | 60 ++++++++++++++++++- 2 files changed, 86 insertions(+), 3 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java index 714017105b4..0072c934959 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -6,6 +6,14 @@ import de.uka.ilkd.key.java.NonTerminalProgramElement; import de.uka.ilkd.key.java.SourceElement; +/** + * This class is used to walk a tree of {@link SourceElement}s. The tree is + * traversed in depth-first order, and the walker can be used to visit the + * children of a node, the siblings of a node and the parent of a node. + *

+ * The walker is backed by a stack, which is used to store the path from the root to the current + * node. + */ public class JavaASTTreeWalker implements TreeWalker { /** * The root of the tree that is being walked. @@ -67,6 +75,25 @@ public SourceElement lastChild() { @Override public SourceElement nextNode() { + SourceElement node = firstChild(); + // TreeWalker is depth-first, so if the current node has children, the first child is taken + if (node != null) { + return node; + } + // If the current node has no children, the next sibling would be the next node + node = nextSibling(); + if (node != null) { + return node; + } + // If the current node has no children and no next sibling, we have to go up the tree and + // find siblings of the ancestors + while (!stack.empty()) { + parentNode(); + node = nextSibling(); + if (node != null) { + return node; + } + } return null; } @@ -125,7 +152,7 @@ public SourceElement parentNode() { } - // ----------------- internal classes for easier handling of the tree ----------------- + // ----------------- internal classes for easier handling of the tree ----------------- // /** * A pair consisting of a {@link NonTerminalProgramElement} and how many children of it have diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java index e18aaea71ca..f7d92ee2a12 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -5,23 +5,79 @@ import de.uka.ilkd.key.java.SourceElement; +/** + * This interface is used to walk a tree of {@link SourceElement}s. The tree is + * traversed in depth-first order, and the walker can be used to visit the + * children of a node, the siblings of a node and the parent of a node. + */ public interface TreeWalker { + /** + * Returns the root of the tree that is being walked. + * + * @return the root of the tree that is being walked + */ SourceElement getRoot(); + /** + * Returns the node of the tree the walker is currently at. + * + * @return the node of the tree the walker is currently at + */ SourceElement getCurrentNode(); + /** + * Returns the first child of the current node, or {@code null} if the + * current node has no children. + * + * @return the first child of the current node, or {@code null} if the + * current node has no children + */ SourceElement firstChild(); + /** + * Returns the last child of the current node, or {@code null} if the current + * node has no children. + * + * @return the last child of the current node, or {@code null} if the current + * node has no children + */ SourceElement lastChild(); + /** + * Returns the next node in the tree, or {@code null} if the current node is + * the last node in the tree. + * + * @return the next node in the tree, or {@code null} if the current node is + * the last node in the tree + */ SourceElement nextNode(); SourceElement previousNode(); + /** + * Returns the next sibling of the current node, or {@code null} if the current + * node has no next sibling. + * + * @return the next sibling of the current node, or {@code null} if the current + * node has no next sibling + */ SourceElement nextSibling(); + /** + * Returns the previous sibling of the current node, or {@code null} if the + * current node has no previous sibling. + * + * @return the previous sibling of the current node, or {@code null} if the + * current node has no previous sibling + */ SourceElement previousSibling(); - SourceElement parentNode(); // leave out or by using a stack storing pair of parent and index - // for sibling + /** + * Returns the parent of the current node, or {@code null} if the current node + * has no parent. + * + * @return the parent of the current node, or {@code null} if the current node + * has no parent + */ + SourceElement parentNode(); } From c5aeda288197d005ef489a485ca5b3eaae20f5f5 Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 12 Mar 2024 17:40:34 +0100 Subject: [PATCH 10/73] finish JavaASTTreeWalker --- .../key/java/visitor/JavaASTTreeWalker.java | 46 +++++++++---- .../uka/ilkd/key/java/visitor/TreeWalker.java | 66 ++++++++++++------- 2 files changed, 77 insertions(+), 35 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java index 0072c934959..877a5381990 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -18,7 +18,7 @@ public class JavaASTTreeWalker implements TreeWalker { /** * The root of the tree that is being walked. */ - private SourceElement root; + private final SourceElement root; /** * The node of the tree the walker is currently at. @@ -28,12 +28,16 @@ public class JavaASTTreeWalker implements TreeWalker { /** * The stack used to store the path from the root to the current node. */ - private Stack stack; + private final Stack stack; /** - * The index of the next child of {@code currentNode} to be visited. + * Creates a new {@link JavaASTTreeWalker} with the given {@code root} as the root of the tree. */ - private int nextChildToVisitIndex; + public JavaASTTreeWalker(SourceElement root) { + this.root = root; + currentNode = root; + stack = new Stack(); + } @Override public SourceElement getRoot() { @@ -52,7 +56,6 @@ public SourceElement firstChild() { // at index 0 is visited. stack.push(new NonTerminalProgramElementChildIndexPair(ntpe, 1)); currentNode = ntpe.getChildAt(0); - nextChildToVisitIndex = 0; return currentNode; } return null; @@ -67,7 +70,6 @@ public SourceElement lastChild() { stack.push( new NonTerminalProgramElementChildIndexPair(ntpe, ntpe.getChildCount())); currentNode = ntpe.getChildAt(ntpe.getChildCount() - 1); - nextChildToVisitIndex = 0; return currentNode; } return null; @@ -75,17 +77,17 @@ public SourceElement lastChild() { @Override public SourceElement nextNode() { - SourceElement node = firstChild(); // TreeWalker is depth-first, so if the current node has children, the first child is taken + SourceElement node = firstChild(); if (node != null) { return node; } - // If the current node has no children, the next sibling would be the next node + // As the current node has no children, the next sibling would be the next node node = nextSibling(); if (node != null) { return node; } - // If the current node has no children and no next sibling, we have to go up the tree and + // As the current node has no children and no next sibling, we have to go up the tree and // find siblings of the ancestors while (!stack.empty()) { parentNode(); @@ -94,12 +96,33 @@ public SourceElement nextNode() { return node; } } + // The current node is the last node in the tree return null; } @Override public SourceElement previousNode() { - return null; + // If the current node is the root, there is no previous node + if (currentNode == root) { + return null; + } + // If the current node has no previous sibling, it is a first child, and we must therefore + // go to the parent + SourceElement node = previousSibling(); + if (node == null) { + node = parentNode(); + return node; + } + // As the current node has a previous sibling, we must go down the tree through all last + // children to find the real previous node + while (true) { + SourceElement lastChild = lastChild(); + if (lastChild != null) { + node = lastChild; + } else { + return node; + } + } } @Override @@ -113,7 +136,6 @@ public SourceElement nextSibling() { // increased by one parent.setNextChildToVisitIndex(parentChildIndex + 1); currentNode = parentNode.getChildAt(parentChildIndex); - nextChildToVisitIndex = 0; return currentNode; } } @@ -133,7 +155,6 @@ public SourceElement previousSibling() { // decreased by one parent.setNextChildToVisitIndex(parentChildIndex - 1); currentNode = parentNode.getChildAt(parentChildIndex - 2); - nextChildToVisitIndex = 0; return currentNode; } } @@ -147,7 +168,6 @@ public SourceElement parentNode() { } final NonTerminalProgramElementChildIndexPair parent = stack.pop(); currentNode = parent.getNonTerminalProgramElement(); - nextChildToVisitIndex = parent.getNextChildToVisitIndex(); return currentNode; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java index f7d92ee2a12..d3f28aebcee 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -26,55 +26,77 @@ public interface TreeWalker { SourceElement getCurrentNode(); /** - * Returns the first child of the current node, or {@code null} if the - * current node has no children. + * Walks to the first child of the current node, or stays in place if the current node has no + * children. * - * @return the first child of the current node, or {@code null} if the - * current node has no children + * @return the first child of the current node, or {@code null} if the current node has no + * children */ SourceElement firstChild(); /** - * Returns the last child of the current node, or {@code null} if the current - * node has no children. + * Walks to the last child of the current node, or stays in place if the current node has no + * children. * - * @return the last child of the current node, or {@code null} if the current - * node has no children + * @return the last child of the current node, or {@code null} if the current node has no + * children */ SourceElement lastChild(); /** - * Returns the next node in the tree, or {@code null} if the current node is - * the last node in the tree. + * Walks to the next node in the tree, or stays in place if the current node is the last node in + * the tree. + *

+ * Possible candidates for the next node are (in this order): + *

+ * 1. The first child of the current node + *

+ * 2. The next sibling of the current node + *

+ * 3. The first found next sibling of some ancestor of the current node from bottom to top * - * @return the next node in the tree, or {@code null} if the current node is - * the last node in the tree + * @return the next node in the tree, or {@code null} if the current node is the last node in + * the tree */ SourceElement nextNode(); + /** + * Walks to the previous node in the tree, or stays in place if the current node is the first + * node in the tree. + *

+ * Possible candidates for the previous node are (in this order): + *

+ * 1. The furthest down last descendant of the previous sibling of the current node in the tree + *

+ * 2. The previous sibling of the current node + *

+ * 3. The parent of the current node + * + * @return the previous node in the tree, or {@code null} if the current node is the last node + * in the tree + */ SourceElement previousNode(); /** - * Returns the next sibling of the current node, or {@code null} if the current - * node has no next sibling. + * Walks to the next sibling of the current node, or stays in place if the current node has no + * next sibling. * - * @return the next sibling of the current node, or {@code null} if the current - * node has no next sibling + * @return the next sibling of the current node, or {@code null} if the current node has no next + * sibling */ SourceElement nextSibling(); /** - * Returns the previous sibling of the current node, or {@code null} if the - * current node has no previous sibling. + * Walks to the previous sibling of the current node, or stays in place if the current node has + * no previous sibling. * - * @return the previous sibling of the current node, or {@code null} if the - * current node has no previous sibling + * @return the previous sibling of the current node, or {@code null} if the current node has no + * previous sibling */ SourceElement previousSibling(); /** - * Returns the parent of the current node, or {@code null} if the current node - * has no parent. + * Walks to the parent of the current node, or stays in place if the current node has no parent. * * @return the parent of the current node, or {@code null} if the current node * has no parent From f51d52f229153da0f5ab3d519e2236409e3b530f Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 14 Mar 2024 14:16:22 +0100 Subject: [PATCH 11/73] add author --- .../java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java | 2 ++ .../src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java index 877a5381990..af78adda6c3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -13,6 +13,8 @@ *

* The walker is backed by a stack, which is used to store the path from the root to the current * node. + * + * @author Tobias Reinhold */ public class JavaASTTreeWalker implements TreeWalker { /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java index d3f28aebcee..d768bb6ae7a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -9,6 +9,8 @@ * This interface is used to walk a tree of {@link SourceElement}s. The tree is * traversed in depth-first order, and the walker can be used to visit the * children of a node, the siblings of a node and the parent of a node. + * + * @author Tobias Reinhold */ public interface TreeWalker { /** From 5d6c1579bb032ff41bc41165f54254e020acd088 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 14 Mar 2024 21:08:53 +0100 Subject: [PATCH 12/73] rename RenamingProperty back to RenamingTermProperty --- .../util/SymbolicExecutionUtil.java | 2 +- .../StartAuxiliaryBlockComputationMacro.java | 2 +- .../StartAuxiliaryLoopComputationMacro.java | 2 +- .../StartAuxiliaryMethodComputationMacro.java | 2 +- .../de/uka/ilkd/key/logic/BoundVariableTools.java | 2 +- .../de/uka/ilkd/key/logic/LabeledTermImpl.java | 4 ++-- .../java/de/uka/ilkd/key/logic/Semisequent.java | 2 +- ...ingProperty.java => RenamingTermProperty.java} | 8 ++++---- .../ilkd/key/logic/label/TermLabelManager.java | 2 +- .../uka/ilkd/key/macros/scripts/FocusCommand.java | 2 +- .../key/macros/scripts/InstantiateCommand.java | 2 +- .../ilkd/key/macros/scripts/RewriteCommand.java | 2 +- .../uka/ilkd/key/macros/scripts/RuleCommand.java | 2 +- .../ilkd/key/macros/scripts/SelectCommand.java | 2 +- .../uka/ilkd/key/proof/join/JoinIsApplicable.java | 2 +- .../de/uka/ilkd/key/rule/OneStepSimplifier.java | 2 +- .../conditions/ApplyUpdateOnRigidCondition.java | 2 +- .../key/rule/match/legacy/ElementMatcher.java | 2 +- .../ilkd/key/rule/match/vm/VMTacletMatcher.java | 2 +- .../MatchSchemaVariableInstruction.java | 2 +- .../de/uka/ilkd/key/rule/merge/MergeRule.java | 2 +- .../uka/ilkd/key/smt/AbstractSMTTranslator.java | 2 +- .../uka/ilkd/key/smt/newsmt2/SeqDefHandler.java | 2 +- .../uka/ilkd/key/smt/newsmt2/SumProdHandler.java | 2 +- .../speclang/FunctionalOperationContractImpl.java | 2 +- .../speclang/jml/translation/JMLSpecFactory.java | 2 +- .../key/strategy/feature/ContainsTermFeature.java | 2 +- .../feature/DependencyContractFeature.java | 2 +- ...usIsSubFormulaOfInfFlowContractAppFeature.java | 2 +- .../quantifierHeuristics/EqualityConstraint.java | 4 ++-- .../quantifierHeuristics/PredictCostProver.java | 2 +- .../key/strategy/termfeature/EqTermFeature.java | 2 +- .../ilkd/key/util/mergerule/MergeRuleUtils.java | 2 +- .../test/java/de/uka/ilkd/key/logic/TestTerm.java | 15 ++++++++------- .../key/logic/equality/TestEqualsModProperty.java | 2 +- .../de/uka/ilkd/key/parser/TestTermParser.java | 2 +- .../de/uka/ilkd/key/rule/TestApplyTaclet.java | 2 +- .../TestApplyUpdateOnRigidCondition.java | 2 +- .../ilkd/key/smt/newsmt2/ProveSMTLemmasTest.java | 2 +- .../ilkd/key/speclang/jml/TestJMLTranslator.java | 2 +- 40 files changed, 52 insertions(+), 51 deletions(-) rename key.core/src/main/java/de/uka/ilkd/key/logic/equality/{RenamingProperty.java => RenamingTermProperty.java} (96%) diff --git a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java index 40f2d639722..a0d1fe02767 100644 --- a/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java +++ b/key.core.symbolic_execution/src/main/java/de/uka/ilkd/key/symbolic_execution/util/SymbolicExecutionUtil.java @@ -72,7 +72,7 @@ import org.slf4j.LoggerFactory; import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * Provides utility methods for symbolic execution with KeY. diff --git a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryBlockComputationMacro.java b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryBlockComputationMacro.java index 7fd6ac4c639..b8f83b1f119 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryBlockComputationMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryBlockComputationMacro.java @@ -24,7 +24,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryLoopComputationMacro.java b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryLoopComputationMacro.java index f2e6191560b..ac99f63d94a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryLoopComputationMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryLoopComputationMacro.java @@ -25,7 +25,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public class StartAuxiliaryLoopComputationMacro extends AbstractProofMacro implements StartSideProofMacro { diff --git a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryMethodComputationMacro.java b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryMethodComputationMacro.java index 65271a84df0..9c2ec5dda28 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryMethodComputationMacro.java +++ b/key.core/src/main/java/de/uka/ilkd/key/informationflow/macros/StartAuxiliaryMethodComputationMacro.java @@ -22,7 +22,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/BoundVariableTools.java b/key.core/src/main/java/de/uka/ilkd/key/logic/BoundVariableTools.java index 06b13c448a8..cad52501053 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/BoundVariableTools.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/BoundVariableTools.java @@ -13,7 +13,7 @@ import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableSet; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java index 4325dcec3a9..e6d9be815f2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java @@ -9,7 +9,7 @@ import de.uka.ilkd.key.logic.equality.EqualsModProperty; import de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty; import de.uka.ilkd.key.logic.equality.Property; -import de.uka.ilkd.key.logic.equality.RenamingProperty; +import de.uka.ilkd.key.logic.equality.RenamingTermProperty; import de.uka.ilkd.key.logic.label.TermLabel; import de.uka.ilkd.key.logic.op.Operator; import de.uka.ilkd.key.logic.op.QuantifiableVariable; @@ -27,7 +27,7 @@ * the method {@link EqualsModProperty#equalsModProperty(Object, Property)} can be used to * compare terms * while ignoring certain - * given properties. E.g. by using {@link RenamingProperty#RENAMING_TERM_PROPERTY}, just the + * given properties. E.g. by using {@link RenamingTermProperty#RENAMING_TERM_PROPERTY}, just the * term structures modulo * renaming are compared whilst ignoring annotations. *

diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/Semisequent.java b/key.core/src/main/java/de/uka/ilkd/key/logic/Semisequent.java index 417c391cfd4..d1a412e6419 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/Semisequent.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/Semisequent.java @@ -8,7 +8,7 @@ import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java similarity index 96% rename from key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java rename to key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index b4d621cc163..a53e767a634 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -20,19 +20,19 @@ * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. * Renaming of variables is ignored in this equality check. */ -public class RenamingProperty implements Property { +public class RenamingTermProperty implements Property { /** * The single instance of this property. */ - public static final RenamingProperty RENAMING_TERM_PROPERTY = new RenamingProperty(); + public static final RenamingTermProperty RENAMING_TERM_PROPERTY = new RenamingTermProperty(); /** * This constructor is private as a single instance of this class should be shared. The instance * can be accessed - * through {@link RenamingProperty#RENAMING_TERM_PROPERTY} and is used as a parameter for + * through {@link RenamingTermProperty#RENAMING_TERM_PROPERTY} and is used as a parameter for * {@link EqualsModProperty#equalsModProperty(Object, Property)}. */ - private RenamingProperty() {} + private RenamingTermProperty() {} /** * Checks if {@code term2} is a term syntactically equal to {@code term1} modulo bound renaming. diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java index dc156a0de8d..c7b61578e3f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/label/TermLabelManager.java @@ -29,7 +29,7 @@ import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.java.CollectionUtil; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** *

diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/FocusCommand.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/FocusCommand.java index 1afa11def64..600decc3a78 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/FocusCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/FocusCommand.java @@ -18,7 +18,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * The command "focus" allows you to select formulas from the current sequent diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/InstantiateCommand.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/InstantiateCommand.java index 5660620c714..bd36320b8fb 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/InstantiateCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/InstantiateCommand.java @@ -24,7 +24,7 @@ import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * instantiate var=a occ=2 with="a_8" hide diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RewriteCommand.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RewriteCommand.java index 3f58900ec70..4695163c98d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RewriteCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RewriteCommand.java @@ -22,7 +22,7 @@ import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * This class provides the command rewrite. diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RuleCommand.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RuleCommand.java index d7517a71dce..391f797fd71 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RuleCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/RuleCommand.java @@ -23,7 +23,7 @@ import org.key_project.util.collection.ImmutableSLList; import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * Command that applies a calculus rule All parameters are passed as strings and converted by the diff --git a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/SelectCommand.java b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/SelectCommand.java index d4a02ff67db..3c8978e0113 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/SelectCommand.java +++ b/key.core/src/main/java/de/uka/ilkd/key/macros/scripts/SelectCommand.java @@ -20,7 +20,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public class SelectCommand extends AbstractCommand { public SelectCommand() { diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/join/JoinIsApplicable.java b/key.core/src/main/java/de/uka/ilkd/key/proof/join/JoinIsApplicable.java index 662e80a056d..2f8c0bb4b34 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/join/JoinIsApplicable.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/join/JoinIsApplicable.java @@ -13,7 +13,7 @@ import de.uka.ilkd.key.logic.op.UpdateApplication; import de.uka.ilkd.key.proof.Goal; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * Methods for checking the applicability of a join for a given selection and thereby computing the diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java b/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java index da0fdfb0db1..d70e6734750 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/OneStepSimplifier.java @@ -46,7 +46,7 @@ import org.jspecify.annotations.NonNull; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public final class OneStepSimplifier implements BuiltInRule { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/conditions/ApplyUpdateOnRigidCondition.java b/key.core/src/main/java/de/uka/ilkd/key/rule/conditions/ApplyUpdateOnRigidCondition.java index 70d649e8b01..333b006fc21 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/conditions/ApplyUpdateOnRigidCondition.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/conditions/ApplyUpdateOnRigidCondition.java @@ -15,7 +15,7 @@ import org.key_project.util.collection.ImmutableArray; import org.key_project.util.collection.ImmutableSet; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java b/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java index dadfda0ecb9..f83c544c76d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java @@ -17,7 +17,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public abstract class ElementMatcher { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/VMTacletMatcher.java b/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/VMTacletMatcher.java index 61fb06e18ce..834ef05a284 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/VMTacletMatcher.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/VMTacletMatcher.java @@ -35,7 +35,7 @@ import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** *

diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/instructions/MatchSchemaVariableInstruction.java b/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/instructions/MatchSchemaVariableInstruction.java index 6345d318a62..9ff0c73212c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/instructions/MatchSchemaVariableInstruction.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/match/vm/instructions/MatchSchemaVariableInstruction.java @@ -14,7 +14,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public abstract class MatchSchemaVariableInstruction extends Instruction { diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/merge/MergeRule.java b/key.core/src/main/java/de/uka/ilkd/key/rule/merge/MergeRule.java index 349a6719920..cad179b7c94 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/rule/merge/MergeRule.java +++ b/key.core/src/main/java/de/uka/ilkd/key/rule/merge/MergeRule.java @@ -49,7 +49,7 @@ import org.jspecify.annotations.NonNull; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.util.mergerule.MergeRuleUtils.clearSemisequent; import static de.uka.ilkd.key.util.mergerule.MergeRuleUtils.closeMergePartnerGoal; import static de.uka.ilkd.key.util.mergerule.MergeRuleUtils.getConjunctiveElementsFor; diff --git a/key.core/src/main/java/de/uka/ilkd/key/smt/AbstractSMTTranslator.java b/key.core/src/main/java/de/uka/ilkd/key/smt/AbstractSMTTranslator.java index 6349986e488..dd4d0fa3a6d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/smt/AbstractSMTTranslator.java +++ b/key.core/src/main/java/de/uka/ilkd/key/smt/AbstractSMTTranslator.java @@ -24,7 +24,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.smt.SMTProblem.sequentToTerm; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SeqDefHandler.java b/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SeqDefHandler.java index e360c274ca1..cbb17d8f795 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SeqDefHandler.java +++ b/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SeqDefHandler.java @@ -29,7 +29,7 @@ import org.key_project.util.collection.DefaultImmutableSet; import org.key_project.util.collection.ImmutableSet; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * This handler handles the seqDef binder function specially. diff --git a/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SumProdHandler.java b/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SumProdHandler.java index 2b176f56a6b..a58ebad7a10 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SumProdHandler.java +++ b/key.core/src/main/java/de/uka/ilkd/key/smt/newsmt2/SumProdHandler.java @@ -11,7 +11,7 @@ import de.uka.ilkd.key.logic.op.Operator; import de.uka.ilkd.key.smt.SMTTranslationException; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; // W I P public class SumProdHandler implements SMTHandler { diff --git a/key.core/src/main/java/de/uka/ilkd/key/speclang/FunctionalOperationContractImpl.java b/key.core/src/main/java/de/uka/ilkd/key/speclang/FunctionalOperationContractImpl.java index f7cd55c8bfc..71f45bb1592 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/speclang/FunctionalOperationContractImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/speclang/FunctionalOperationContractImpl.java @@ -33,7 +33,7 @@ import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.java.MapUtil; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.util.Assert.assertEqualSort; import static de.uka.ilkd.key.util.Assert.assertSubSort; diff --git a/key.core/src/main/java/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java b/key.core/src/main/java/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java index cf59890b49d..3aeeb77ba78 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java +++ b/key.core/src/main/java/de/uka/ilkd/key/speclang/jml/translation/JMLSpecFactory.java @@ -52,7 +52,7 @@ import org.jspecify.annotations.Nullable; import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLSpecCase.Clause.DIVERGES; import static de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLSpecCase.Clause.SIGNALS; import static de.uka.ilkd.key.speclang.jml.pretranslation.TextualJMLSpecCase.ClauseHd.ENSURES; diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ContainsTermFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ContainsTermFeature.java index 1ab3a2093ee..85bc997492d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ContainsTermFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/ContainsTermFeature.java @@ -13,7 +13,7 @@ import de.uka.ilkd.key.strategy.TopRuleAppCost; import de.uka.ilkd.key.strategy.termProjection.ProjectionToTerm; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DependencyContractFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DependencyContractFeature.java index 37311a23005..19a2e12a234 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DependencyContractFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/DependencyContractFeature.java @@ -17,7 +17,7 @@ import org.key_project.util.collection.ImmutableSLList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; public final class DependencyContractFeature extends BinaryFeature { diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FocusIsSubFormulaOfInfFlowContractAppFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FocusIsSubFormulaOfInfFlowContractAppFeature.java index 2733400dfac..dcecdb4e948 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FocusIsSubFormulaOfInfFlowContractAppFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/feature/FocusIsSubFormulaOfInfFlowContractAppFeature.java @@ -16,7 +16,7 @@ import org.key_project.util.collection.ImmutableList; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java index 62b85386cc0..043f59b1b43 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java @@ -13,7 +13,7 @@ import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.BooleanContainer; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.equality.RenamingProperty; +import de.uka.ilkd.key.logic.equality.RenamingTermProperty; import de.uka.ilkd.key.logic.label.TermLabelState; import de.uka.ilkd.key.logic.op.Operator; import de.uka.ilkd.key.logic.op.ProgramVariable; @@ -414,7 +414,7 @@ private static NameAbstractionTable handleJava(Term t0, Term t1, NameAbstraction if (!t0.javaBlock().isEmpty() || !t1.javaBlock().isEmpty()) { nat = checkNat(nat); - if (RenamingProperty.javaBlocksNotEqualModRenaming(t0.javaBlock(), t1.javaBlock(), + if (RenamingTermProperty.javaBlocksNotEqualModRenaming(t0.javaBlock(), t1.javaBlock(), nat)) { return FAILED; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/PredictCostProver.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/PredictCostProver.java index 653afe0402c..f65cd882f6a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/PredictCostProver.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/PredictCostProver.java @@ -18,7 +18,7 @@ import org.key_project.util.collection.ImmutableSet; import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * TODO: rewrite, this seems pretty inefficient ... diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/termfeature/EqTermFeature.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/termfeature/EqTermFeature.java index 4b94585469f..8b12fd667fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/termfeature/EqTermFeature.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/termfeature/EqTermFeature.java @@ -8,7 +8,7 @@ import de.uka.ilkd.key.strategy.feature.MutableState; import de.uka.ilkd.key.strategy.termProjection.TermBuffer; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * Term feature for testing equality of two terms. The feature returns zero iff it is invoked on a diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java b/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java index 6f14c0f8cce..8c1f23348e7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java @@ -40,7 +40,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * This class encapsulates static methods used in the MergeRule implementation. The methods are diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java index d2047a53169..f2e53339029 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java @@ -5,7 +5,7 @@ import de.uka.ilkd.key.java.StatementBlock; import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; -import de.uka.ilkd.key.logic.equality.RenamingProperty; +import de.uka.ilkd.key.logic.equality.RenamingTermProperty; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.logic.sort.Sort; import de.uka.ilkd.key.logic.sort.SortImpl; @@ -110,10 +110,11 @@ public void testProgramElementEqualsModRenaming() { Term match1 = TacletForTests.parseTerm("\\<{ int i; }\\>true & \\<{ int i; }\\>true"); Term match2 = TacletForTests.parseTerm("\\<{ int i; }\\>true "); assertTrue( - match1.sub(0).equalsModProperty(match2, RenamingProperty.RENAMING_TERM_PROPERTY), + match1.sub(0).equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (0)."); assertTrue( - match1.sub(0).equalsModProperty(match1.sub(1), RenamingProperty.RENAMING_TERM_PROPERTY), + match1.sub(0).equalsModProperty(match1.sub(1), + RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (1)."); Term match3 = TacletForTests.parseTerm("\\<{ int j = 0; }\\>true "); assertNotEquals(match1, match3, "Terms should not be equal."); @@ -124,15 +125,15 @@ public void testProgramElementEqualsModRenaming() { public void testEqualsModRenamingWithLabels() { Term match1 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ } } }\\>true"); Term match2 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ } } }\\>true"); - assertTrue(match1.equalsModProperty(match2, RenamingProperty.RENAMING_TERM_PROPERTY), + assertTrue(match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); Term match3 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); Term match4 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int j = 0; } } }\\>true"); - assertTrue(match3.equalsModProperty(match4, RenamingProperty.RENAMING_TERM_PROPERTY), + assertTrue(match3.equalsModProperty(match4, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); Term match5 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); Term match6 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); - assertTrue(match5.equalsModProperty(match6, RenamingProperty.RENAMING_TERM_PROPERTY), + assertTrue(match5.equalsModProperty(match6, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); } @@ -145,7 +146,7 @@ public void testEqualsModRenaming() { final Term pz = tf.createTerm(p, new Term[] { tf.createTerm(z) }, null, null); final Term quant2 = tb.all(z, tb.all(z, tb.all(z, pz))); - assertTrue(quant1.equalsModProperty(quant2, RenamingProperty.RENAMING_TERM_PROPERTY), + assertTrue(quant1.equalsModProperty(quant2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms " + quant1 + " and " + quant2 + " should be equal mod renaming"); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 147235413c0..855f8ba7b9f 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -19,7 +19,7 @@ import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; import static de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty.PROOF_IRRELEVANCY_PROPERTY; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.logic.equality.TermLabelsProperty.TERM_LABELS_PROPERTY; import static org.junit.jupiter.api.Assertions.*; diff --git a/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java b/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java index 6c7189fd10e..8bcf58141e3 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java +++ b/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java @@ -21,7 +21,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static org.junit.jupiter.api.Assertions.*; public class TestTermParser extends AbstractTestTermParser { diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java index aa300084d42..53d2dfea857 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java @@ -25,7 +25,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static org.junit.jupiter.api.Assertions.*; diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java b/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java index 13ffbc93a56..27e57b4fa09 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java @@ -15,7 +15,7 @@ import org.junit.jupiter.api.Test; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static org.junit.jupiter.api.Assertions.*; public class TestApplyUpdateOnRigidCondition { diff --git a/key.core/src/test/java/de/uka/ilkd/key/smt/newsmt2/ProveSMTLemmasTest.java b/key.core/src/test/java/de/uka/ilkd/key/smt/newsmt2/ProveSMTLemmasTest.java index 9301d7e09d6..8c095a11241 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/smt/newsmt2/ProveSMTLemmasTest.java +++ b/key.core/src/test/java/de/uka/ilkd/key/smt/newsmt2/ProveSMTLemmasTest.java @@ -33,7 +33,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** * This test case makes sure that all KeY formulas which are translated to axioms in SMT can diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java index bfdd080623c..aac7e1acdee 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java @@ -26,7 +26,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static de.uka.ilkd.key.logic.equality.RenamingProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static java.lang.String.format; import static org.junit.jupiter.api.Assertions.*; From eed4891f3f3407d73e86c16ae6bcdca984154466 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 14 Mar 2024 22:00:54 +0100 Subject: [PATCH 13/73] introduce new generic type in EqualsModProperty to use as vararg --- .../main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java | 2 +- key.core/src/main/java/de/uka/ilkd/key/logic/Term.java | 2 +- key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java | 4 ++-- .../de/uka/ilkd/key/logic/equality/EqualsModProperty.java | 7 +++---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java index e6d9be815f2..045a234fc66 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/LabeledTermImpl.java @@ -24,7 +24,7 @@ *

* * Two labeled terms are equal if they have equal term structure and equal annotations. In contrast, - * the method {@link EqualsModProperty#equalsModProperty(Object, Property)} can be used to + * the method {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} can be used to * compare terms * while ignoring certain * given properties. E.g. by using {@link RenamingTermProperty#RENAMING_TERM_PROPERTY}, just the diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java index 38bb53957d8..850cb703550 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java @@ -40,7 +40,7 @@ * supported: {@link Term#execPostOrder(Visitor)} and {@link Term#execPreOrder(Visitor)}. */ public interface Term - extends SVSubstitute, Sorted, EqualsModProperty { + extends SVSubstitute, Sorted, EqualsModProperty { /** * The top operator (e.g., in "A and B" this is "and", in f(x,y) it is "f"). diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java index 6c5a1883c7e..1a24eb189dc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java @@ -339,7 +339,7 @@ protected int computeHashCode() { } @Override - public boolean equalsModProperty(Object o, Property property) { + public boolean equalsModProperty(Object o, Property property, Void... v) { if (!(o instanceof Term other)) { return false; } @@ -347,7 +347,7 @@ public boolean equalsModProperty(Object o, Property property) { } @Override - public int hashCodeModProperty(Property property) { + public int hashCodeModProperty(Property property) { return property.hashCodeModThisProperty(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index 6e29408ecb1..ebcbe15267c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -4,13 +4,12 @@ package de.uka.ilkd.key.logic.equality; /** - * Interface to check for equality ignoring given properties and to compute according hash codes on - * terms. + * Interface to check for equality ignoring given properties and to compute according hash codes. * * @param the type of the objects that are checked for equality or hashed * @author Tobias Reinhold */ -public interface EqualsModProperty { +public interface EqualsModProperty { /** * Checks whether this object is equal to {@code o} modulo the property described by @@ -21,7 +20,7 @@ public interface EqualsModProperty { * @return whether this object is equal to o */ - boolean equalsModProperty(Object o, Property property); + boolean equalsModProperty(Object o, Property property, V... v); /** * Computes the hash code according to the given ignored {@code property}. From 2da0a673d694f632ad43142a37eef0b86af87545 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 14 Mar 2024 22:15:56 +0100 Subject: [PATCH 14/73] fix doc --- .../uka/ilkd/key/java/visitor/TreeWalker.java | 23 ++++++----- .../key/logic/equality/EqualsModProperty.java | 2 + .../IrrelevantTermLabelsProperty.java | 10 ++--- .../equality/ProofIrrelevancyProperty.java | 4 +- .../RenamingSourceElementProperty.java | 38 +++++++++++++++++++ .../logic/equality/RenamingTermProperty.java | 4 +- .../logic/equality/TermLabelsProperty.java | 4 +- 7 files changed, 61 insertions(+), 24 deletions(-) create mode 100644 key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java index d768bb6ae7a..84735ea3faa 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -50,12 +50,11 @@ public interface TreeWalker { * the tree. *

* Possible candidates for the next node are (in this order): - *

- * 1. The first child of the current node - *

- * 2. The next sibling of the current node - *

- * 3. The first found next sibling of some ancestor of the current node from bottom to top + *

    + *
  1. The first child of the current node
  2. + *
  3. The next sibling of the current node
  4. + *
  5. The first found next sibling of some ancestor of the current node from bottom to top
  6. + *
* * @return the next node in the tree, or {@code null} if the current node is the last node in * the tree @@ -67,12 +66,12 @@ public interface TreeWalker { * node in the tree. *

* Possible candidates for the previous node are (in this order): - *

- * 1. The furthest down last descendant of the previous sibling of the current node in the tree - *

- * 2. The previous sibling of the current node - *

- * 3. The parent of the current node + *

    + *
  1. The furthest down last descendant of the previous sibling of the current node in the tree + *
  2. + *
  3. The previous sibling of the current node
  4. + *
  5. The parent of the current node
  6. + *
* * @return the previous node in the tree, or {@code null} if the current node is the last node * in the tree diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index ebcbe15267c..c3a18450df6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -7,6 +7,8 @@ * Interface to check for equality ignoring given properties and to compute according hash codes. * * @param the type of the objects that are checked for equality or hashed + * @param the type of additional arguments needed for the equality check + * * @author Tobias Reinhold */ public interface EqualsModProperty { diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index aefcdc2a635..73849849bd4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -10,7 +10,7 @@ /** * A property that can be used in - * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All irrelevant term labels are ignored in this equality check. */ public class IrrelevantTermLabelsProperty implements Property { @@ -25,20 +25,18 @@ public class IrrelevantTermLabelsProperty implements Property { * can be accessed * through {@link IrrelevantTermLabelsProperty#IRRELEVANT_TERM_LABELS_PROPERTY} and is used as a * parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private IrrelevantTermLabelsProperty() {} /** * Checks if {@code term2} is a term syntactically equal to {@code term1}, except for some - * irrelevant - * labels. + * irrelevant labels. * * @param term1 a term * @param term2 the term compared to {@code term1} * @return {@code true} iff {@code term2} is a term syntactically equal to {@code term1}, except - * for - * their irrelevant labels. + * for their irrelevant labels. * @see TermLabel#isProofRelevant() isStrategyRelevant */ @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index 4c0f651e88e..cd8effaf911 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -15,7 +15,7 @@ /** * A property that can be used in - * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All proof irrelevant attributes are ignored in this equality check. */ public class ProofIrrelevancyProperty implements Property { @@ -30,7 +30,7 @@ public class ProofIrrelevancyProperty implements Property { * can be accessed * through {@link ProofIrrelevancyProperty#PROOF_IRRELEVANCY_PROPERTY} and is used as a * parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private ProofIrrelevancyProperty() {} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java new file mode 100644 index 00000000000..4f1017f53c6 --- /dev/null +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -0,0 +1,38 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.logic.equality; + +import de.uka.ilkd.key.java.SourceElement; + +/** + * A property that can be used in + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for + * {@link SourceElement}s. + */ +public class RenamingSourceElementProperty implements Property { + /** + * The single instance of this property. + */ + public static final RenamingSourceElementProperty RENAMING_SOURCE_ELEMENT_PROPERTY = + new RenamingSourceElementProperty(); + + /** + * This constructor is private as a single instance of this class should be shared. The instance + * can be accessed + * through {@link RenamingSourceElementProperty#RENAMING_SOURCE_ELEMENT_PROPERTY} and is used as + * a parameter for + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. + */ + private RenamingSourceElementProperty() {} + + @Override + public Boolean equalsModThisProperty(SourceElement se1, SourceElement se2) { + return null; + } + + @Override + public int hashCodeModThisProperty(SourceElement sourceElement) { + return 0; + } +} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index a53e767a634..d646c4211e5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -17,7 +17,7 @@ /** * A property that can be used in - * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * Renaming of variables is ignored in this equality check. */ public class RenamingTermProperty implements Property { @@ -30,7 +30,7 @@ public class RenamingTermProperty implements Property { * This constructor is private as a single instance of this class should be shared. The instance * can be accessed * through {@link RenamingTermProperty#RENAMING_TERM_PROPERTY} and is used as a parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private RenamingTermProperty() {} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 8b77aa01605..140f2283cc1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -9,7 +9,7 @@ /** * A property that can be used in - * {@link EqualsModProperty#equalsModProperty(Object, Property)} for terms. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All term labels are ignored in this equality check. */ public class TermLabelsProperty implements Property { @@ -22,7 +22,7 @@ public class TermLabelsProperty implements Property { * This constructor is private as a single instance of this class should be shared. The instance * can be accessed * through {@link TermLabelsProperty#TERM_LABELS_PROPERTY} and is used as a parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property)}. + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private TermLabelsProperty() {} From fcbcccd66c43957b8282a6600217e0b4c244811b Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 15 Mar 2024 16:30:22 +0100 Subject: [PATCH 15/73] change return type to boolean instead of Boolean --- .../logic/equality/IrrelevantTermLabelsProperty.java | 7 +++---- .../key/logic/equality/ProofIrrelevancyProperty.java | 10 ++++------ .../java/de/uka/ilkd/key/logic/equality/Property.java | 6 +++--- .../ilkd/key/logic/equality/RenamingTermProperty.java | 7 +++---- .../ilkd/key/logic/equality/TermLabelsProperty.java | 10 ++++------ 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 73849849bd4..8b9ea38fb30 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -22,9 +22,8 @@ public class IrrelevantTermLabelsProperty implements Property { /** * This constructor is private as a single instance of this class should be shared. The instance - * can be accessed - * through {@link IrrelevantTermLabelsProperty#IRRELEVANT_TERM_LABELS_PROPERTY} and is used as a - * parameter for + * can be accessed through {@link IrrelevantTermLabelsProperty#IRRELEVANT_TERM_LABELS_PROPERTY} + * and is used as a parameter for * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private IrrelevantTermLabelsProperty() {} @@ -40,7 +39,7 @@ private IrrelevantTermLabelsProperty() {} * @see TermLabel#isProofRelevant() isStrategyRelevant */ @Override - public Boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index cd8effaf911..cfb1eb5e5a7 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -27,17 +27,15 @@ public class ProofIrrelevancyProperty implements Property { /** * This constructor is private as a single instance of this class should be shared. The instance - * can be accessed - * through {@link ProofIrrelevancyProperty#PROOF_IRRELEVANCY_PROPERTY} and is used as a - * parameter for + * can be accessed through {@link ProofIrrelevancyProperty#PROOF_IRRELEVANCY_PROPERTY} and is + * used as a parameter for * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private ProofIrrelevancyProperty() {} /** * Checks if {@code term2} is a term syntactically equal to {@code term1}, except for attributes - * that - * are not relevant for the purpose of these terms in the proof. + * that are not relevant for the purpose of these terms in the proof. *

* Combines the prior implementations of {@link EqualsModProofIrrelevancy} in TermImpl and * LabeledTermImpl. @@ -49,7 +47,7 @@ private ProofIrrelevancyProperty() {} * proof-irrelevant attributes. */ @Override - public Boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java index 00ef16995fb..a0709e82687 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java @@ -22,11 +22,11 @@ public interface Property { * @param t2 the second element of the equality check * @return whether {@code t1} and {@code t2} are equal ignoring a certain property */ - Boolean equalsModThisProperty(T t1, T t2); + boolean equalsModThisProperty(T t1, T t2); /** - * Computes the hash code of {@code t} in a context where {@link this#equalsModThisProperty(T, - * T)} + * Computes the hash code of {@code t} in a context where + * {@link this#equalsModThisProperty(Object, Object)} * is used as an equality check, so that it can be used in, e.g., a HashMap. * * @param t the object to compute the hash code for diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index d646c4211e5..7389f5d4dbd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -28,9 +28,8 @@ public class RenamingTermProperty implements Property { /** * This constructor is private as a single instance of this class should be shared. The instance - * can be accessed - * through {@link RenamingTermProperty#RENAMING_TERM_PROPERTY} and is used as a parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. + * can be accessed through {@link RenamingTermProperty#RENAMING_TERM_PROPERTY} and is used as a + * parameter for {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private RenamingTermProperty() {} @@ -43,7 +42,7 @@ private RenamingTermProperty() {} * and javaBlock as {@code term1} modulo bound renaming */ @Override - public Boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 140f2283cc1..889a2bd1567 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -20,16 +20,14 @@ public class TermLabelsProperty implements Property { /** * This constructor is private as a single instance of this class should be shared. The instance - * can be accessed - * through {@link TermLabelsProperty#TERM_LABELS_PROPERTY} and is used as a parameter for - * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. + * can be accessed through {@link TermLabelsProperty#TERM_LABELS_PROPERTY} and is used as a + * parameter for {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])}. */ private TermLabelsProperty() {} /** * Checks if {@code term2} is a term syntactically equal to {@code term1}, ignoring all - * term - * labels. + * term labels. * * @param term1 a term * @param term2 the term compared to {@code term1} @@ -38,7 +36,7 @@ private TermLabelsProperty() {} * term labels */ @Override - public Boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2) { if (term2 == term1) { return true; } From 3cdbb8e6fa0f5dc207a1af337a9e7ac92805fa03 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 15 Mar 2024 19:16:16 +0100 Subject: [PATCH 16/73] start implementing RenamingSourceElementProperty --- .../RenamingSourceElementProperty.java | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 4f1017f53c6..45ec2ce2008 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -3,7 +3,9 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic.equality; +import de.uka.ilkd.key.java.Comment; import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.visitor.JavaASTTreeWalker; /** * A property that can be used in @@ -27,12 +29,34 @@ public class RenamingSourceElementProperty implements Property { private RenamingSourceElementProperty() {} @Override - public Boolean equalsModThisProperty(SourceElement se1, SourceElement se2) { - return null; + public boolean equalsModThisProperty(SourceElement se1, SourceElement se2) { + JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); + JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); + + SourceElement next1 = tw1.getCurrentNode(); + SourceElement next2 = tw2.getCurrentNode(); + + while (next1 != null && next2 != null) { + if (!next1.equals(next2)) { + return false; + } + next1 = tw1.nextNode(); + next2 = tw2.nextNode(); + } + + return next1 == null && next2 == null; } @Override public int hashCodeModThisProperty(SourceElement sourceElement) { return 0; } + + private boolean comparison(SourceElement se1, SourceElement se2) { + return se1.equals(se2); + } + + private boolean comparison(Comment comment, SourceElement se) { + return true; + } } From 9035ba5b7401458c53346ac3e2967bdb7d2240e4 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 17 Mar 2024 12:07:08 +0100 Subject: [PATCH 17/73] add testcase for unexpected behavior of equalsModRenaming for SourceElements --- .../logic/equality/TestEqualsModProperty.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 855f8ba7b9f..a0578a77cb9 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -5,6 +5,8 @@ import java.util.Arrays; +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.expression.literal.StringLiteral; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; import de.uka.ilkd.key.logic.op.*; @@ -24,7 +26,7 @@ import static org.junit.jupiter.api.Assertions.*; /** - * Tests for {@link TermEqualsModProperty}. + * Tests for {@link EqualsModProperty}. * * @author Tobias Reinhold */ @@ -284,4 +286,20 @@ public void proofIrrelevancy() { assertFalse(term2.equalsModProperty(term1, PROOF_IRRELEVANCY_PROPERTY), "Should be false as terms do not have the same relevant term labels"); } + + @Test + public void renamingSourceElements() { + Term match1 = TacletForTests.parseTerm("\\<{ int i; }\\>true"); + Term match2 = TacletForTests.parseTerm("\\<{ int i; }\\>true"); + assertTrue( + match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Terms should be equalModRenaming (0)."); + + Comment testComment = new Comment("test"); + StringLiteral stringLiteral = new StringLiteral("testStringLiteral"); + + // This seems very bad as equalsModRenaming is seemingly NOT symmetric!!! + assertTrue(testComment.equalsModRenaming(stringLiteral, null)); + assertFalse(stringLiteral.equalsModRenaming(testComment, null)); + } } From 31e7e197f0eef4332748938f79ec3284a4daba9e Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 17 Mar 2024 13:10:55 +0100 Subject: [PATCH 18/73] fix one RENAMING_PROPERTY that slipped through --- .../java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java index 4f615633aef..3e4761143cc 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java @@ -448,7 +448,7 @@ public void testCorrectImplicitThisResolution() { TB.not(TB.equals(TB.var(qv), TB.NULL()))), // implicit non null TB.equals(TB.var(qv), TB.var(selfVar)))); - final boolean condition = result.equalsModProperty(expected, RENAMING_PROPERTY); + final boolean condition = result.equalsModProperty(expected, RENAMING_TERM_PROPERTY); assertTrue(condition, format("Expected:%s\n Was:%s", ProofSaver.printTerm(expected, services), ProofSaver.printTerm(result, services))); } From 9ffb63680d50de4783e54dbc0ee42d1ed9893bdf Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 17 Mar 2024 13:13:55 +0100 Subject: [PATCH 19/73] fix doc --- .../de/uka/ilkd/key/logic/equality/RenamingTermProperty.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index de8f49468e0..d827249bb3b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -181,9 +181,9 @@ private static NameAbstractionTable handleJava(JavaBlock jb0, JavaBlock jb1, *

* Moved here from {@link JavaBlock} while refactoring equalsModRenaming in {@link Term}. * As the implementation of equalsModRenaming in {@link JavaBlock} was only used in - * {@link RenamingProperty#handleJava(JavaBlock, JavaBlock, NameAbstractionTable)} + * {@link RenamingTermProperty#handleJava(JavaBlock, JavaBlock, NameAbstractionTable)} * and the deprecated class de.uka.ilkd.key.strategy.quantifierHeuristics.EqualityConstraint, - * it is now only a helper method in {@link RenamingProperty}. + * it is now only a helper method in {@link RenamingTermProperty}. * * @param jb1 the first {@link JavaBlock} * @param jb2 the second {@link JavaBlock} From 0a3cd4be243832ddf3f30b1e99dbcbf951a21776 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 17 Mar 2024 19:47:36 +0100 Subject: [PATCH 20/73] change from generic class to generic method --- .../java/de/uka/ilkd/key/java/SourceElement.java | 15 ++++++++++----- .../main/java/de/uka/ilkd/key/logic/Term.java | 2 +- .../java/de/uka/ilkd/key/logic/TermImpl.java | 2 +- .../key/logic/equality/EqualsModProperty.java | 6 +++--- .../equality/IrrelevantTermLabelsProperty.java | 4 +++- .../logic/equality/ProofIrrelevancyProperty.java | 4 +++- .../de/uka/ilkd/key/logic/equality/Property.java | 6 ++++-- .../equality/RenamingSourceElementProperty.java | 16 +++++++++++++++- .../key/logic/equality/RenamingTermProperty.java | 7 +++++-- .../key/logic/equality/TermLabelsProperty.java | 4 +++- .../logic/equality/TestEqualsModProperty.java | 4 ++-- 11 files changed, 50 insertions(+), 20 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java index 046d51538cb..55104738d5b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java @@ -4,6 +4,8 @@ package de.uka.ilkd.key.java; import de.uka.ilkd.key.java.visitor.Visitor; +import de.uka.ilkd.key.logic.equality.EqualsModProperty; +import de.uka.ilkd.key.logic.equality.Property; import de.uka.ilkd.key.logic.op.SVSubstitute; /** @@ -12,7 +14,7 @@ * to achieve an immutable structure */ -public interface SourceElement extends SVSubstitute { +public interface SourceElement extends SVSubstitute, EqualsModProperty { /** @@ -92,8 +94,11 @@ public interface SourceElement extends SVSubstitute { * seen as {int decl_1; decl_1=0;} for the first one but {int decl_1; i=0;} for the second one. * These are not syntactical equal, therefore false is returned. */ - boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat); - - - + @Override + default boolean equalsModProperty(Object o, Property property, V... v) { + if (!(o instanceof SourceElement)) { + return false; + } + return property.equalsModThisProperty(this, (SourceElement) o, v); + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java index af803193741..84bd93a65c2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/Term.java @@ -43,7 +43,7 @@ * supported: {@link Term#execPostOrder(Visitor)} and {@link Term#execPreOrder(Visitor)}. */ public interface Term - extends SVSubstitute, Sorted, EqualsModProperty, org.key_project.logic.Term { + extends SVSubstitute, Sorted, EqualsModProperty, org.key_project.logic.Term { @Override Operator op(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java index eb894cf687d..66dcd1494fd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/TermImpl.java @@ -347,7 +347,7 @@ protected int computeHashCode() { } @Override - public boolean equalsModProperty(Object o, Property property, Void... v) { + public boolean equalsModProperty(Object o, Property property, V... v) { if (!(o instanceof Term other)) { return false; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index c3a18450df6..03f4860e62c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -7,11 +7,10 @@ * Interface to check for equality ignoring given properties and to compute according hash codes. * * @param the type of the objects that are checked for equality or hashed - * @param the type of additional arguments needed for the equality check * * @author Tobias Reinhold */ -public interface EqualsModProperty { +public interface EqualsModProperty { /** * Checks whether this object is equal to {@code o} modulo the property described by @@ -19,10 +18,11 @@ public interface EqualsModProperty { * * @param o the object that is checked for equality * @param property the property to be ignored in the equality check + * @param v the additional arguments needed for the equality check * @return whether this object is equal to o */ - boolean equalsModProperty(Object o, Property property, V... v); + boolean equalsModProperty(Object o, Property property, V... v); /** * Computes the hash code according to the given ignored {@code property}. diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 8b9ea38fb30..759a53aa7cc 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -34,12 +34,14 @@ private IrrelevantTermLabelsProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} + * @param v the additional parameters needed for the comparison * @return {@code true} iff {@code term2} is a term syntactically equal to {@code term1}, except * for their irrelevant labels. + * @param the type of the additional parameters needed for the comparison * @see TermLabel#isProofRelevant() isStrategyRelevant */ @Override - public boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2, V... v) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index f35fecb9c28..ea733323e26 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -43,11 +43,13 @@ private ProofIrrelevancyProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} + * @param v the additional parameters needed for the comparison * @return true iff {@code term2} is a term syntactically equal to {@code term1}, except for * proof-irrelevant attributes. + * @param the type of the additional parameters needed for the comparison */ @Override - public boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2, V... v) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java index a0709e82687..a42b3a51e91 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java @@ -12,6 +12,7 @@ * properties. * * @param the type of the objects that are checked for equality or hashed + * * @author Tobias Reinhold */ public interface Property { @@ -20,13 +21,14 @@ public interface Property { * * @param t1 the first element of the equality check * @param t2 the second element of the equality check + * @param v the additional arguments needed for the equality check * @return whether {@code t1} and {@code t2} are equal ignoring a certain property */ - boolean equalsModThisProperty(T t1, T t2); + boolean equalsModThisProperty(T t1, T t2, V... v); /** * Computes the hash code of {@code t} in a context where - * {@link this#equalsModThisProperty(Object, Object)} + * {@link this#equalsModThisProperty(Object, Object, Object[])} * is used as an equality check, so that it can be used in, e.g., a HashMap. * * @param t the object to compute the hash code for diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 45ec2ce2008..275b7e7c87f 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -4,6 +4,7 @@ package de.uka.ilkd.key.logic.equality; import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.visitor.JavaASTTreeWalker; @@ -28,8 +29,21 @@ public class RenamingSourceElementProperty implements Property { */ private RenamingSourceElementProperty() {} + /** + * Checks if {@code se2} is a source element syntactically equal to {@code se1} modulo renaming. + * + * @param se1 the first element of the equality check + * @param se2 the second element of the equality check + * @param v the additional arguments needed for the equality check + * @return {@code true} iff {@code se2} is a source element syntactically equal to {@code se1} + * modulo renaming + * @param the type of the additional parameters needed for the comparison + */ @Override - public boolean equalsModThisProperty(SourceElement se1, SourceElement se2) { + public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V... v) { + // For this equality check, v must be a single NameAbstractionTable + NameAbstractionTable nat = (NameAbstractionTable) v[0]; + JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index d827249bb3b..085205158ab 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -35,11 +35,14 @@ private RenamingTermProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} - * @return true iff {@code term2} has the same values in operator, sort, arity, varsBoundHere + * @param v the additional parameters needed for the comparison + * @return {@code true} iff {@code term2} has the same values in operator, sort, arity, + * varsBoundHere * and javaBlock as {@code term1} modulo bound renaming + * @param the type of the additional parameters needed for the comparison */ @Override - public boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2, V... v) { if (term2 == term1) { return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 889a2bd1567..757c5b79045 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -31,12 +31,14 @@ private TermLabelsProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} + * @param v the additional parameters needed for the comparison * @return {@code true} iff {@code term2} is a term syntactically equal to {@code term1} * ignoring all * term labels + * @param the type of the additional parameters needed for the comparison */ @Override - public boolean equalsModThisProperty(Term term1, Term term2) { + public boolean equalsModThisProperty(Term term1, Term term2, V... v) { if (term2 == term1) { return true; } diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 1109f927200..4bff9a07a1d 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -289,8 +289,8 @@ public void proofIrrelevancy() { @Test public void renamingSourceElements() { - Term match1 = TacletForTests.parseTerm("\\<{ int i; }\\>true"); - Term match2 = TacletForTests.parseTerm("\\<{ int i; }\\>true"); + Term match1 = TacletForTests.parseTerm("\\<{ int i; int j; }\\>true"); + Term match2 = TacletForTests.parseTerm("\\<{ int i; int k; }\\>true"); assertTrue( match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (0)."); From ffdb2d7366dc3d231ab617062fd484746e1aec4b Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 17 Mar 2024 19:52:00 +0100 Subject: [PATCH 21/73] fix doc --- .../java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java | 1 + .../src/main/java/de/uka/ilkd/key/logic/equality/Property.java | 1 + 2 files changed, 2 insertions(+) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index 03f4860e62c..d5a3b71f6c0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -20,6 +20,7 @@ public interface EqualsModProperty { * @param property the property to be ignored in the equality check * @param v the additional arguments needed for the equality check * @return whether this object is equal to o + * @param the type of the additional parameters needed for the comparison */ boolean equalsModProperty(Object o, Property property, V... v); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java index a42b3a51e91..c0c0e267df4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/Property.java @@ -23,6 +23,7 @@ public interface Property { * @param t2 the second element of the equality check * @param v the additional arguments needed for the equality check * @return whether {@code t1} and {@code t2} are equal ignoring a certain property + * @param the type of the additional parameters needed for the comparison */ boolean equalsModThisProperty(T t1, T t2, V... v); From e6003e8e93b23c8ea552d787c56eb1f2eea9a525 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 18 Mar 2024 15:00:04 +0100 Subject: [PATCH 22/73] remove equalsModRenaming from all Literal classes --- .../literal/AbstractIntegerLiteral.java | 12 ++++-------- .../expression/literal/BooleanLiteral.java | 18 +++++++----------- .../java/expression/literal/DoubleLiteral.java | 17 ++++++----------- .../expression/literal/EmptyMapLiteral.java | 4 +--- .../expression/literal/EmptySeqLiteral.java | 6 +----- .../expression/literal/EmptySetLiteral.java | 6 +----- .../java/expression/literal/FloatLiteral.java | 17 ++++++----------- .../java/expression/literal/FreeLiteral.java | 10 +++++++++- .../java/expression/literal/NullLiteral.java | 5 +++++ .../java/expression/literal/RealLiteral.java | 13 ++++++------- .../java/expression/literal/StringLiteral.java | 11 ++++++----- 11 files changed, 52 insertions(+), 67 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/AbstractIntegerLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/AbstractIntegerLiteral.java index e6f2fccbb33..5b5c29f7a36 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/AbstractIntegerLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/AbstractIntegerLiteral.java @@ -3,8 +3,6 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.expression.Literal; import de.uka.ilkd.key.ldt.IntegerLDT; @@ -51,12 +49,10 @@ protected AbstractIntegerLiteral(ExtList children) { @Override public boolean equals(Object o) { - return super.equals(o); - } - - @Override - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o.getClass() == this.getClass())) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } return ((AbstractIntegerLiteral) o).getValue() == getValue(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/BooleanLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/BooleanLiteral.java index 5bc482b286f..958e44be1c8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/BooleanLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/BooleanLiteral.java @@ -103,16 +103,6 @@ public String getName() { return (value ? "true" : "false"); } - /** - * tests if equals - */ - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o instanceof BooleanLiteral)) { - return false; - } - return ((BooleanLiteral) o).getValue() == getValue(); - } - @Override protected int computeHashCode() { return 37 * super.computeHashCode() + (getValue() ? 0 : 1); @@ -120,7 +110,13 @@ protected int computeHashCode() { @Override public boolean equals(Object o) { - return super.equals(o); + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { + return false; + } + return ((BooleanLiteral) o).getValue() == getValue(); } /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/DoubleLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/DoubleLiteral.java index 04763c3085d..606317b452e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/DoubleLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/DoubleLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -69,11 +67,12 @@ public DoubleLiteral(String value) { this.value = value; } - /** - * tests if equals - */ - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o instanceof DoubleLiteral)) { + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } return ((DoubleLiteral) o).getValue().equals(getValue()); @@ -84,10 +83,6 @@ protected int computeHashCode() { return 37 * super.computeHashCode() + getValue().hashCode(); } - public boolean equals(Object o) { - return super.equals(o); - } - /** * Get value. * diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java index 14f8cf1eec5..b923423cf69 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -22,7 +20,7 @@ private EmptyMapLiteral() { } @Override - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { + public boolean equals(Object o) { return o == this; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java index 842a150bf67..518a7043587 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -22,13 +20,11 @@ public class EmptySeqLiteral extends Literal { private EmptySeqLiteral() {} - @Override - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { + public boolean equals(Object o) { return o == this; } - public void visit(Visitor v) { v.performActionOnEmptySeqLiteral(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java index 760c5b9d2cb..7ea29d65dbe 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -20,13 +18,11 @@ public class EmptySetLiteral extends Literal { public static final EmptySetLiteral LOCSET = new EmptySetLiteral(); - @Override - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { + public boolean equals(Object o) { return o == this; } - public void visit(Visitor v) { v.performActionOnEmptySetLiteral(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FloatLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FloatLiteral.java index 9cfd3e20742..e72f26fb21e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FloatLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FloatLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -61,11 +59,12 @@ public FloatLiteral(String value) { this.value = value; } - /** - * tests if equals - */ - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o instanceof FloatLiteral)) { + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } return ((FloatLiteral) o).getValue().equals(getValue()); @@ -76,10 +75,6 @@ protected int computeHashCode() { return 37 * super.computeHashCode() + getValue().hashCode(); } - public boolean equals(Object o) { - return super.equals(o); - } - /** * Get value. * diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java index 342942214bb..4ef309c9915 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java @@ -16,10 +16,18 @@ public class FreeLiteral extends Literal { public final static FreeLiteral INSTANCE = new FreeLiteral(); + private FreeLiteral() { + super(); + } + + @Override + public boolean equals(Object o) { + return o == this; + } + @Override public void visit(Visitor v) { // TODO Auto-generated method stub - } @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java index 41f31b60e9b..73f7337b802 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java @@ -25,6 +25,11 @@ private NullLiteral() { super(); } + @Override + public boolean equals(Object o) { + return o == this; + } + /** * calls the corresponding method of a visitor in order to perform some action/transformation on * this element diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/RealLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/RealLiteral.java index 0df6fadc4e0..d9d31fe0965 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/RealLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/RealLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.abstraction.PrimitiveType; import de.uka.ilkd.key.java.expression.Literal; @@ -69,11 +67,12 @@ public RealLiteral(String value) { this.value = value; } - /** - * tests if equals - */ - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o instanceof RealLiteral)) { + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } return ((RealLiteral) o).getValue().equals(getValue()); diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/StringLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/StringLiteral.java index adfa9153590..3864378fcdb 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/StringLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/StringLiteral.java @@ -3,9 +3,7 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.expression.literal; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.Services; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.abstraction.KeYJavaType; import de.uka.ilkd.key.java.expression.Literal; import de.uka.ilkd.key.java.reference.ReferencePrefix; @@ -41,9 +39,12 @@ public StringLiteral(ExtList children, String value) { this.value = value; } - - public boolean equalsModRenaming(SourceElement o, NameAbstractionTable nat) { - if (!(o instanceof StringLiteral)) { + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } return ((StringLiteral) o).getValue().equals(getValue()); From 5136b532700c37270e04ee48c3f3c78c74e0fa03 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 18 Mar 2024 15:01:09 +0100 Subject: [PATCH 23/73] add default implementation of hashCodeModProperty to SourceElement --- .../src/main/java/de/uka/ilkd/key/java/SourceElement.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java index 55104738d5b..2b8f19660b0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java @@ -101,4 +101,9 @@ default boolean equalsModProperty(Object o, Property property } return property.equalsModThisProperty(this, (SourceElement) o, v); } + + @Override + default int hashCodeModProperty(Property property) { + return property.hashCodeModThisProperty(this); + } } From fe5640752ad274728853afff51049cc4df502401 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 18 Mar 2024 20:05:33 +0100 Subject: [PATCH 24/73] remove more implementations of equalsModRenaming --- .../de/uka/ilkd/key/java/StatementBlock.java | 49 +++++++++--------- .../declaration/VariableSpecification.java | 22 ++++---- .../key/java/statement/LabeledStatement.java | 51 +++++++++---------- .../java/statement/TransactionStatement.java | 19 +++---- .../de/uka/ilkd/key/logic/op/ProgramSV.java | 8 --- 5 files changed, 71 insertions(+), 78 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java b/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java index 6d0c95695c8..aa3f00d3c89 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java @@ -20,7 +20,6 @@ /** * Statement block. taken from COMPOST and changed to achieve an immutable structure */ - public class StatementBlock extends JavaStatement implements StatementContainer, TypeDeclarationContainer, VariableScope, TypeScope, ProgramPrefix { @@ -46,7 +45,6 @@ public StatementBlock() { * * @param children an ExtList that contains the children */ - public StatementBlock(ExtList children) { super(children); body = new ImmutableArray<>(children.collect(Statement.class)); @@ -75,13 +73,30 @@ public StatementBlock(Statement... body) { } @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return super.equalsModRenaming(se, nat) - && (this.getStartPosition().equals(Position.UNDEFINED) || // why do we care here - // about position info and - // nowhere else? - se.getStartPosition().equals(Position.UNDEFINED) - || this.getStartPosition().line() == se.getStartPosition().line()); + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { + return false; + } + + final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) o; + if (jnte.getChildCount() != getChildCount()) { + return false; + } + + for (int i = 0, cc = getChildCount(); i < cc; i++) { + if (!getChildAt(i).equals(jnte.getChildAt(i))) { + return false; + } + } + + return (this.getStartPosition().equals(Position.UNDEFINED) || // why do we care here + // about position info and + // nowhere else? + jnte.getStartPosition().equals(Position.UNDEFINED) + || this.getStartPosition().line() == jnte.getStartPosition().line()); } /** computes the prefix elements for the given array of statment block */ @@ -98,14 +113,11 @@ public static ImmutableArray computePrefixElements( return new ImmutableArray<>(prefix); } - - /** * Get body. * * @return the statement array wrapper. */ - public ImmutableArray getBody() { return body; } @@ -114,13 +126,11 @@ public final boolean isEmpty() { return body.isEmpty(); } - /** * Returns the number of children of this node. * * @return an int giving the number of children of this node */ - public int getChildCount() { return body.size(); } @@ -132,7 +142,6 @@ public int getChildCount() { * @return the program element at the given position * @exception ArrayIndexOutOfBoundsException if index is out of bounds */ - public ProgramElement getChildAt(int index) { if (body != null) { return body.get(index); @@ -145,12 +154,11 @@ public ProgramElement getChildAt(int index) { * * @return the number of statements. */ - public int getStatementCount() { return body.size(); } - /* + /** * Return the statement at the specified index in this node's "virtual" statement array. * * @param index an index for a statement. @@ -159,7 +167,6 @@ public int getStatementCount() { * * @exception ArrayIndexOutOfBoundsException if index is out of bounds. */ - public Statement getStatementAt(int index) { if (body != null) { return body.get(index); @@ -172,7 +179,6 @@ public Statement getStatementAt(int index) { * * @return the number of type declarations. */ - public int getTypeDeclarationCount() { int count = 0; if (body != null) { @@ -185,7 +191,7 @@ public int getTypeDeclarationCount() { return count; } - /* + /** * Return the type declaration at the specified index in this node's "virtual" type declaration * array. * @@ -195,7 +201,6 @@ public int getTypeDeclarationCount() { * * @exception ArrayIndexOutOfBoundsException if index is out of bounds. */ - public TypeDeclaration getTypeDeclarationAt(int index) { if (body != null) { int s = body.size(); @@ -222,7 +227,6 @@ public void visit(Visitor v) { v.performActionOnStatementBlock(this); } - public SourceElement getFirstElement() { if (isEmpty()) { return this; @@ -240,7 +244,6 @@ public SourceElement getFirstElementIncludingBlocks() { } } - @Override public boolean hasNextPrefixElement() { return body.size() != 0 && (body.get(0) instanceof ProgramPrefix); diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java index 787cf6b874e..b8566333c05 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java @@ -257,16 +257,17 @@ public void visit(Visitor v) { v.performActionOnVariableSpecification(this); } - /** - * equals modulo renaming is described in the corresponding comment in class SourceElement. The - * variables declared in the local variable declaration have to be added to the - * NameAbstractionTable. - */ @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - if (!(se instanceof VariableSpecification vs)) { + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { return false; } + + VariableSpecification vs = (VariableSpecification) o; + if (dimensions != vs.getDimensions()) { return false; } @@ -279,12 +280,15 @@ public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { return false; } } - nat.add(var, vs.getProgramVariable()); + + // TODO: add this in treewalker: + // nat.add(var, vs.getProgramVariable()); + if (vs.getChildCount() != getChildCount()) { return false; } for (int i = 0, cc = getChildCount(); i < cc; i++) { - if (!getChildAt(i).equalsModRenaming(vs.getChildAt(i), nat)) { + if (!getChildAt(i).equals(vs.getChildAt(i))) { return false; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java index 7a8fffc97ca..fb18d4840f1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java @@ -15,20 +15,17 @@ /** * Labeled statement. */ - public class LabeledStatement extends JavaStatement implements StatementContainer, NamedProgramElement, ProgramPrefix { /** * Name. */ - protected final Label name; /** * Body. */ - protected final Statement body; @@ -66,7 +63,6 @@ public LabeledStatement(ExtList children, Label label, PositionInfo pos) { * * @param name an identifier. */ - public LabeledStatement(Label name) { this.name = name; body = new EmptyStatement(); @@ -84,7 +80,6 @@ public LabeledStatement(Label name) { * @param id a Label. * @param statement a statement. */ - public LabeledStatement(Label id, Statement statement, PositionInfo pos) { super(pos); this.name = id; @@ -167,7 +162,6 @@ public SourceElement getLastElement() { * * @return the string. */ - public final String getName() { return (name == null) ? null : name.toString(); } @@ -177,7 +171,6 @@ public final String getName() { * * @return the identifier. */ - public Label getLabel() { return name; } @@ -210,7 +203,6 @@ public Statement getBody() { * * @return an int giving the number of children of this node */ - public int getChildCount() { int result = 0; if (name != null) { @@ -229,7 +221,6 @@ public int getChildCount() { * @return the program element at the given position * @exception ArrayIndexOutOfBoundsException if index is out of bounds */ - public ProgramElement getChildAt(int index) { if (name != null) { if (index == 0) { @@ -251,7 +242,6 @@ public ProgramElement getChildAt(int index) { * * @return the number of statements. */ - public int getStatementCount() { return (body != null) ? 1 : 0; } @@ -263,7 +253,6 @@ public int getStatementCount() { * @return the statement with the given index. * @exception ArrayIndexOutOfBoundsException if index is out of bounds. */ - public Statement getStatementAt(int index) { if (body != null && index == 0) { return body; @@ -271,6 +260,31 @@ public Statement getStatementAt(int index) { throw new ArrayIndexOutOfBoundsException(); } + @Override + public boolean equals(Object o) { + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { + return false; + } + + // TODO: do this in the treewalker: + // final LabeledStatement lSt = (LabeledStatement) se; + // nat.add(name, lSt.name); + + final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) o; + if (jnte.getChildCount() != getChildCount()) { + return false; + } + for (int i = 0, cc = getChildCount(); i < cc; i++) { + if (!getChildAt(i).equals(jnte.getChildAt(i))) { + return false; + } + } + return true; + } + /** * calls the corresponding method of a visitor in order to perform some action/transformation on * this element @@ -281,21 +295,6 @@ public void visit(Visitor v) { v.performActionOnLabeledStatement(this); } - /** - * testing if programelements are equal modulo renaming abstract from names. Therefore - * declaration of label names have to be mapped to the same abstract name. This is done here. - */ - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - if (se == null || this.getClass() != se.getClass()) { - return false; - } - - final LabeledStatement lSt = (LabeledStatement) se; - - nat.add(name, lSt.name); - return super.equalsModRenaming(lSt, nat); - } - public PosInProgram getFirstActiveChildPos() { return firstActiveChildPos; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/statement/TransactionStatement.java b/key.core/src/main/java/de/uka/ilkd/key/java/statement/TransactionStatement.java index 00c17a5e034..290a6401408 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/statement/TransactionStatement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/statement/TransactionStatement.java @@ -3,10 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.java.statement; -import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.java.SourceData; -import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.visitor.Visitor; import de.uka.ilkd.key.rule.MatchConditions; @@ -51,14 +49,17 @@ public String toString() { return names[type - 1]; } + @Override public boolean equals(Object o) { - if (o instanceof TransactionStatement) { - return ((TransactionStatement) o).type == this.type; + if (o == this) { + return true; + } + if (o == null || o.getClass() != this.getClass()) { + return false; } - return false; + return ((TransactionStatement) o).type == this.type; } - public MatchConditions match(SourceData source, MatchConditions conditions) { if (this.equals(source.getSource())) { source.next(); @@ -66,10 +67,4 @@ public MatchConditions match(SourceData source, MatchConditions conditions) { } return null; } - - public boolean equalsModRenaming(SourceElement source, NameAbstractionTable nat) { - return this.equals(source); - } - - } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramSV.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramSV.java index ef86b0009ce..cdbb018c2e5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramSV.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramSV.java @@ -54,14 +54,6 @@ public boolean isListSV() { return isListSV; } - /** - * this method tests on object identity - */ - @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return se == this; - } - /** * @return comments if the schemavariable stands for programm construct and has comments * attached to it (not supported yet) From 281dd3c009b4caaf8de3e2112ce7577ee2e79d9a Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 25 Mar 2024 19:52:17 +0100 Subject: [PATCH 25/73] remove even more implementations of equalsModRenaming --- .../java/de/uka/ilkd/key/java/Comment.java | 12 +++------- .../java/JavaNonTerminalProgramElement.java | 23 ++++++------------- .../de/uka/ilkd/key/java/StatementBlock.java | 2 ++ .../key/java/declaration/TypeDeclaration.java | 10 ++++++++ .../ilkd/key/logic/ProgramElementName.java | 17 -------------- .../ilkd/key/logic/op/ProgramVariable.java | 12 ---------- .../logic/equality/TestEqualsModProperty.java | 5 ++-- 7 files changed, 25 insertions(+), 56 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/Comment.java b/key.core/src/main/java/de/uka/ilkd/key/java/Comment.java index 0d556acb369..affdef25096 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/Comment.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/Comment.java @@ -43,25 +43,19 @@ public String getText() { return text; } - + @Override public String toString() { return getText(); } - - /** - * comments can be ignored - */ - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return true; - } - + @Override public int hashCode() { int result = 17; result = 37 * result + getText().hashCode(); return result; } + @Override public boolean equals(Object o) { if (o == this) { return true; diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/JavaNonTerminalProgramElement.java b/key.core/src/main/java/de/uka/ilkd/key/java/JavaNonTerminalProgramElement.java index ded5c975478..9ad160c6b1b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/JavaNonTerminalProgramElement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/JavaNonTerminalProgramElement.java @@ -55,37 +55,28 @@ protected int getArrayPos(ImmutableArray arr, ProgramElement el) return -1; } - - /** - * commented in interface SourceElement. Overwrites the default method implementation in - * ProgramElement by descending down to the children. - */ - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - - if (se == this) { + @Override + public boolean equals(Object o) { + if (o == this) { return true; - } else if (se == null || this.getClass() != se.getClass()) { + } + if (o == null || o.getClass() != this.getClass()) { return false; } - final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) se; + final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) o; if (jnte.getChildCount() != getChildCount()) { return false; } for (int i = 0, cc = getChildCount(); i < cc; i++) { - if (!getChildAt(i).equalsModRenaming(jnte.getChildAt(i), nat)) { + if (!getChildAt(i).equals(jnte.getChildAt(i))) { return false; } } return true; } - @Override - public boolean equals(Object o) { - return super.equals(o); - } - @Override protected int computeHashCode() { int localHash = 17 * super.computeHashCode(); diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java b/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java index aa3f00d3c89..3aed53cad25 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/StatementBlock.java @@ -95,6 +95,8 @@ public boolean equals(Object o) { return (this.getStartPosition().equals(Position.UNDEFINED) || // why do we care here // about position info and // nowhere else? + // We also care in + // LoopStatement jnte.getStartPosition().equals(Position.UNDEFINED) || this.getStartPosition().line() == jnte.getStartPosition().line()); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java index ffa57dc1440..83bcef20307 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java @@ -363,4 +363,14 @@ public boolean equals(Object o) { return false; } } + + @Override + public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { + return super.equalsModRenaming(se, nat); + } + + @Override + public ProgramElement getChildAt(int index) { + return null; + } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/ProgramElementName.java b/key.core/src/main/java/de/uka/ilkd/key/logic/ProgramElementName.java index 67acf1b8591..627cb288e29 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/ProgramElementName.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/ProgramElementName.java @@ -94,7 +94,6 @@ public SourceElement getFirstElementIncludingBlocks() { return getFirstElement(); } - /** * to be compatible to a ProgramElement */ @@ -112,7 +111,6 @@ public void visit(Visitor v) { v.performActionOnProgramElementName(this); } - /** * Returns the start position of the primary token of this element. To get the start position of * the syntactical first token, call the corresponding method of getFirstElement(). @@ -144,25 +142,10 @@ public recoder.java.SourceElement.Position getRelativePosition() { return recoder.java.SourceElement.Position.UNDEFINED; } - public PositionInfo getPositionInfo() { return PositionInfo.UNDEFINED; } - - /** - * equals modulo renaming is described in the corresponding comment in class SourceElement. The - * ProgramElementName has to check if an abstract name has been assigned and if, if both - * elements are assigned to the same name, otherwise the names have to be equal - */ - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - if (!(se instanceof ProgramElementName)) { - return false; - } - return nat.sameAbstractName(this, se); - } - - public String getQualifier() { return qualifierString; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramVariable.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramVariable.java index 625e4c3f32a..e5b275ed12c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramVariable.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramVariable.java @@ -204,18 +204,6 @@ public ReferencePrefix getReferencePrefix() { return null; } - - /** - * equals modulo renaming is described in the corresponding comment in class SourceElement. In - * this case two programvariables are considered to be equal if they are assigned to the same - * abstract name or if they are the same object. - */ - @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return nat.sameAbstractName(this, se); - } - - @Override public Expression convertToProgram(Term t, ExtList l) { if (isStatic()) { diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 4bff9a07a1d..edce6f7faa8 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -299,7 +299,8 @@ public void renamingSourceElements() { StringLiteral stringLiteral = new StringLiteral("testStringLiteral"); // This seems very bad as equalsModRenaming is seemingly NOT symmetric!!! - assertTrue(testComment.equalsModRenaming(stringLiteral, null)); - assertFalse(stringLiteral.equalsModRenaming(testComment, null)); + // assertTrue(testComment.equalsModRenaming(stringLiteral, null)); + // assertFalse(stringLiteral.equalsModRenaming(testComment, null)); + // Currently, } } From 26bc6344a169cf1a9f2fd4e3d47c695eb25545b7 Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 4 Apr 2024 16:51:34 +0200 Subject: [PATCH 26/73] remove the last implementations of equalsModRenaming in inheritors of SourceElement --- .../de/uka/ilkd/key/java/JavaProgramElement.java | 15 ++------------- .../key/java/declaration/TypeDeclaration.java | 10 ---------- .../main/java/de/uka/ilkd/key/ldt/FreeLDT.java | 2 +- .../de/uka/ilkd/key/logic/op/ProgramMethod.java | 9 +++------ .../key/logic/equality/TestEqualsModProperty.java | 2 +- 5 files changed, 7 insertions(+), 31 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/JavaProgramElement.java b/key.core/src/main/java/de/uka/ilkd/key/java/JavaProgramElement.java index 4a6697b0328..102ecee7489 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/JavaProgramElement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/JavaProgramElement.java @@ -78,16 +78,6 @@ public Comment[] getComments() { return comments; } - - /** - * commented in interface SourceElement. The default equals method compares two elements by - * testing if they have the same type and calling the default equals method. - */ - @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return (this.getClass() == se.getClass()); - } - protected int computeHashCode() { int result = 17 * this.getClass().hashCode(); return result; @@ -114,11 +104,10 @@ public boolean equals(Object o) { if (o == this) { return true; } - if (o == null || o.getClass() != this.getClass()) { + if (o == null) { return false; } - - return equalsModRenaming((JavaProgramElement) o, NameAbstractionTableDisabled.INSTANCE); + return (this.getClass() == o.getClass()); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java index 83bcef20307..ffa57dc1440 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/TypeDeclaration.java @@ -363,14 +363,4 @@ public boolean equals(Object o) { return false; } } - - @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - return super.equalsModRenaming(se, nat); - } - - @Override - public ProgramElement getChildAt(int index) { - return null; - } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java b/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java index 58b49471584..00701a9dae8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java +++ b/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java @@ -22,7 +22,7 @@ * Generic data type, which has no predefined theory. It is meant as a basis to implement an * additional abstract data type, e.g., binary trees, stacks, etc. in .key files. * - * @author daniel + * @author Daniel Bruns * */ public final class FreeLDT extends LDT { diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramMethod.java b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramMethod.java index a86db464202..d80bfb2c81c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramMethod.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/op/ProgramMethod.java @@ -266,16 +266,13 @@ public ProgramElement getChildAt(int i) { return null; } - /** - * equals modulo renaming is described in class SourceElement. - */ @Override - public boolean equalsModRenaming(SourceElement se, NameAbstractionTable nat) { - if (!(se instanceof IProgramMethod)) { + public boolean equals(Object obj) { + if (!(obj instanceof IProgramMethod ipm)) { return false; } - return method == ((IProgramMethod) se).getMethodDeclaration(); + return method == ipm.getMethodDeclaration(); } @Deprecated diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index edce6f7faa8..85debccb260 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -289,7 +289,7 @@ public void proofIrrelevancy() { @Test public void renamingSourceElements() { - Term match1 = TacletForTests.parseTerm("\\<{ int i; int j; }\\>true"); + Term match1 = TacletForTests.parseTerm("\\<{ int i; int j; /*Test*/ }\\>true"); Term match2 = TacletForTests.parseTerm("\\<{ int i; int k; }\\>true"); assertTrue( match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), From 0ae1c39738097a25336b0c49f9aab6fc874c3802 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 5 Apr 2024 15:46:05 +0200 Subject: [PATCH 27/73] use equalsModProperty instead of equalsModRenaming --- .../uka/ilkd/key/logic/equality/RenamingTermProperty.java | 6 ++++-- .../strategy/quantifierHeuristics/EqualityConstraint.java | 5 ++++- .../de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java | 7 +++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index 085205158ab..736aa85857b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -12,6 +12,8 @@ import org.key_project.util.collection.ImmutableList; import org.key_project.util.collection.ImmutableSLList; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; + /** * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. @@ -143,7 +145,7 @@ private boolean unifyHelp(Term t0, Term t1, ImmutableList if (!(op0 instanceof SchemaVariable) && op0 instanceof ProgramVariable pv0) { if (op1 instanceof ProgramVariable pv1) { nat = checkNat(nat); - if (!pv0.equalsModRenaming(pv1, nat)) { + if (!pv0.equalsModProperty(pv1, RENAMING_SOURCE_ELEMENT_PROPERTY, nat)) { return false; } } else { @@ -200,7 +202,7 @@ public static boolean javaBlocksNotEqualModRenaming(JavaBlock jb1, JavaBlock jb2 if (pe1 == null && pe2 == null) { return false; } else if (pe1 != null && pe2 != null) { - return !pe1.equalsModRenaming(pe2, nat); + return !pe1.equalsModProperty(pe2, RENAMING_SOURCE_ELEMENT_PROPERTY, nat); } return true; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java index da934fd3a3f..f77ca51a50b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java +++ b/key.core/src/main/java/de/uka/ilkd/key/strategy/quantifierHeuristics/EqualityConstraint.java @@ -27,6 +27,8 @@ import org.key_project.util.collection.ImmutableSLList; import org.key_project.util.collection.ImmutableSet; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; + /** * This class implements a persistent constraint. The constraint contains pairs of Metavariables X @@ -425,7 +427,8 @@ private static NameAbstractionTable handleJava(Term t0, Term t1, NameAbstraction return FAILED; } nat = checkNat(nat); - if (!((ProgramVariable) t0.op()).equalsModRenaming((ProgramVariable) t1.op(), nat)) { + if (!((ProgramVariable) t0.op()).equalsModProperty(t1.op(), + RENAMING_SOURCE_ELEMENT_PROPERTY, nat)) { return FAILED; } } diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java b/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java index ac9488419d8..6a407e7cc7d 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/mergerule/MergeRuleUtils.java @@ -45,6 +45,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; /** @@ -821,7 +822,8 @@ public static boolean equalsModBranchUniqueRenaming(SourceElement se1, SourceEle // Quick short cut for the special case where no program variables // have to be renamed. - if (se1.equalsModRenaming(se2, new NameAbstractionTable())) { + if (se1.equalsModProperty(se2, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable())) { return true; } @@ -836,7 +838,8 @@ public static boolean equalsModBranchUniqueRenaming(SourceElement se1, SourceEle replVisitor1.start(); replVisitor2.start(); - return replVisitor1.result().equalsModRenaming(replVisitor2.result(), + return replVisitor1.result().equalsModProperty(replVisitor2.result(), + RENAMING_SOURCE_ELEMENT_PROPERTY, new NameAbstractionTable()); } From e909f858b20abf274e59c6b229e5ad95c7210510 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 9 Apr 2024 16:53:23 +0200 Subject: [PATCH 28/73] change equalsModRenaming to equalsModProperty --- .../test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java index 26a5f9f96ce..a1df0325dca 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java @@ -26,6 +26,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static org.junit.jupiter.api.Assertions.*; @@ -848,7 +849,9 @@ public void testContextAdding() { goals.head().sequent().getFormulabyNr(1).formula().javaBlock().program(); // FIXME weigl: This test case is spurious: // actual.toString() == expected.toString() but internally there is a difference. - assertTrue(expected.equalsModRenaming(is, new NameAbstractionTable()), + assertTrue( + expected.equalsModProperty(is, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable()), "Expected:" + expected + "\n but was:" + is); } @@ -882,7 +885,9 @@ public void testRemoveEmptyBlock() { ProgramElement is = goals.head().sequent().getFormulabyNr(1).formula().javaBlock().program(); - assertTrue(expected.equalsModRenaming(is, new NameAbstractionTable()), + assertTrue( + expected.equalsModProperty(is, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable()), "Expected:" + expected + "\n but was:" + is); } From d70867e3222679cdf0a3d20bba06f44d451a24f9 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 11 Apr 2024 19:16:11 +0200 Subject: [PATCH 29/73] handle more special cases in RenamingSourceElementProperty --- .../declaration/VariableSpecification.java | 3 - .../key/java/statement/LabeledStatement.java | 4 - .../RenamingSourceElementProperty.java | 82 +++++++++++++++++-- 3 files changed, 76 insertions(+), 13 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java index b8566333c05..dce692a4d7c 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/declaration/VariableSpecification.java @@ -281,9 +281,6 @@ public boolean equals(Object o) { } } - // TODO: add this in treewalker: - // nat.add(var, vs.getProgramVariable()); - if (vs.getChildCount() != getChildCount()) { return false; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java index fb18d4840f1..a864d451754 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java @@ -269,10 +269,6 @@ public boolean equals(Object o) { return false; } - // TODO: do this in the treewalker: - // final LabeledStatement lSt = (LabeledStatement) se; - // nat.add(name, lSt.name); - final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) o; if (jnte.getChildCount() != getChildCount()) { return false; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 275b7e7c87f..7c02cd0ad51 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -3,9 +3,10 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic.equality; -import de.uka.ilkd.key.java.Comment; import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.declaration.VariableSpecification; +import de.uka.ilkd.key.java.statement.LabeledStatement; import de.uka.ilkd.key.java.visitor.JavaASTTreeWalker; /** @@ -42,6 +43,10 @@ private RenamingSourceElementProperty() {} @Override public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V... v) { // For this equality check, v must be a single NameAbstractionTable + if (v.length != 1 || !(v[0] instanceof NameAbstractionTable)) { + throw new IllegalArgumentException( + "Expected a single NameAbstractionTable as argument."); + } NameAbstractionTable nat = (NameAbstractionTable) v[0]; JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); @@ -51,9 +56,22 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V SourceElement next2 = tw2.getCurrentNode(); while (next1 != null && next2 != null) { - if (!next1.equals(next2)) { - return false; + // TODO: check all the different cases... + if (next1 instanceof LabeledStatement) { + if (!handleLabeledStatement((LabeledStatement) next1, next2, nat)) { + return false; + } + } else if (next1 instanceof VariableSpecification) { + if (!handleVariableSpecification((VariableSpecification) next1, next2, nat)) { + return false; + } + } else { + if (!handleStandard(next1, next2)) { + return false; + } } + + // pass onto the next nodes in the tree next1 = tw1.nextNode(); next2 = tw2.nextNode(); } @@ -63,14 +81,66 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V @Override public int hashCodeModThisProperty(SourceElement sourceElement) { - return 0; + throw new UnsupportedOperationException( + "Hashing of SourceElements modulo renaming not yet implemented!"); } - private boolean comparison(SourceElement se1, SourceElement se2) { + /* --------------------- Helper methods for special cases ---------------------- */ + + // TODO: maybe delete this method or document it to show design choices + private boolean handleStandard(SourceElement se1, SourceElement se2) { return se1.equals(se2); } - private boolean comparison(Comment comment, SourceElement se) { + private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, + NameAbstractionTable nat) { + if (se.getClass() != ls.getClass()) { + return false; + } + final LabeledStatement other = (LabeledStatement) se; + if (ls.getChildCount() != other.getChildCount()) { + return false; + } + nat.add(ls.getLabel(), ((LabeledStatement) se).getLabel()); + return true; + } + + private boolean handleVariableSpecification(VariableSpecification vs, SourceElement se, + NameAbstractionTable nat) { + // TODO: Checking for exact class might be too strict as the original implementation was + // only using instanceof + if (se.getClass() != vs.getClass()) { + return false; + } + final VariableSpecification other = (VariableSpecification) se; + if (vs.getChildCount() != other.getChildCount()) { + return false; + } + if (vs.getDimensions() != other.getDimensions()) { + return false; + } + if (vs.getType() != null) { + if (!vs.getType().equals(other.getType())) { + return false; + } + } else { + if (other.getType() != null) { + return false; + } + } + nat.add(vs.getProgramVariable(), other.getProgramVariable()); return true; } + + // This follows the (probably incorrect) prior implementation of the comparison on comments that + // is not symmetrical. + // Might not be needed for equalsModRenaming to be correct as comments seem to be filtered out + // of JavaBlocks. + /* + * private boolean handleComment(Comment comment, SourceElement se) { + * return true; + * } + */ + + /* ------------------ End of helper methods for special cases ------------------ */ } From 8aa72c34a854d65a2aae6fb1fc921e150734a8d7 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 12 Apr 2024 18:33:42 +0200 Subject: [PATCH 30/73] finish implementation of equalsModRenaming for SourceElements --- .../key/java/reference/PackageReference.java | 3 ++ .../RenamingSourceElementProperty.java | 43 ++++++++++++++++++- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/reference/PackageReference.java b/key.core/src/main/java/de/uka/ilkd/key/java/reference/PackageReference.java index fdccddd95cc..1400b752b3b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/reference/PackageReference.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/reference/PackageReference.java @@ -148,6 +148,9 @@ public ReferencePrefix setReferencePrefix(ReferencePrefix r) { } public boolean equals(Object o) { + if (o == this) { + return true; + } if (!(o instanceof PackageReference pr)) { return false; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 7c02cd0ad51..fa276793488 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -3,11 +3,14 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic.equality; +import de.uka.ilkd.key.java.JavaNonTerminalProgramElement; import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.declaration.VariableSpecification; import de.uka.ilkd.key.java.statement.LabeledStatement; import de.uka.ilkd.key.java.visitor.JavaASTTreeWalker; +import de.uka.ilkd.key.logic.ProgramElementName; +import de.uka.ilkd.key.logic.op.ProgramVariable; /** * A property that can be used in @@ -65,13 +68,22 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V if (!handleVariableSpecification((VariableSpecification) next1, next2, nat)) { return false; } + } else if (next1 instanceof ProgramVariable || next1 instanceof ProgramElementName) { + if (!handleProgramVariableOrElementName(next1, next2, nat)) { + return false; + } + } else if (next1 instanceof JavaNonTerminalProgramElement) { + if (!handleJavaNonTerminalProgramElements((JavaNonTerminalProgramElement) next1, + next2)) { + return false; + } } else { if (!handleStandard(next1, next2)) { return false; } } - // pass onto the next nodes in the tree + // walk to the next nodes in the tree next1 = tw1.nextNode(); next2 = tw2.nextNode(); } @@ -94,6 +106,9 @@ private boolean handleStandard(SourceElement se1, SourceElement se2) { private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, NameAbstractionTable nat) { + if (se == ls) { + return true; + } if (se.getClass() != ls.getClass()) { return false; } @@ -107,6 +122,9 @@ private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, private boolean handleVariableSpecification(VariableSpecification vs, SourceElement se, NameAbstractionTable nat) { + if (se == vs) { + return true; + } // TODO: Checking for exact class might be too strict as the original implementation was // only using instanceof if (se.getClass() != vs.getClass()) { @@ -132,6 +150,17 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem return true; } + private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElement se2, + NameAbstractionTable nat) { + // TODO: Checking for exact class might be too strict as the original implementation was + // only using instanceof + // or no check at all. Could be more efficient to check for classes first though. + if (se1.getClass() != se2.getClass()) { + return false; + } + return nat.sameAbstractName(se1, se2); + } + // This follows the (probably incorrect) prior implementation of the comparison on comments that // is not symmetrical. // Might not be needed for equalsModRenaming to be correct as comments seem to be filtered out @@ -142,5 +171,17 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem * } */ + private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramElement jnte, + SourceElement se) { + if (se == jnte) { + return true; + } + if (se.getClass() != jnte.getClass()) { + return false; + } + final JavaNonTerminalProgramElement other = (JavaNonTerminalProgramElement) se; + return jnte.getChildCount() == other.getChildCount(); + } + /* ------------------ End of helper methods for special cases ------------------ */ } From 162d149e43a596d2984da849f71800de4e122e6e Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 12 Apr 2024 19:39:55 +0200 Subject: [PATCH 31/73] add doc to RenamingSourceElementProperty --- .../RenamingSourceElementProperty.java | 108 +++++++++++++----- 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index fa276793488..ba15ff20e18 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -59,7 +59,7 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V SourceElement next2 = tw2.getCurrentNode(); while (next1 != null && next2 != null) { - // TODO: check all the different cases... + // Handle special cases of prior equalsModRenaming implementation if (next1 instanceof LabeledStatement) { if (!handleLabeledStatement((LabeledStatement) next1, next2, nat)) { return false; @@ -98,14 +98,66 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { } /* --------------------- Helper methods for special cases ---------------------- */ - - // TODO: maybe delete this method or document it to show design choices + /** + * Handles the standard case of comparing two {@link SourceElement}s modulo renaming. + * + * @param se1 the first {@link SourceElement} to be compared + * @param se2 the second {@link SourceElement} to be compared + * @return {@code true} iff the two source elements are equal under the standard {@code equals} + * method + */ private boolean handleStandard(SourceElement se1, SourceElement se2) { + /* + * As the prior implementations of equalsModRenaming for SourceElements were mostly the same + * as the normal equals method, we decided to move equalsModRenaming completely into the + * equals method and handle the special cases separately while walking through the tree that + * is a SourceElement. + */ return se1.equals(se2); } + /** + * Handles the special case of comparing a {@link JavaNonTerminalProgramElement} to a + * {@link SourceElement}. + * + * @param jnte the {@link JavaNonTerminalProgramElement} to be compared + * @param se the {@link SourceElement} to be compared + * @return {@code true} iff {@code se} is of the same class and has the same number of children + * as {@code jnte} + */ + private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramElement jnte, + SourceElement se) { + /* + * A JavaNonTerminalProgramElement is a special case of a SourceElement, as we must not + * traverse the children recursively. This is the case as we might have to add some entries + * of children nodes to a NameAbstractionTable so that they can be compared later on by the + * TreeWalker. + */ + if (se == jnte) { + return true; + } + if (se.getClass() != jnte.getClass()) { + return false; + } + final JavaNonTerminalProgramElement other = (JavaNonTerminalProgramElement) se; + return jnte.getChildCount() == other.getChildCount(); + } + + /** + * Handles the special case of comparing a {@link LabeledStatement} to a {@link SourceElement}. + * + * @param ls the {@link LabeledStatement} to be compared + * @param se the {@link SourceElement} to be compared + * @param nat the {@link NameAbstractionTable} the label of {@code ls} should be added to + * @return {@code true} iff {@code se} is also a {@link LabeledStatement} and has the same + * number of children as {@code ls} + */ private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, NameAbstractionTable nat) { + /* + * A LabeledStatement is a special case of a JavaNonTerminalProgramElement, as we must also + * not traverse the children recursively but also additionally add the label to a NAT. + */ if (se == ls) { return true; } @@ -120,8 +172,23 @@ private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, return true; } + /** + * Handles the special case of comparing a {@link VariableSpecification} to a + * {@link SourceElement}. + * + * @param vs the {@link VariableSpecification} to be compared + * @param se the {@link SourceElement} to be compared + * @param nat the {@link NameAbstractionTable} the variable of {@code vs} should be added to + * @return {@code true} iff {@code se} is of the same class as {@code vs} and has the same + * number of children, dimensions and type + */ private boolean handleVariableSpecification(VariableSpecification vs, SourceElement se, NameAbstractionTable nat) { + /* + * A VariableSpecification is a special case of a JavaNonTerminalProgramElement similar to + * LabeledStatement, but we also need to check the dimensions and type of the + * VariableSpecification. + */ if (se == vs) { return true; } @@ -150,38 +217,27 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem return true; } + /** + * Handles the special case of comparing a {@link ProgramVariable} or a + * {@link ProgramElementName} to a {@link SourceElement}. + * + * @param se1 the first {@link SourceElement} which is either a {@link ProgramVariable} or a + * {@link ProgramElementName} + * @param se2 the second {@link SourceElement} to be compared + * @param nat the {@link NameAbstractionTable} that should be used to check whether {@code se1} + * and {@code se2} have the same abstract name + * @return {@code true} iff {@code se1} and {@code se2} have the same abstract name + */ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElement se2, NameAbstractionTable nat) { // TODO: Checking for exact class might be too strict as the original implementation was - // only using instanceof - // or no check at all. Could be more efficient to check for classes first though. + // only using instanceof or no check at all. if (se1.getClass() != se2.getClass()) { return false; } return nat.sameAbstractName(se1, se2); } - // This follows the (probably incorrect) prior implementation of the comparison on comments that - // is not symmetrical. - // Might not be needed for equalsModRenaming to be correct as comments seem to be filtered out - // of JavaBlocks. - /* - * private boolean handleComment(Comment comment, SourceElement se) { - * return true; - * } - */ - - private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramElement jnte, - SourceElement se) { - if (se == jnte) { - return true; - } - if (se.getClass() != jnte.getClass()) { - return false; - } - final JavaNonTerminalProgramElement other = (JavaNonTerminalProgramElement) se; - return jnte.getChildCount() == other.getChildCount(); - } /* ------------------ End of helper methods for special cases ------------------ */ } From 26e174f79845188fee844cac256cac0525c96657 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 15 Apr 2024 22:33:46 +0200 Subject: [PATCH 32/73] change tests for equalsModRenaming on Comments --- .../key/logic/equality/TestEqualsModProperty.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 85debccb260..03fd1b2b4e2 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -6,6 +6,7 @@ import java.util.Arrays; import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.expression.literal.StringLiteral; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; @@ -21,6 +22,7 @@ import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; import static de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty.PROOF_IRRELEVANCY_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; import static de.uka.ilkd.key.logic.equality.TermLabelsProperty.TERM_LABELS_PROPERTY; import static org.junit.jupiter.api.Assertions.*; @@ -290,7 +292,7 @@ public void proofIrrelevancy() { @Test public void renamingSourceElements() { Term match1 = TacletForTests.parseTerm("\\<{ int i; int j; /*Test*/ }\\>true"); - Term match2 = TacletForTests.parseTerm("\\<{ int i; int k; }\\>true"); + Term match2 = TacletForTests.parseTerm("\\<{ int i; /*Another test*/ int k; }\\>true"); assertTrue( match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (0)."); @@ -298,9 +300,9 @@ public void renamingSourceElements() { Comment testComment = new Comment("test"); StringLiteral stringLiteral = new StringLiteral("testStringLiteral"); - // This seems very bad as equalsModRenaming is seemingly NOT symmetric!!! - // assertTrue(testComment.equalsModRenaming(stringLiteral, null)); - // assertFalse(stringLiteral.equalsModRenaming(testComment, null)); - // Currently, + assertFalse(testComment.equalsModProperty(stringLiteral, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable())); + assertFalse(stringLiteral.equalsModProperty(testComment, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable())); } } From d16f2f8309a7b204b55f812cbcd75c911edf2db8 Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 16 Apr 2024 13:25:46 +0200 Subject: [PATCH 33/73] minor changes to RenamingSourceElementProperty before PR --- .../RenamingSourceElementProperty.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index ba15ff20e18..138fab1a81e 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -38,19 +38,21 @@ private RenamingSourceElementProperty() {} * * @param se1 the first element of the equality check * @param se2 the second element of the equality check - * @param v the additional arguments needed for the equality check + * @param v the additional arguments needed for the equality check (a single + * {@link NameAbstractionTable} in this case) * @return {@code true} iff {@code se2} is a source element syntactically equal to {@code se1} * modulo renaming * @param the type of the additional parameters needed for the comparison + * ({@link NameAbstractionTable} in this case) */ @Override public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V... v) { // For this equality check, v must be a single NameAbstractionTable - if (v.length != 1 || !(v[0] instanceof NameAbstractionTable)) { + if (v.length != 1 || !(v[0] instanceof NameAbstractionTable nat)) { throw new IllegalArgumentException( "Expected a single NameAbstractionTable as argument."); } - NameAbstractionTable nat = (NameAbstractionTable) v[0]; + // NameAbstractionTable nat = (NameAbstractionTable) v[0]; JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); @@ -60,20 +62,20 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V while (next1 != null && next2 != null) { // Handle special cases of prior equalsModRenaming implementation - if (next1 instanceof LabeledStatement) { - if (!handleLabeledStatement((LabeledStatement) next1, next2, nat)) { + if (next1 instanceof LabeledStatement ls) { + if (!handleLabeledStatement(ls, next2, nat)) { return false; } - } else if (next1 instanceof VariableSpecification) { - if (!handleVariableSpecification((VariableSpecification) next1, next2, nat)) { + } else if (next1 instanceof VariableSpecification vs) { + if (!handleVariableSpecification(vs, next2, nat)) { return false; } } else if (next1 instanceof ProgramVariable || next1 instanceof ProgramElementName) { if (!handleProgramVariableOrElementName(next1, next2, nat)) { return false; } - } else if (next1 instanceof JavaNonTerminalProgramElement) { - if (!handleJavaNonTerminalProgramElements((JavaNonTerminalProgramElement) next1, + } else if (next1 instanceof JavaNonTerminalProgramElement jnte) { + if (!handleJavaNonTerminalProgramElements(jnte, next2)) { return false; } @@ -109,7 +111,7 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { private boolean handleStandard(SourceElement se1, SourceElement se2) { /* * As the prior implementations of equalsModRenaming for SourceElements were mostly the same - * as the normal equals method, we decided to move equalsModRenaming completely into the + * as their normal equals methods, we decided to move equalsModRenaming completely into the * equals method and handle the special cases separately while walking through the tree that * is a SourceElement. */ @@ -129,9 +131,9 @@ private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramEleme SourceElement se) { /* * A JavaNonTerminalProgramElement is a special case of a SourceElement, as we must not - * traverse the children recursively. This is the case as we might have to add some entries - * of children nodes to a NameAbstractionTable so that they can be compared later on by the - * TreeWalker. + * traverse the children recursively through the normal equals method. This is the case + * as we might have to add some entries of children nodes to a NameAbstractionTable so + * that they can be compared later on by the TreeWalker. */ if (se == jnte) { return true; @@ -230,6 +232,11 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem */ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElement se2, NameAbstractionTable nat) { + /* + * A ProgramVariable or a ProgramElementName is a special case of a SourceElement and one + * of the main reasons for equalsModRenaming. Equality here comes down to checking the + * abstract name of the elements in a NAT. + */ // TODO: Checking for exact class might be too strict as the original implementation was // only using instanceof or no check at all. if (se1.getClass() != se2.getClass()) { From a1bfab5076061fe252f1494efdc80069ca6ebb17 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sat, 20 Apr 2024 14:03:40 +0200 Subject: [PATCH 34/73] add more doc to EqualsModProperty and related interfaces/classes --- .../key/logic/equality/EqualsModProperty.java | 30 +++++++++++++++++-- .../IrrelevantTermLabelsProperty.java | 9 ++++-- .../equality/ProofIrrelevancyProperty.java | 9 ++++-- .../RenamingSourceElementProperty.java | 16 +++++----- .../logic/equality/RenamingTermProperty.java | 12 +++++--- .../logic/equality/TermLabelsProperty.java | 12 +++++--- 6 files changed, 64 insertions(+), 24 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java index d5a3b71f6c0..221985603ff 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/EqualsModProperty.java @@ -5,6 +5,24 @@ /** * Interface to check for equality ignoring given properties and to compute according hash codes. + *

+ * Overview of currently implemented properties that can be used with this interface: + * + *

  • For Terms:
  • + *
      + *
    1. {@link RenamingTermProperty}: Terms are checked for equality modulo renaming.
    2. + *
    3. {@link TermLabelsProperty}: Terms are checked for equality ignoring all term labels.
    4. + *
    5. {@link IrrelevantTermLabelsProperty}: Terms are checked for equality ignoring irrelevant term + * labels.
    6. + *
    7. {@link ProofIrrelevancyProperty}: Terms are checked for equality ignoring proof irrelevant + * attributes.
    8. + *
    + *
  • For SourceElements:
  • + *
      + *
    1. {@link RenamingSourceElementProperty}: Source elements are checked for equality modulo + * renaming.
    2. + *
    + * * * @param the type of the objects that are checked for equality or hashed * @@ -15,14 +33,20 @@ public interface EqualsModProperty { /** * Checks whether this object is equal to {@code o} modulo the property described by * {@code property}. + *

    + * Some properties call for additional arguments. For more information on that, + * see the documentation of {@code equalsModThisProperty} for the certain property. + *

    + * To get an overview of the currently implemented properties, see the documentation of + * {@link EqualsModProperty}. * * @param o the object that is checked for equality * @param property the property to be ignored in the equality check - * @param v the additional arguments needed for the equality check + * @param v the additional arguments needed by {@code property} for the equality check * @return whether this object is equal to o - * @param the type of the additional parameters needed for the comparison + * @param the type of the additional parameters needed by {@code property} for the + * comparison */ - boolean equalsModProperty(Object o, Property property, V... v); /** diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 759a53aa7cc..73ca237ffb5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -12,6 +12,11 @@ * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All irrelevant term labels are ignored in this equality check. + *

    + * The single instance of this property can be accessed through + * {@link IrrelevantTermLabelsProperty#IRRELEVANT_TERM_LABELS_PROPERTY}. + * + * @author Tobias Reinhold */ public class IrrelevantTermLabelsProperty implements Property { /** @@ -34,10 +39,10 @@ private IrrelevantTermLabelsProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} - * @param v the additional parameters needed for the comparison + * @param v should not be used for this equality check * @return {@code true} iff {@code term2} is a term syntactically equal to {@code term1}, except * for their irrelevant labels. - * @param the type of the additional parameters needed for the comparison + * @param is not needed for this equality check * @see TermLabel#isProofRelevant() isStrategyRelevant */ @Override diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index ea733323e26..c62ae31f956 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -17,6 +17,11 @@ * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All proof irrelevant attributes are ignored in this equality check. + *

    + * The single instance of this property can be accessed through + * {@link ProofIrrelevancyProperty#PROOF_IRRELEVANCY_PROPERTY}. + * + * @author Tobias Reinhold */ public class ProofIrrelevancyProperty implements Property { /** @@ -43,10 +48,10 @@ private ProofIrrelevancyProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} - * @param v the additional parameters needed for the comparison + * @param v should not be used for this equality check * @return true iff {@code term2} is a term syntactically equal to {@code term1}, except for * proof-irrelevant attributes. - * @param the type of the additional parameters needed for the comparison + * @param is not needed for this equality check */ @Override public boolean equalsModThisProperty(Term term1, Term term2, V... v) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 138fab1a81e..12877287fc2 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -16,6 +16,11 @@ * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for * {@link SourceElement}s. + *

    + * The single instance of this property can be accessed through + * {@link RenamingSourceElementProperty#RENAMING_SOURCE_ELEMENT_PROPERTY}. + * + * @author Tobias Reinhold */ public class RenamingSourceElementProperty implements Property { /** @@ -38,12 +43,10 @@ private RenamingSourceElementProperty() {} * * @param se1 the first element of the equality check * @param se2 the second element of the equality check - * @param v the additional arguments needed for the equality check (a single - * {@link NameAbstractionTable} in this case) + * @param v should be a single {@link NameAbstractionTable} for this equality check * @return {@code true} iff {@code se2} is a source element syntactically equal to {@code se1} * modulo renaming - * @param the type of the additional parameters needed for the comparison - * ({@link NameAbstractionTable} in this case) + * @param is supposed to be {@link NameAbstractionTable} for this equality check */ @Override public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V... v) { @@ -52,7 +55,6 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V throw new IllegalArgumentException( "Expected a single NameAbstractionTable as argument."); } - // NameAbstractionTable nat = (NameAbstractionTable) v[0]; JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); @@ -194,8 +196,6 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem if (se == vs) { return true; } - // TODO: Checking for exact class might be too strict as the original implementation was - // only using instanceof if (se.getClass() != vs.getClass()) { return false; } @@ -237,8 +237,6 @@ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElem * of the main reasons for equalsModRenaming. Equality here comes down to checking the * abstract name of the elements in a NAT. */ - // TODO: Checking for exact class might be too strict as the original implementation was - // only using instanceof or no check at all. if (se1.getClass() != se2.getClass()) { return false; } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index 736aa85857b..2a7fc825544 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -18,6 +18,11 @@ * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * Renaming of variables is ignored in this equality check. + *

    + * The single instance of this property can be accessed through + * {@link RenamingTermProperty#RENAMING_TERM_PROPERTY}. + * + * @author Tobias Reinhold */ public class RenamingTermProperty implements Property { /** @@ -37,11 +42,10 @@ private RenamingTermProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} - * @param v the additional parameters needed for the comparison + * @param v should not be used for this equality check * @return {@code true} iff {@code term2} has the same values in operator, sort, arity, - * varsBoundHere - * and javaBlock as {@code term1} modulo bound renaming - * @param the type of the additional parameters needed for the comparison + * varsBoundHere and javaBlock as {@code term1} modulo bound renaming + * @param is not needed for this equality check */ @Override public boolean equalsModThisProperty(Term term1, Term term2, V... v) { diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 757c5b79045..e1460782eee 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -11,6 +11,11 @@ * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. * All term labels are ignored in this equality check. + *

    + * The single instance of this property can be accessed through + * {@link TermLabelsProperty#TERM_LABELS_PROPERTY}. + * + * @author Tobias Reinhold */ public class TermLabelsProperty implements Property { /** @@ -31,11 +36,10 @@ private TermLabelsProperty() {} * * @param term1 a term * @param term2 the term compared to {@code term1} - * @param v the additional parameters needed for the comparison + * @param v should not be used for this equality check * @return {@code true} iff {@code term2} is a term syntactically equal to {@code term1} - * ignoring all - * term labels - * @param the type of the additional parameters needed for the comparison + * ignoring all term labels + * @param is not needed for this equality check */ @Override public boolean equalsModThisProperty(Term term1, Term term2, V... v) { From daa4dcbca85675fa0c6fe1d30cff8e0ed8a73e62 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 21 Apr 2024 17:16:06 +0200 Subject: [PATCH 35/73] change names of methods of TreeWalker --- .../ilkd/key/java/visitor/JavaASTTreeWalker.java | 15 +++------------ .../de/uka/ilkd/key/java/visitor/TreeWalker.java | 4 ++-- .../equality/RenamingSourceElementProperty.java | 4 ++-- 3 files changed, 7 insertions(+), 16 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java index af78adda6c3..87bc7a8bcd3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java @@ -42,12 +42,12 @@ public JavaASTTreeWalker(SourceElement root) { } @Override - public SourceElement getRoot() { + public SourceElement root() { return root; } @Override - public SourceElement getCurrentNode() { + public SourceElement currentNode() { return currentNode; } @@ -187,8 +187,7 @@ private static class NonTerminalProgramElementChildIndexPair { final NonTerminalProgramElement nonTerminalProgramElement; /** - * The index of the next child of {@code nonTerminalProgramElement} that should to be - * visited. + * The index of the next child of {@code nonTerminalProgramElement} that should be visited. */ int nextChildToVisitIndex; @@ -312,14 +311,6 @@ boolean empty() { return count == 0; } - /** - * Empties the stack. - */ - void clear() { - count = 0; - stack = new NonTerminalProgramElementChildIndexPair[stack.length]; - } - /** * Increases the capacity of the stack. *

    diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java index 84735ea3faa..154ad7eda08 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java @@ -18,14 +18,14 @@ public interface TreeWalker { * * @return the root of the tree that is being walked */ - SourceElement getRoot(); + SourceElement root(); /** * Returns the node of the tree the walker is currently at. * * @return the node of the tree the walker is currently at */ - SourceElement getCurrentNode(); + SourceElement currentNode(); /** * Walks to the first child of the current node, or stays in place if the current node has no diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 12877287fc2..82279627ec6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -59,8 +59,8 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); - SourceElement next1 = tw1.getCurrentNode(); - SourceElement next2 = tw2.getCurrentNode(); + SourceElement next1 = tw1.currentNode(); + SourceElement next2 = tw2.currentNode(); while (next1 != null && next2 != null) { // Handle special cases of prior equalsModRenaming implementation From 43130c10bb79b10e6e75c3cf4c0f2e35efd63029 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 21 Apr 2024 17:16:31 +0200 Subject: [PATCH 36/73] add test for JavaASTTreeWalker --- .../java/visitor/TestJavaASTTreeWalker.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java diff --git a/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java b/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java new file mode 100644 index 00000000000..3817af80b68 --- /dev/null +++ b/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java @@ -0,0 +1,99 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.java.visitor; + +import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.java.StatementBlock; +import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; +import de.uka.ilkd.key.java.expression.literal.IntLiteral; +import de.uka.ilkd.key.rule.TacletForTests; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * Tests for {@link JavaASTTreeWalker}. + * + * @author Tobias Reinhold + */ +public class TestJavaASTTreeWalker { + @Test + public void walker() { + final SourceElement se = TacletForTests + .parsePrg("{int i; int j = 1; i = j; if (i == j) { i = 2; } else { j = 2; } }"); + JavaASTTreeWalker walker = new JavaASTTreeWalker(se); + + // The root node should be a StatementBlock + assertEquals(StatementBlock.class, walker.root().getClass()); + StatementBlock root = (StatementBlock) walker.root(); + SourceElement currentNode = walker.currentNode(); + assertEquals(currentNode, root, + "In the beginning, the current node should be the root node."); + + // For the following assertions, I drew the AST of the source element on paper and used that + // to verify the correctness of the walker. + + // First child of the root is a LocalVariableDeclaration; should be the next visited + SourceElement firstChild = walker.firstChild(); + assertEquals(LocalVariableDeclaration.class, firstChild.getClass(), + "The first child of the root should be a LocalVariableDeclaration."); + assertEquals(root.getChildAt(0), firstChild, + "walker.firstChild() should return the first child of the current node."); + + // The parent of the first child should be the root + currentNode = walker.parentNode(); + assertEquals(root, currentNode, "The parent of the first child should be the root."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (0)"); + + // The next node should be the first child again + currentNode = walker.nextNode(); + assertEquals(firstChild, currentNode, "The next node should be the first child."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (1)"); + + // Going back, we should be at the root again + currentNode = walker.previousNode(); + assertEquals(root, currentNode, "The previous node should be the root again."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (2)"); + + // The last child (the fourth) of the root should be an If + currentNode = walker.lastChild(); + assertEquals(root.getChildAt(3), currentNode, + "walker.lastChild() should here return the last (fourth) child of the root."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (3)"); + + // Interesting step: moving to the previous sibling should yield the CopyAssignment 'i = j;' + currentNode = walker.previousSibling(); + assertEquals(root.getChildAt(2), currentNode, + "walker.previousSibling() should here return the second to last (third) child of the root."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (4)"); + + // Even more interesting: the previous node should now be deeper in the tree, namely a + // descendant of the second LocalVariableDeclaration 'int j = 1:' + // To be exact, it should be the IntLiteral '1' + currentNode = walker.previousNode(); + assertEquals(IntLiteral.class, currentNode.getClass(), + "The previous node should be an IntLiteral."); + assertEquals(1, ((IntLiteral) currentNode).getValue(), + "The previous node should be the IntLiteral '1'."); + assertEquals(currentNode, walker.currentNode(), + "The worker should not just return the new node but also visit it. (5)"); + + // The next sibling should then be null, as the currentNode is the last node in the subtree + // of 'int j = 1;' + assertNull(walker.nextSibling(), + "walker.nextSibling() should return null as there is no next sibling."); + + // Also interesting: the walker did not move, the next node should then again be the + // CopyAssignment (third child) of the root + currentNode = walker.nextNode(); + assertEquals(root.getChildAt(2), currentNode, + "The next node should again be the third child of the root."); + } +} From a499abd6d831f21aca128ddd6504488faac80240 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 25 Apr 2024 18:17:15 +0200 Subject: [PATCH 37/73] fix errors introduced through merge --- .../equality/ProofIrrelevancyProperty.java | 4 +- .../ilkd/key/logic/util/EqualityUtils.java | 16 ++-- .../key/logic/util/LinkedHashMapWrapper.java | 75 ++++++++++--------- 3 files changed, 52 insertions(+), 43 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java index 9e48a23bb98..1172bfd5d87 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/ProofIrrelevancyProperty.java @@ -14,6 +14,7 @@ import org.key_project.util.EqualsModProofIrrelevancyUtil; import org.key_project.util.collection.ImmutableArray; + /** * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for terms. @@ -105,7 +106,8 @@ public boolean equalsModThisProperty(Term term1, Term term2, V... v) { */ @Override public int hashCodeModThisProperty(Term term) { - int hashcode = Objects.hash(term.op(), hashCodeIterable(term.subs()), + int hashcode = Objects.hash(term.op(), + EqualityUtils.hashCodeModPropertyOfIterable(PROOF_IRRELEVANCY_PROPERTY, term.subs()), EqualsModProofIrrelevancyUtil.hashCodeIterable(term.boundVars()), term.javaBlock()); // part from LabeledTermImpl diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java index e149df04ef4..a737a9d73f9 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/EqualityUtils.java @@ -3,21 +3,21 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic.util; -import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; -import de.uka.ilkd.key.logic.equality.TermProperty; +import de.uka.ilkd.key.logic.equality.EqualsModProperty; +import de.uka.ilkd.key.logic.equality.Property; public class EqualityUtils { /** - * Computes the hashcode of an iterable of terms modulo a given property using the elements' - * {@link TermEqualsModProperty} implementation. + * Computes the hashcode modulo a given property of an iterable of elements that implement + * {@link EqualsModProperty}. * * @param iter iterable of terms * @return combined hashcode */ - public static int hashCodeModPropertyOfIterable(TermProperty property, - Iterable iter) { + public static > int hashCodeModPropertyOfIterable( + Property property, + Iterable iter) { // adapted from Arrays.hashCode if (iter == null) { return 0; @@ -25,7 +25,7 @@ public static int hashCodeModPropertyOfIterable(TermProperty property, int result = 1; - for (Term element : iter) { + for (T element : iter) { result = 31 * result + (element == null ? 0 : element.hashCodeModProperty(property)); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java index 060b6bb4b45..98e94a8f9b8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java @@ -6,15 +6,14 @@ import java.util.Iterator; import de.uka.ilkd.key.logic.Term; -import de.uka.ilkd.key.logic.equality.TermEqualsModProperty; -import de.uka.ilkd.key.logic.equality.TermProperty; +import de.uka.ilkd.key.logic.equality.EqualsModProperty; +import de.uka.ilkd.key.logic.equality.Property; import de.uka.ilkd.key.util.LinkedHashMap; -import de.uka.ilkd.key.util.Pair; /** * This class is a wrapper for {@link LinkedHashMap} where the keys are {@link Term}s. *

    - * Internally, the {@link Term}s are wrapped so that {@link TermEqualsModProperty} can be used for + * Internally, the {@link Term}s are wrapped so that {@link EqualsModProperty} can be used for * equality checks and * hash codes instead of the usual {@code equals} and {@code hashCode} methods of {@link Term}. * @@ -27,17 +26,18 @@ public class LinkedHashMapWrapper { private final LinkedHashMap map; /** - * The {@link TermProperty} that is used for equality checks and hash codes. + * The {@link Property} that is used for equality checks and hash codes. */ - private final TermProperty property; + private final Property property; /** * Constructs a new empty {@link LinkedHashMapWrapper}. * - * @param property the {@link TermProperty} that is used internally for equality checks and hash + * @param property the {@link Property} that is used internally for equality checks and + * hash * codes */ - public LinkedHashMapWrapper(TermProperty property) { + public LinkedHashMapWrapper(Property property) { this.property = property; map = new LinkedHashMap<>(); } @@ -47,10 +47,11 @@ public LinkedHashMapWrapper(TermProperty property) { * * @param key the key to be inserted * @param value the value corresponding to {@code key} - * @param property the {@link TermProperty} that is used internally for equality checks and hash + * @param property the {@link Property} that is used internally for equality checks and + * hash * codes */ - public LinkedHashMapWrapper(Term key, V value, TermProperty property) { + public LinkedHashMapWrapper(Term key, V value, Property property) { this(property); put(key, value); } @@ -64,10 +65,11 @@ public LinkedHashMapWrapper(Term key, V value, TermProperty property) { * * @param keys the array of keys to be inserted * @param values the array of values corresponding to the keys - * @param property the {@link TermProperty} that is used internally for equality checks and hash + * @param property the {@link Property} that is used internally for equality checks and + * hash * codes */ - public LinkedHashMapWrapper(Term[] keys, V[] values, TermProperty property) { + public LinkedHashMapWrapper(Term[] keys, V[] values, Property property) { this(property); putAll(keys, values); } @@ -81,10 +83,11 @@ public LinkedHashMapWrapper(Term[] keys, V[] values, TermProperty property) { * * @param keys the iterable of keys to be inserted * @param values the iterable of values corresponding to the keys - * @param property the {@link TermProperty} that is used internally for equality checks and hash + * @param property the {@link Property} that is used internally for equality checks and + * hash * codes */ - public LinkedHashMapWrapper(Iterable keys, Iterable values, TermProperty property) { + public LinkedHashMapWrapper(Iterable keys, Iterable values, Property property) { this(property); putAll(keys, values); } @@ -213,15 +216,15 @@ public boolean containsValue(V value) { * * @return an iterator over the key-value pairs in this map */ - public Iterator> iterator() { + public Iterator> iterator() { return new PairIterator<>(map); } /** - * This helper method wraps a term in a {@link TermWrapper} with the {@link TermProperty} of + * This helper method wraps a term in a {@link TermWrapper} with the {@link Property} of * this map. *

    - * This is done so that {@link TermEqualsModProperty} can be used for equality checks and hash + * This is done so that {@link EqualsModProperty} can be used for equality checks and hash * codes instead of the * usual {@code equals} and {@code hashCode} methods of {@link Term} in the internal * {@link LinkedHashMap}. @@ -239,27 +242,31 @@ private TermWrapper wrapTerm(Term term) { * This class is used to wrap a term and override the {@code equals} and {@code hashCode} methods for use in a * {@link LinkedHashMap}. *

    - * The wrapped term is equipped with a {@link TermProperty} that is used for - * {@link TermEqualsModProperty#equalsModProperty(Object, TermProperty)} and - * {@link TermEqualsModProperty#hashCodeModProperty(TermProperty)}. + * The wrapped term is equipped with a {@link Property} that is used for + * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} and + * {@link EqualsModProperty#hashCodeModProperty(Property)} )}. * * @param term The term to be wrapped - * @param property The {@link TermProperty} that is used in the {@code equals} and {@code hashCode} methods + * @param property The {@link Property} that is used in the {@code equals} and {@code hashCode} methods */ - private record TermWrapper(Term term, TermProperty property) { - @Override - public boolean equals(Object obj) { - return term.equalsModProperty(obj, property); - } + private record TermWrapper(Term term, Property property) { - @Override - public int hashCode() { - return term.hashCodeModProperty(property); - } + @Override + public boolean equals(Object obj) { + return term.equalsModProperty(obj, property); } - // ------------- class to iterate over internal map and unwrap terms + @Override + public int hashCode() { + return term.hashCodeModProperty(property); + }} + + // ------------- record for term-value mapping + public record TermPair(Term term, V value) + { + } + // ------------- class to iterate over internal map and unwrap terms /** * This class is used to iterate over the key-value pairs in the {@link LinkedHashMapWrapper}. *

    @@ -267,7 +274,7 @@ public int hashCode() { * * @param the type of the values in the {@link LinkedHashMapWrapper} */ - private static class PairIterator implements Iterator> { + private static class PairIterator implements Iterator> { /** * The iterator over the keys of the internal map. */ @@ -299,9 +306,9 @@ public boolean hasNext() { } @Override - public Pair next() { + public TermPair next() { last = keyIt.next(); - return new Pair<>(last.term(), map.get(last)); + return new TermPair<>(last.term(), map.get(last)); } @Override From b14e38f405081163578bc54ef035c14a62dea954 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 30 Apr 2024 20:19:07 +0200 Subject: [PATCH 38/73] change LinkedHashMapWrapper to be more general --- .../key/logic/util/LinkedHashMapWrapper.java | 157 ++++++++++-------- 1 file changed, 88 insertions(+), 69 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java index 98e94a8f9b8..77825d3aef3 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java @@ -10,34 +10,38 @@ import de.uka.ilkd.key.logic.equality.Property; import de.uka.ilkd.key.util.LinkedHashMap; +import org.key_project.util.collection.Pair; + /** - * This class is a wrapper for {@link LinkedHashMap} where the keys are {@link Term}s. - *

    - * Internally, the {@link Term}s are wrapped so that {@link EqualsModProperty} can be used for - * equality checks and - * hash codes instead of the usual {@code equals} and {@code hashCode} methods of {@link Term}. + * This class is a wrapper for {@link LinkedHashMap} where the keys are elements that implement + * {@link EqualsModProperty}. * + * @param the type of the keys in the wrapped LinkedHashMap * @param the type of the values in the wrapped LinkedHashMap */ -public class LinkedHashMapWrapper { +public class LinkedHashMapWrapper, V> { + /* + * Internally, the elements are wrapped so that EqualsModProperty can be used for equality + * checks and hash codes instead of the usual equals and hashCode methods. + */ + /** * The wrapped {@link LinkedHashMap}. */ - private final LinkedHashMap map; + private final LinkedHashMap, V> map; /** - * The {@link Property} that is used for equality checks and hash codes. + * The {@link Property} that is used for equality checks and hash codes. */ - private final Property property; + private final Property property; /** * Constructs a new empty {@link LinkedHashMapWrapper}. * * @param property the {@link Property} that is used internally for equality checks and - * hash - * codes + * hash codes */ - public LinkedHashMapWrapper(Property property) { + public LinkedHashMapWrapper(Property property) { this.property = property; map = new LinkedHashMap<>(); } @@ -48,10 +52,9 @@ public LinkedHashMapWrapper(Property property) { * @param key the key to be inserted * @param value the value corresponding to {@code key} * @param property the {@link Property} that is used internally for equality checks and - * hash - * codes + * hash codes */ - public LinkedHashMapWrapper(Term key, V value, Property property) { + public LinkedHashMapWrapper(K key, V value, Property property) { this(property); put(key, value); } @@ -66,10 +69,9 @@ public LinkedHashMapWrapper(Term key, V value, Property property) { * @param keys the array of keys to be inserted * @param values the array of values corresponding to the keys * @param property the {@link Property} that is used internally for equality checks and - * hash - * codes + * hash codes */ - public LinkedHashMapWrapper(Term[] keys, V[] values, Property property) { + public LinkedHashMapWrapper(K[] keys, V[] values, Property property) { this(property); putAll(keys, values); } @@ -84,10 +86,9 @@ public LinkedHashMapWrapper(Term[] keys, V[] values, Property property) { * @param keys the iterable of keys to be inserted * @param values the iterable of values corresponding to the keys * @param property the {@link Property} that is used internally for equality checks and - * hash - * codes + * hash codes */ - public LinkedHashMapWrapper(Iterable keys, Iterable values, Property property) { + public LinkedHashMapWrapper(Iterable keys, Iterable values, Property property) { this(property); putAll(keys, values); } @@ -116,8 +117,8 @@ public boolean isEmpty() { * @param key the key whose presence in this map is to be tested * @return true if this map contains a mapping for the specified key */ - public boolean containsKey(Term key) { - return map.containsKey(wrapTerm(key)); + public boolean containsKey(K key) { + return map.containsKey(wrapKey(key)); } /** @@ -127,8 +128,8 @@ public boolean containsKey(Term key) { * @param key the key whose associated value is to be returned * @return the value to which the specified key is mapped */ - public V get(Term key) { - return map.get(wrapTerm(key)); + public V get(K key) { + return map.get(wrapKey(key)); } /** @@ -142,8 +143,8 @@ public V get(Term key) { * @return the previous value associated with {@code key}, or {@code null} if there was no * mapping for {@code key} */ - public V put(Term key, V value) { - return map.put(wrapTerm(key), value); + public V put(K key, V value) { + return map.put(wrapKey(key), value); } /** @@ -156,7 +157,7 @@ public V put(Term key, V value) { * @param keys the array of keys to be inserted * @param vals the array of values corresponding to the keys */ - public void putAll(Term[] keys, V[] vals) { + public void putAll(K[] keys, V[] vals) { for (int i = 0; i < keys.length; i++) { if (i < vals.length) { put(keys[i], vals[i]); @@ -176,9 +177,9 @@ public void putAll(Term[] keys, V[] vals) { * @param keys the iterable of keys to be inserted * @param vals the iterable of values corresponding to the keys */ - public void putAll(Iterable keys, Iterable vals) { + public void putAll(Iterable keys, Iterable vals) { Iterator itVals = vals.iterator(); - for (Term key : keys) { + for (K key : keys) { if (itVals.hasNext()) { put(key, itVals.next()); } else { @@ -195,8 +196,8 @@ public void putAll(Iterable keys, Iterable vals) { * @return the previous value associated with {@code key}, or {@code null} if there was no * mapping for {@code key} */ - public V remove(Term key) { - return map.remove(wrapTerm(key)); + public V remove(K key) { + return map.remove(wrapKey(key)); } /** @@ -216,86 +217,104 @@ public boolean containsValue(V value) { * * @return an iterator over the key-value pairs in this map */ - public Iterator> iterator() { + public Iterator> iterator() { return new PairIterator<>(map); } /** - * This helper method wraps a term in a {@link TermWrapper} with the {@link Property} of - * this map. + * This helper method wraps an element in an {@link ElementWrapper} with the {@link Property} + * of this map. *

    - * This is done so that {@link EqualsModProperty} can be used for equality checks and hash - * codes instead of the - * usual {@code equals} and {@code hashCode} methods of {@link Term} in the internal + * This is done so that {@link EqualsModProperty} can be used for equality checks and hash codes + * instead of the usual {@code equals} and {@code hashCode} methods in the internal * {@link LinkedHashMap}. * - * @param term the term to be wrapped - * @return the wrapped term + * @param key the key to be wrapped + * @return the wrapped key */ - private TermWrapper wrapTerm(Term term) { - return new TermWrapper(term, property); + private ElementWrapper wrapKey(K key) { + return new ElementWrapper(key, property); } - // ------------- wrapper class for terms + // ------------- wrapper class for keys in the internal map /** - * This class is used to wrap a term and override the {@code equals} and {@code hashCode} methods for use in a - * {@link LinkedHashMap}. + * This class is used to wrap an element and override the {@code equals} and {@code hashCode} + * methods for use in a map. *

    - * The wrapped term is equipped with a {@link Property} that is used for + * The wrapped element is equipped with a {@link Property} that is used for * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} and - * {@link EqualsModProperty#hashCodeModProperty(Property)} )}. + * {@link EqualsModProperty#hashCodeModProperty(Property)} instead of the normal + * {@code equals} implementation. * - * @param term The term to be wrapped - * @param property The {@link Property} that is used in the {@code equals} and {@code hashCode} methods + * @param the type of the wrapped element */ - private record TermWrapper(Term term, Property property) { + private static class ElementWrapper> { + /** + * The wrapped element. + */ + K key; - @Override - public boolean equals(Object obj) { - return term.equalsModProperty(obj, property); - } + /** + * The {@link Property} that is used for equality checks and hash codes. + */ + Property property; - @Override - public int hashCode() { - return term.hashCodeModProperty(property); - }} + /** + * Creates a new wrapper for the given element. + * + * @param key the element to be wrapped + * @param property the {@link Property} that is used for equality checks and hash codes + */ + public ElementWrapper(K key, Property property) { + this.key = key; + this.property = property; + } - // ------------- record for term-value mapping - public record TermPair(Term term, V value) - { + @Override + public boolean equals(Object obj) { + return key.equalsModProperty(obj, property); + } + + @Override + public int hashCode() { + return key.hashCodeModProperty(property); + } } + // ------------- class to iterate over internal map and unwrap terms /** * This class is used to iterate over the key-value pairs in the {@link LinkedHashMapWrapper}. *

    - * The terms in the pairs are unwrapped before returning them. + * The keys in the pairs are unwrapped before returning them. * + * @param the type of the keys in the {@link LinkedHashMapWrapper} * @param the type of the values in the {@link LinkedHashMapWrapper} */ - private static class PairIterator implements Iterator> { + private static class PairIterator, V> + implements Iterator> { /** * The iterator over the keys of the internal map. */ - private final Iterator keyIt; + private final Iterator> keyIt; /** * The internal map. */ - private final LinkedHashMap map; + private final LinkedHashMap, V> map; /** * The last key-value pair that was returned by {@link #next()}. */ - private TermWrapper last = null; + private ElementWrapper last = null; /** * Creates a new iterator over the key-value pairs in the {@link LinkedHashMapWrapper}. * * @param map the internal map of the {@link LinkedHashMapWrapper} to iterate over */ - public PairIterator(final LinkedHashMap map) { + public PairIterator(final LinkedHashMap, V> map) { this.map = map; keyIt = map.keySet().iterator(); } @@ -306,9 +325,9 @@ public boolean hasNext() { } @Override - public TermPair next() { + public Pair next() { last = keyIt.next(); - return new TermPair<>(last.term(), map.get(last)); + return new Pair<>(last.key, map.get(last)); } @Override From 5c47fc108dca6972ebcfc398340d407bee02b866 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 5 May 2024 14:03:23 +0200 Subject: [PATCH 39/73] add tests for hashCodeModProperty at various spots where equalsModProperty was asserted to be true --- .../java/de/uka/ilkd/key/logic/TestTerm.java | 18 +++++++ .../logic/equality/TestEqualsModProperty.java | 48 +++++++++++++++++-- .../uka/ilkd/key/parser/TestTermParser.java | 3 ++ .../de/uka/ilkd/key/rule/TestApplyTaclet.java | 9 ++++ .../TestApplyUpdateOnRigidCondition.java | 21 ++++++++ .../key/speclang/jml/TestJMLTranslator.java | 18 +++++++ 6 files changed, 113 insertions(+), 4 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java index 6a8e3319620..a4bb8639218 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/TestTerm.java @@ -116,10 +116,16 @@ public void testProgramElementEqualsModRenaming() { assertTrue( match1.sub(0).equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (0)."); + assertEquals(match1.sub(0).hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + match2.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal. (0)"); assertTrue( match1.sub(0).equalsModProperty(match1.sub(1), RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming (1)."); + assertEquals(match1.sub(0).hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + match1.sub(1).hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal. (1)"); Term match3 = TacletForTests.parseTerm("\\<{ int j = 0; }\\>true "); assertNotEquals(match1, match3, "Terms should not be equal."); @@ -131,14 +137,23 @@ public void testEqualsModRenamingWithLabels() { Term match2 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ } } }\\>true"); assertTrue(match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); + assertEquals(match1.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + match2.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming. (0)"); Term match3 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); Term match4 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int j = 0; } } }\\>true"); assertTrue(match3.equalsModProperty(match4, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); + assertEquals(match3.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + match4.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming. (1)"); Term match5 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); Term match6 = TacletForTests.parseTerm("\\<{ label0:{ label1:{ int i = 0; } } }\\>true"); assertTrue(match5.equalsModProperty(match6, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming."); + assertEquals(match5.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + match6.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming. (2)"); } @Test @@ -152,6 +167,9 @@ public void testEqualsModRenaming() { assertTrue(quant1.equalsModProperty(quant2, RenamingTermProperty.RENAMING_TERM_PROPERTY), "Terms " + quant1 + " and " + quant2 + " should be equal mod renaming"); + assertEquals(quant1.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + quant2.hashCodeModProperty(RenamingTermProperty.RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java index 03fd1b2b4e2..ef17a3062c9 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java +++ b/key.core/src/test/java/de/uka/ilkd/key/logic/equality/TestEqualsModProperty.java @@ -7,6 +7,7 @@ import de.uka.ilkd.key.java.Comment; import de.uka.ilkd.key.java.NameAbstractionTable; +import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.java.expression.literal.StringLiteral; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; @@ -88,6 +89,10 @@ public void renaming() { "Should be true as labels do not matter"); assertTrue(term2.equalsModProperty(term1, RENAMING_TERM_PROPERTY), "Should be true as labels do not matter"); + assertEquals(term1.hashCodeModProperty(RENAMING_TERM_PROPERTY), + term2.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal as labels do not matter (0)"); + labels1 = new ImmutableArray<>(relevantLabel1); term1 = tb.label(term1, labels1); @@ -95,6 +100,9 @@ public void renaming() { "Should be true as labels do not matter"); assertTrue(term2.equalsModProperty(term1, RENAMING_TERM_PROPERTY), "Should be true as labels do not matter"); + assertEquals(term1.hashCodeModProperty(RENAMING_TERM_PROPERTY), + term2.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal as labels do not matter (1)"); ImmutableArray labels2 = new ImmutableArray<>(relevantLabel2); term2 = tb.label(term2, labels2); @@ -102,6 +110,9 @@ public void renaming() { "Should be true as labels do not matter"); assertTrue(term2.equalsModProperty(term1, RENAMING_TERM_PROPERTY), "Should be true as labels do not matter"); + assertEquals(term1.hashCodeModProperty(RENAMING_TERM_PROPERTY), + term2.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal as labels do not matter (2)"); } // equalsModProperty(...) with IRRELEVANT_TERM_LABELS_PROPERTY @@ -142,6 +153,9 @@ public void irrelevantTermLabels() { "Should be true as term1 has no relevant term labels and term2 does not have any labels"); assertTrue(term2.equalsModProperty(term1, IRRELEVANT_TERM_LABELS_PROPERTY), "Should be true as term1 has no relevant term labels and term2 does not have any labels"); + assertEquals(term1.hashCodeModProperty(IRRELEVANT_TERM_LABELS_PROPERTY), + term2.hashCodeModProperty(IRRELEVANT_TERM_LABELS_PROPERTY), + "Hash codes should be equal as term1 has no relevant term labels and term2 does not have any labels (0)"); // ------------ same relevant labels labels1 = new ImmutableArray<>(relevantLabel1, relevantLabel2); @@ -153,6 +167,9 @@ public void irrelevantTermLabels() { "Should be true as both terms have the same relevant term labels"); assertTrue(term2.equalsModProperty(term1, IRRELEVANT_TERM_LABELS_PROPERTY), "Should be true as both terms have the same relevant term labels"); + assertEquals(term1.hashCodeModProperty(IRRELEVANT_TERM_LABELS_PROPERTY), + term2.hashCodeModProperty(IRRELEVANT_TERM_LABELS_PROPERTY), + "Hash codes should be equal as both terms have the same relevant term labels (1)"); // ------------ not the same relevant labels labels1 = new ImmutableArray<>(relevantLabel1, irrelevantLabel); @@ -196,6 +213,9 @@ public void allTermLabels() { "Should be true as underlying terms are equal"); assertTrue(term2.equalsModProperty(term1, TERM_LABELS_PROPERTY), "Should be true as underlying terms are equal"); + assertEquals(term1.hashCodeModProperty(TERM_LABELS_PROPERTY), + term2.hashCodeModProperty(TERM_LABELS_PROPERTY), + "Hash codes should be equal as all term labels are ignored (0)"); // ------------ same relevant labels labels1 = new ImmutableArray<>(relevantLabel1, relevantLabel2); @@ -207,6 +227,9 @@ public void allTermLabels() { "Should be true as underlying terms are equal"); assertTrue(term2.equalsModProperty(term1, TERM_LABELS_PROPERTY), "Should be true as underlying terms are equal"); + assertEquals(term1.hashCodeModProperty(TERM_LABELS_PROPERTY), + term2.hashCodeModProperty(TERM_LABELS_PROPERTY), + "Hash codes should be equal as all term labels are ignored (1)"); // ------------ not the same relevant labels labels1 = new ImmutableArray<>(relevantLabel1, irrelevantLabel); @@ -217,6 +240,9 @@ public void allTermLabels() { "Should be true as underlying terms are equal"); assertTrue(term2.equalsModProperty(term1, TERM_LABELS_PROPERTY), "Should be true as underlying terms are equal"); + assertEquals(term1.hashCodeModProperty(TERM_LABELS_PROPERTY), + term2.hashCodeModProperty(TERM_LABELS_PROPERTY), + "Hash codes should be equal as all term labels are ignored (2)"); } // equalsModProperty(...) with PROOF_IRRELEVANCY_PROPERTY @@ -257,6 +283,9 @@ public void proofIrrelevancy() { "Should be true as term1 has no relevant term labels and term2 does not have any labels"); assertTrue(term2.equalsModProperty(term1, PROOF_IRRELEVANCY_PROPERTY), "Should be true as term1 has no relevant term labels and term2 does not have any labels"); + assertEquals(term1.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + term2.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + "Hash codes should be equal as proof irrelevant properties are ignored (0)"); // ------------ same relevant labels labels1 = new ImmutableArray<>(relevantLabel1, relevantLabel2, irrelevantLabel); @@ -268,6 +297,9 @@ public void proofIrrelevancy() { "Should be true as both terms have the same relevant term labels"); assertTrue(term2.equalsModProperty(term1, PROOF_IRRELEVANCY_PROPERTY), "Should be true as both terms have the same relevant term labels"); + assertEquals(term1.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + term2.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + "Hash codes should be equal as proof irrelevant properties are ignored (1)"); labels1 = new ImmutableArray<>(relevantLabel1, relevantLabel2, irrelevantLabel); labels2 = new ImmutableArray<>(relevantLabel1, relevantLabel2); @@ -277,6 +309,9 @@ public void proofIrrelevancy() { "Should be true as both terms have the same relevant term labels and irrelevant labels do not matter"); assertTrue(term2.equalsModProperty(term1, PROOF_IRRELEVANCY_PROPERTY), "Should be true as both terms have the same relevant term labels and irrelevant labels do not matter"); + assertEquals(term1.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + term2.hashCodeModProperty(PROOF_IRRELEVANCY_PROPERTY), + "Hash codes should be equal as proof irrelevant properties are ignored (2)"); // ------------ not the same relevant labels labels1 = new ImmutableArray<>(relevantLabel1); @@ -291,11 +326,16 @@ public void proofIrrelevancy() { @Test public void renamingSourceElements() { - Term match1 = TacletForTests.parseTerm("\\<{ int i; int j; /*Test*/ }\\>true"); - Term match2 = TacletForTests.parseTerm("\\<{ int i; /*Another test*/ int k; }\\>true"); + ProgramElement match1 = TacletForTests.parsePrg("{ int i; int j; /*Test*/ }"); + ProgramElement match2 = TacletForTests.parsePrg("{ int i; /*Another test*/ int k; }"); assertTrue( - match1.equalsModProperty(match2, RenamingTermProperty.RENAMING_TERM_PROPERTY), - "Terms should be equalModRenaming (0)."); + match1.equalsModProperty(match2, RENAMING_SOURCE_ELEMENT_PROPERTY, + new NameAbstractionTable()), + "ProgramElements should be equal modulo renaming (0)."); + assertEquals(match1.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + match2.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + "Hash codes should be equal as ProgramElements are equal modulo renaming (0)."); + Comment testComment = new Comment("test"); StringLiteral stringLiteral = new StringLiteral("testStringLiteral"); diff --git a/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java b/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java index 8337dd79455..609497cdcc9 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java +++ b/key.core/src/test/java/de/uka/ilkd/key/parser/TestTermParser.java @@ -260,6 +260,9 @@ public void test13() throws Exception { + "\\<{ int p_y = 1;boolean p_x = 2<1;" + "while(p_x){ int s=3 ;} }\\>" + " true)"); assertTrue(t3.equalsModProperty(t4, RENAMING_TERM_PROPERTY), "Terms should be equalModRenaming"); + assertEquals(t3.hashCodeModProperty(RENAMING_TERM_PROPERTY), + t4.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equalModRenaming"); } @Test diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java index a1df0325dca..55abf044cb7 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/TestApplyTaclet.java @@ -745,6 +745,9 @@ private void doTestCatchList(int p_proof) { "Wrong result. Expected:" + ProofSaver.printAnything(correctFormula, TacletForTests.services()) + " But was:" + ProofSaver.printAnything(resultFormula, TacletForTests.services())); + assertEquals(resultFormula.hashCodeModProperty(RENAMING_TERM_PROPERTY), + correctFormula.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes of formulas should be equal modulo renaming"); } private Goal createGoal(Node n, TacletIndex tacletIndex) { @@ -853,6 +856,9 @@ public void testContextAdding() { expected.equalsModProperty(is, RENAMING_SOURCE_ELEMENT_PROPERTY, new NameAbstractionTable()), "Expected:" + expected + "\n but was:" + is); + assertEquals(expected.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + is.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + "Hash codes of ProgramElements should be equals modulo renaming."); } /** @@ -889,6 +895,9 @@ public void testRemoveEmptyBlock() { expected.equalsModProperty(is, RENAMING_SOURCE_ELEMENT_PROPERTY, new NameAbstractionTable()), "Expected:" + expected + "\n but was:" + is); + assertEquals(expected.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + is.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY), + "Hash codes of ProgramElements should be equal modulo renaming."); } @Test diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java b/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java index 8c2347bbc55..ec338c9d17d 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/conditions/TestApplyUpdateOnRigidCondition.java @@ -27,6 +27,9 @@ void updateWithoutVariables() { Term expected = TacletForTests.parseTerm("\\forall int a; {i:=0}(a = i)"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Update without free variables was not properly applied on formula!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (0)"); term = TacletForTests.parseTerm("{i:=0}(i = 0)"); result = applyUpdateOnFormula(term); @@ -39,6 +42,9 @@ void updateWithoutVariables() { expected = TacletForTests.parseTerm("f({i:=0} const)"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Update without free variables was not properly applied on term!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (1)"); } @Test @@ -53,6 +59,9 @@ void updateWithVariablesNoClash() { TacletForTests.parseTerm("\\forall int b; \\forall java.lang.Object a; {i:=b} (a = i)"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Update is not simply pulled over quantification!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (0)"); term = TacletForTests.parseTerm("\\forall int b; {i:=b} (0 = i)"); b = term.boundVars().get(0); @@ -60,6 +69,9 @@ void updateWithVariablesNoClash() { expected = TacletForTests.parseTerm("\\forall int b; {i:=b} 0 = {i:=b} i"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Update is not simply pulled over equality!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (1)"); term = TacletForTests.parseTerm("\\forall int b; {i:=b} f(const) = 0"); b = term.boundVars().get(0); @@ -67,6 +79,9 @@ void updateWithVariablesNoClash() { expected = TacletForTests.parseTerm("\\forall int b; f({i:=b} const) = 0"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Update is not simply pulled over function symbol!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (2)"); } @Test @@ -81,6 +96,9 @@ void updateWithVariablesAndClash() { .parseTerm("\\forall int a; \\forall java.lang.Object a1; {i:=a} (a1 = i)"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Renaming or applying update afterwards !"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (0)"); term = TacletForTests.parseTerm( "\\forall int a1; \\forall int a; {i:=a}\\forall java.lang.Object a; i = a1"); @@ -91,6 +109,9 @@ void updateWithVariablesAndClash() { "\\forall int a1; \\forall int a; \\forall java.lang.Object a2; {i:=a} (i = a1)"); assertTrue(expected.equalsModProperty(result, RENAMING_TERM_PROPERTY), "Counter appended to stem was not increased high enough!"); + assertEquals(expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Terms should be equal modulo renaming. (1)"); } @Test diff --git a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java index 10e0bf0b853..0f6d59684a5 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java +++ b/key.core/src/test/java/de/uka/ilkd/key/speclang/jml/TestJMLTranslator.java @@ -188,6 +188,9 @@ public void testForAll() { TB.and(TB.leq(TB.zTerm("0"), TB.var(i)), TB.leq(TB.var(i), TB.zTerm("2147483647"))))); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } @@ -204,6 +207,9 @@ public void testForEx() { TB.and(TB.leq(TB.zTerm("0"), TB.var(i)), TB.leq(TB.var(i), TB.zTerm("2147483647"))))); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } @@ -220,6 +226,9 @@ public void testBsumInt() { Assertions.assertSame(q, result.sub(0).op()); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } @@ -234,6 +243,9 @@ public void testBsumBigInt() { Assertions.assertSame(q, result.op()); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } @Test @@ -251,6 +263,9 @@ public void testInfiniteUnion() { TB.ife(guard, TB.empty(), TB.empty())); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } @Test @@ -269,6 +284,9 @@ public void testInfiniteUnion2() { TB.ife(guard, TB.empty(), TB.empty())); assertTrue(result.equalsModProperty(expected, RENAMING_TERM_PROPERTY), "Result was: " + result + "; \nExpected was: " + expected); + assertEquals(result.hashCodeModProperty(RENAMING_TERM_PROPERTY), + expected.hashCodeModProperty(RENAMING_TERM_PROPERTY), + "Hash codes should be equal modulo renaming."); } From 2c8849317b1425fc58ce0bfb344f8bcce5cfadc2 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 10 May 2024 18:29:07 +0200 Subject: [PATCH 40/73] change small things about hashCodeModProperty() when ignoring irrelevant or all term labels --- .../key/logic/equality/IrrelevantTermLabelsProperty.java | 8 ++++++-- .../uka/ilkd/key/logic/equality/TermLabelsProperty.java | 8 ++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java index 805f55cd4fc..9c6b0dc8cd6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/IrrelevantTermLabelsProperty.java @@ -98,8 +98,12 @@ public int hashCodeModThisProperty(Term term) { hashcode = hashcode * 17 + term.boundVars().hashCode(); hashcode = hashcode * 17 + term.javaBlock().hashCode(); - for (TermLabel label : term.getLabels()) { - hashcode += (label.isProofRelevant() ? 7 * label.hashCode() : 0); + final ImmutableArray labels = term.getLabels(); + for (int i = 0, sz = labels.size(); i < sz; i++) { + final TermLabel currentLabel = labels.get(i); + if (currentLabel.isProofRelevant()) { + hashcode += 7 * currentLabel.hashCode(); + } } return hashcode; diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java index 9bce4f5aeb7..d44f9915cc1 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/TermLabelsProperty.java @@ -66,16 +66,16 @@ public boolean equalsModThisProperty(Term term1, Term term2, V... v) { /** * Computes the hash code of {@code term} while ignoring all term labels. - *

    - * Currently, the hash code is computed almost the same way as in TermImpl. This is also the - * case for labeled terms, - * as all term labels are ignored. * * @param term the term to compute the hash code for * @return the hash code */ @Override public int hashCodeModThisProperty(Term term) { + /* + * Currently, the hash code is computed almost the same way as in TermImpl. This is also the + * case for labeled terms, as all term labels are ignored. + */ int hashcode = 5; hashcode = hashcode * 17 + term.op().hashCode(); hashcode = hashcode * 17 From f3f95339c45c9a1027b0c0476ba10f547c6ebc7e Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Sun, 12 May 2024 15:19:53 +0200 Subject: [PATCH 41/73] start idea for hash codes modulo renaming on SourceElements --- .../RenamingSourceElementProperty.java | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 82279627ec6..d638d415771 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -97,11 +97,44 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V @Override public int hashCodeModThisProperty(SourceElement sourceElement) { - throw new UnsupportedOperationException( - "Hashing of SourceElements modulo renaming not yet implemented!"); + /* + * Currently, the best approach seems to walk through the sourceElement with a + * JavaASTTreeWalker and sum up hash codes. + */ + JavaASTTreeWalker tw = new JavaASTTreeWalker(sourceElement); + SourceElement next = tw.currentNode(); + + int hashCode = 1; + + while (next != null) { + // Handle special cases of prior equalsModRenaming implementation + if (next instanceof LabeledStatement ls) { + // TODO: decide what to add here; + hashCode = 31 * hashCode + ls.getChildCount(); + } else if (next instanceof VariableSpecification vs) { + hashCode = 31 * hashCode + 5; + } else if (next instanceof ProgramVariable || next instanceof ProgramElementName) { + // TODO: decide what to add here; + hashCode = 31 * hashCode + 37; + } else if (next instanceof JavaNonTerminalProgramElement jnte) { + // TODO: decide what to add here; + hashCode = 31 * hashCode + 43; + } else { + // In the standard case, we just use the default hashCode implementation + hashCode = 31 * hashCode + next.hashCode(); + } + + // walk to the next nodes in the tree + next = tw.nextNode(); + } + + return hashCode; } - /* --------------------- Helper methods for special cases ---------------------- */ + /* + * --------------------- Helper methods for special cases in equalsModThisProperty + * ---------------------- + */ /** * Handles the standard case of comparing two {@link SourceElement}s modulo renaming. * @@ -244,5 +277,8 @@ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElem } - /* ------------------ End of helper methods for special cases ------------------ */ + /* + * ------------------ End of helper methods for special cases in + * equalsModThisProperty------------------ + */ } From 76f72587323f52b98100e1768e16ef424a76bdc9 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 16 May 2024 18:10:03 +0200 Subject: [PATCH 42/73] start implementation of more complex hash function (still has a bug) --- .../RenamingSourceElementProperty.java | 44 ++++++++++++------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index d638d415771..bf0517a21f4 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -3,6 +3,8 @@ * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.logic.equality; +import java.util.*; + import de.uka.ilkd.key.java.JavaNonTerminalProgramElement; import de.uka.ilkd.key.java.NameAbstractionTable; import de.uka.ilkd.key.java.SourceElement; @@ -104,21 +106,27 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { JavaASTTreeWalker tw = new JavaASTTreeWalker(sourceElement); SourceElement next = tw.currentNode(); + NameAbstractionMap absMap = new NameAbstractionMap(); + int hashCode = 1; while (next != null) { - // Handle special cases of prior equalsModRenaming implementation + // Handle special cases so that hashCodeModThisProperty fits equalsModThisProperty if (next instanceof LabeledStatement ls) { - // TODO: decide what to add here; hashCode = 31 * hashCode + ls.getChildCount(); + absMap.add(ls); } else if (next instanceof VariableSpecification vs) { - hashCode = 31 * hashCode + 5; + hashCode = 31 * hashCode + vs.getChildCount(); + hashCode = + 31 * hashCode + 17 * ((vs.getType() == null) ? 0 : vs.getType().hashCode()) + + vs.getDimensions(); + absMap.add(vs); } else if (next instanceof ProgramVariable || next instanceof ProgramElementName) { - // TODO: decide what to add here; - hashCode = 31 * hashCode + 37; + // TODO: fix; somehow this returns null, meaning that something must be looked up, + // that is not yet in the map + hashCode = 31 * hashCode + absMap.getDepth(next); } else if (next instanceof JavaNonTerminalProgramElement jnte) { - // TODO: decide what to add here; - hashCode = 31 * hashCode + 43; + hashCode = 31 * hashCode + jnte.getChildCount(); } else { // In the standard case, we just use the default hashCode implementation hashCode = 31 * hashCode + next.hashCode(); @@ -131,10 +139,7 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { return hashCode; } - /* - * --------------------- Helper methods for special cases in equalsModThisProperty - * ---------------------- - */ + /*------------- Helper methods for special cases in equalsModThisProperty --------------*/ /** * Handles the standard case of comparing two {@link SourceElement}s modulo renaming. * @@ -277,8 +282,17 @@ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElem } - /* - * ------------------ End of helper methods for special cases in - * equalsModThisProperty------------------ - */ + /* ---------- End of helper methods for special cases in equalsModThisProperty ---------- */ + + private static class NameAbstractionMap { + private final Map declarationsMap = new HashMap<>(); + + public void add(SourceElement element) { + declarationsMap.put(element, declarationsMap.size()); + } + + public int getDepth(SourceElement element) { + return declarationsMap.get(element); + } + } } From 7cfdcc2e89fd1467f23b0de68522e927a92b027b Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 16 May 2024 20:44:21 +0200 Subject: [PATCH 43/73] fix and finish hashCodeModThisProperty for RenamingSourceElementProperty --- .../RenamingSourceElementProperty.java | 42 +++++++++++++++---- 1 file changed, 35 insertions(+), 7 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index bf0517a21f4..233fbdc5a2b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -122,9 +122,7 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { + vs.getDimensions(); absMap.add(vs); } else if (next instanceof ProgramVariable || next instanceof ProgramElementName) { - // TODO: fix; somehow this returns null, meaning that something must be looked up, - // that is not yet in the map - hashCode = 31 * hashCode + absMap.getDepth(next); + hashCode = 31 * hashCode + absMap.getAbstractName(next); } else if (next instanceof JavaNonTerminalProgramElement jnte) { hashCode = 31 * hashCode + jnte.getChildCount(); } else { @@ -284,15 +282,45 @@ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElem /* ---------- End of helper methods for special cases in equalsModThisProperty ---------- */ + /** + * A helper class to map {@link SourceElement}s to an abstract name. + *

    + * As names are abstracted from in this property, we need to give named elements abstract names + * for them to be used in the hash code. This approach is similar to + * {@link NameAbstractionTable}, where we collect elements with names in the order they are + * declared. Each element is associated with the number of previously added elements, which is + * then used as the abstract name. + */ private static class NameAbstractionMap { - private final Map declarationsMap = new HashMap<>(); + /** + * The map that associates {@link SourceElement}s with their abstract names. + */ + private final Map map = new HashMap<>(); + /** + * Adds a {@link SourceElement} to the map. + * + * @param element the {@link SourceElement} to be added + */ public void add(SourceElement element) { - declarationsMap.put(element, declarationsMap.size()); + map.put(element, map.size()); } - public int getDepth(SourceElement element) { - return declarationsMap.get(element); + /** + * Returns the abstract name of a {@link SourceElement} or {@code -1} if the element is not + * in the map. + *

    + * A common case for a look-up of an element that is not in the map, is a built-in datatype, + * e.g., the {@link ProgramElementName} {@code int}. + * + * @param element the {@link SourceElement} whose abstract name should be returned + * @return the abstract name of the {@link SourceElement} or {@code -1} if the element is + * not + * in the map + */ + public int getAbstractName(SourceElement element) { + final Integer result = map.get(element); + return result != null ? result : -1; } } } From 09ebe685689d65c60c9d960c8c7c1d6136a3124b Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 17 May 2024 20:11:20 +0200 Subject: [PATCH 44/73] start implementation of hashCodeModThisProperty for RenamingTermProperty (wip) --- .../RenamingSourceElementProperty.java | 3 +- .../logic/equality/RenamingTermProperty.java | 55 ++++++++++++++++++- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 233fbdc5a2b..e71c94759cd 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -315,8 +315,7 @@ public void add(SourceElement element) { * * @param element the {@link SourceElement} whose abstract name should be returned * @return the abstract name of the {@link SourceElement} or {@code -1} if the element is - * not - * in the map + * not in the map */ public int getAbstractName(SourceElement element) { final Integer result = map.get(element); diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index a8333ab77f4..b5c4d3e7bbb 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -64,8 +64,8 @@ public boolean equalsModThisProperty(Term term1, Term term2, V... v) { */ @Override public int hashCodeModThisProperty(Term term) { - throw new UnsupportedOperationException( - "Hashing of terms modulo renaming not yet implemented!"); + // Labels can be completely ignored + return helper1(term, ImmutableSLList.nil()); } // equals modulo renaming logic @@ -250,6 +250,14 @@ private boolean descendRecursively(Term t0, Term t1, return true; } + + /** + * Checks if the given {@link NameAbstractionTable} is not null. If it is null, a new + * {@link NameAbstractionTable} is created and returned. + * + * @param nat the {@link NameAbstractionTable} to check + * @return the given {@code nat} if it is not null, a new {@link NameAbstractionTable} otherwise + */ private static NameAbstractionTable checkNat(NameAbstractionTable nat) { if (nat == null) { return new NameAbstractionTable(); @@ -258,4 +266,47 @@ private static NameAbstractionTable checkNat(NameAbstractionTable nat) { } // end of equals modulo renaming logic + /* -------- Helper methods for hashCodeModThisProperty --------- */ + + private int helper1(Term term, ImmutableList list) { + // mirrors the implementation of unifyHelp that is responsible for equality modulo renaming + int hashCode = 1; + hashCode = 17 * hashCode + term.sort().hashCode(); + hashCode = 17 * hashCode + term.arity(); + + final Operator op = term.op(); + if (op instanceof QuantifiableVariable qv) { + hashCode = 17 * hashCode + hashQuantifiableVariable(qv, list); + } else if (op instanceof Modality mod) { + hashCode = 17 * hashCode + mod.kind().hashCode(); + hashCode = 17 * hashCode + hashJavaBlock(mod); + } else if (op instanceof ProgramVariable pv) { + hashCode = 17 * hashCode + pv.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY); + } + + return recursiveHelper(hashCode, list); + } + + private int hashQuantifiableVariable(QuantifiableVariable qv, + ImmutableList list) { + final int index = indexOf(qv, list); + // if the variable is not bound, it can make a big difference + // if the variable is bound, we just need to consider the place it is bound at + return index == -1 ? qv.hashCode() : index; + } + + private int hashJavaBlock(Modality mod) { + final JavaBlock jb = mod.program(); + if (!jb.isEmpty()) { + final JavaProgramElement jpe = jb.program(); + return jpe != null ? jpe.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY) : 0; + } + return 0; + } + + private int recursiveHelper(int hashCode, ImmutableList list) { + return 0; + } + + /* ----- End of helper methods for hashCodeModThisProperty ----- */ } From 3d70ce012aa47ffb3bf47ad2b0d2497041b59e53 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 21 May 2024 17:59:57 +0200 Subject: [PATCH 45/73] finish implementation of hashCodeModThisProperty for RenamingTermProperty --- .../logic/equality/RenamingTermProperty.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index b5c4d3e7bbb..efbfa78d973 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -65,7 +65,7 @@ public boolean equalsModThisProperty(Term term1, Term term2, V... v) { @Override public int hashCodeModThisProperty(Term term) { // Labels can be completely ignored - return helper1(term, ImmutableSLList.nil()); + return helper1(term, ImmutableSLList.nil(), 1); } // equals modulo renaming logic @@ -268,9 +268,8 @@ private static NameAbstractionTable checkNat(NameAbstractionTable nat) { /* -------- Helper methods for hashCodeModThisProperty --------- */ - private int helper1(Term term, ImmutableList list) { + private int helper1(Term term, ImmutableList list, int hashCode) { // mirrors the implementation of unifyHelp that is responsible for equality modulo renaming - int hashCode = 1; hashCode = 17 * hashCode + term.sort().hashCode(); hashCode = 17 * hashCode + term.arity(); @@ -284,7 +283,7 @@ private int helper1(Term term, ImmutableList list) { hashCode = 17 * hashCode + pv.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY); } - return recursiveHelper(hashCode, list); + return recursiveHelper(term, list, hashCode); } private int hashQuantifiableVariable(QuantifiableVariable qv, @@ -304,8 +303,19 @@ private int hashJavaBlock(Modality mod) { return 0; } - private int recursiveHelper(int hashCode, ImmutableList list) { - return 0; + private int recursiveHelper(Term term, ImmutableList list, int hashCode) { + for (int i = 0; i < term.arity(); i++) { + ImmutableList subBoundVars = list; + + for (int j = 0; j < term.varsBoundHere(i).size(); j++) { + final QuantifiableVariable qVar = term.varsBoundHere(i).get(j); + hashCode = 17 * hashCode + qVar.sort().hashCode(); + subBoundVars = subBoundVars.prepend(qVar); + } + + hashCode = helper1(term.sub(i), subBoundVars, hashCode); + } + return hashCode; } /* ----- End of helper methods for hashCodeModThisProperty ----- */ From 9bda17afd4240d3b5e67489bc664d74eca019d85 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 22 May 2024 18:49:10 +0200 Subject: [PATCH 46/73] add doc to RenamingTermProperty --- .../logic/equality/RenamingTermProperty.java | 100 ++++++++++++++++-- 1 file changed, 89 insertions(+), 11 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java index efbfa78d973..0931009a9b8 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingTermProperty.java @@ -65,7 +65,7 @@ public boolean equalsModThisProperty(Term term1, Term term2, V... v) { @Override public int hashCodeModThisProperty(Term term) { // Labels can be completely ignored - return helper1(term, ImmutableSLList.nil(), 1); + return hashTermHelper(term, ImmutableSLList.nil(), 1); } // equals modulo renaming logic @@ -166,6 +166,15 @@ private boolean unifyHelp(Term t0, Term t1, ImmutableList return descendRecursively(t0, t1, ownBoundVars, cmpBoundVars, nat); } + /** + * Handles the case where the first term is a quantifiable variable. + * + * @param t0 the first term + * @param t1 the second term + * @param ownBoundVars variables bound above the current position in {@code t0} + * @param cmpBoundVars variables bound above the current position in {@code t1} + * @return true iff the quantifiable variables are equal modulo renaming + */ private boolean handleQuantifiableVariable(Term t0, Term t1, ImmutableList ownBoundVars, ImmutableList cmpBoundVars) { @@ -180,6 +189,16 @@ && compareBoundVariables((QuantifiableVariable) t0.op(), */ private static final NameAbstractionTable FAILED = new NameAbstractionTable(); + /** + * Checks whether the given {@link JavaBlock}s are equal modulo renaming and returns the updated + * {@link NameAbstractionTable} or {@link #FAILED} if the {@link JavaBlock}s are not equal. + * + * @param jb0 the first {@link JavaBlock} to compare + * @param jb1 the second {@link JavaBlock} to compare + * @param nat the {@link NameAbstractionTable} used for the comparison + * @return the updated {@link NameAbstractionTable} if the {@link JavaBlock}s are equal modulo + * renaming or {@link #FAILED} if they are not + */ private static NameAbstractionTable handleJava(JavaBlock jb0, JavaBlock jb1, NameAbstractionTable nat) { if (!jb0.isEmpty() || !jb1.isEmpty()) { @@ -217,6 +236,17 @@ public static boolean javaBlocksNotEqualModRenaming(JavaBlock jb1, JavaBlock jb2 return true; } + /** + * Recursively descends into the subterms of the given terms and checks if they are equal modulo + * renaming. + * + * @param t0 the first term + * @param t1 the second term + * @param ownBoundVars variables bound above the current position in {@code t0} + * @param cmpBoundVars variables bound above the current position in {@code t1} + * @param nat the {@link NameAbstractionTable} used for the comparison + * @return true iff the subterms are equal modulo renaming + */ private boolean descendRecursively(Term t0, Term t1, ImmutableList ownBoundVars, ImmutableList cmpBoundVars, NameAbstractionTable nat) { @@ -266,16 +296,30 @@ private static NameAbstractionTable checkNat(NameAbstractionTable nat) { } // end of equals modulo renaming logic + /* -------- Helper methods for hashCodeModThisProperty --------- */ - private int helper1(Term term, ImmutableList list, int hashCode) { + /** + * Helps to compute the hash code of a term modulo bound renaming. + *

    + * This method takes care of the top level of the term and calls the recursive helper method + * {@link #recursiveHelper(Term, ImmutableList, int)} to take care of the subterms. + * + * @param term the term to compute the hash code for + * @param nameAbstractionList the list of bound variables that is used to abstract from the + * variable names + * @param hashCode the accumulated hash code (should be 1 for the first call) + * @return the hash code + */ + private int hashTermHelper(Term term, ImmutableList nameAbstractionList, + int hashCode) { // mirrors the implementation of unifyHelp that is responsible for equality modulo renaming hashCode = 17 * hashCode + term.sort().hashCode(); hashCode = 17 * hashCode + term.arity(); final Operator op = term.op(); if (op instanceof QuantifiableVariable qv) { - hashCode = 17 * hashCode + hashQuantifiableVariable(qv, list); + hashCode = 17 * hashCode + hashQuantifiableVariable(qv, nameAbstractionList); } else if (op instanceof Modality mod) { hashCode = 17 * hashCode + mod.kind().hashCode(); hashCode = 17 * hashCode + hashJavaBlock(mod); @@ -283,29 +327,63 @@ private int helper1(Term term, ImmutableList list, int has hashCode = 17 * hashCode + pv.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY); } - return recursiveHelper(term, list, hashCode); + return recursiveHelper(term, nameAbstractionList, hashCode); } + /** + * Computes the hash code of a quantifiable variable modulo bound renaming. + *

    + * If the variable is bound, the hash code is computed based on the index of the variable in the + * list of bound variables. + * If the variable is not bound, the hash code is computed based on the variable itself. + * + * @param qv the {@link QuantifiableVariable} to compute the hash code for + * @param nameAbstractionList the list of bound variables that is used to abstract from the + * variable names + * @return the hash code + */ private int hashQuantifiableVariable(QuantifiableVariable qv, - ImmutableList list) { - final int index = indexOf(qv, list); - // if the variable is not bound, it can make a big difference - // if the variable is bound, we just need to consider the place it is bound at + ImmutableList nameAbstractionList) { + final int index = indexOf(qv, nameAbstractionList); + // if the variable is bound, we just need to consider the place it is bound at and abstract + // from the name return index == -1 ? qv.hashCode() : index; } + /** + * Computes the hash code of a Java block modulo bound renaming. + *

    + * The hash code is computed based on the hash code of the program element of the Java block. + * + * @param mod the {@link Modality} to compute the hash code for + * @return the hash code + */ private int hashJavaBlock(Modality mod) { final JavaBlock jb = mod.program(); if (!jb.isEmpty()) { final JavaProgramElement jpe = jb.program(); return jpe != null ? jpe.hashCodeModProperty(RENAMING_SOURCE_ELEMENT_PROPERTY) : 0; } + // if the Java block is empty, we do not add anything to the hash code return 0; } - private int recursiveHelper(Term term, ImmutableList list, int hashCode) { + /** + * Recursively computes the hash code of a term modulo bound renaming. + *

    + * This method iterates over the subterms of the given term and calls + * {@link #hashTermHelper(Term, ImmutableList, int)} for each subterm. + * + * @param term the term to compute the hash code for + * @param nameAbstractionList the list of bound variables that is used to abstract from the + * variable names + * @param hashCode the accumulated hash code + * @return the hash code + */ + private int recursiveHelper(Term term, ImmutableList nameAbstractionList, + int hashCode) { for (int i = 0; i < term.arity(); i++) { - ImmutableList subBoundVars = list; + ImmutableList subBoundVars = nameAbstractionList; for (int j = 0; j < term.varsBoundHere(i).size(); j++) { final QuantifiableVariable qVar = term.varsBoundHere(i).get(j); @@ -313,7 +391,7 @@ private int recursiveHelper(Term term, ImmutableList list, subBoundVars = subBoundVars.prepend(qVar); } - hashCode = helper1(term.sub(i), subBoundVars, hashCode); + hashCode = hashTermHelper(term.sub(i), subBoundVars, hashCode); } return hashCode; } From 99faea37bf2b5bb2bb0efee392c5516b2de8259e Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 11 Jun 2024 18:27:21 +0200 Subject: [PATCH 47/73] delete file --- .../java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java b/key.core/src/main/java/de/uka/ilkd/key/rule/match/legacy/ElementMatcher.java deleted file mode 100644 index e69de29bb2d..00000000000 From 195722624911fddb565577367f5a787df796fcef Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 11 Jun 2024 18:27:59 +0200 Subject: [PATCH 48/73] change author --- key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java b/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java index 00701a9dae8..1d3bc9698ff 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java +++ b/key.core/src/main/java/de/uka/ilkd/key/ldt/FreeLDT.java @@ -22,7 +22,7 @@ * Generic data type, which has no predefined theory. It is meant as a basis to implement an * additional abstract data type, e.g., binary trees, stacks, etc. in .key files. * - * @author Daniel Bruns + * @author Daniel Grahl * */ public final class FreeLDT extends LDT { From 0dfe70b95b4456b397eae0f6b51f9c7b7021a849 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 12 Jun 2024 16:20:12 +0200 Subject: [PATCH 49/73] remove unnecessary override of equals --- .../key/java/statement/LabeledStatement.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java index a864d451754..845af967733 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/statement/LabeledStatement.java @@ -260,27 +260,6 @@ public Statement getStatementAt(int index) { throw new ArrayIndexOutOfBoundsException(); } - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o == null || o.getClass() != this.getClass()) { - return false; - } - - final JavaNonTerminalProgramElement jnte = (JavaNonTerminalProgramElement) o; - if (jnte.getChildCount() != getChildCount()) { - return false; - } - for (int i = 0, cc = getChildCount(); i < cc; i++) { - if (!getChildAt(i).equals(jnte.getChildAt(i))) { - return false; - } - } - return true; - } - /** * calls the corresponding method of a visitor in order to perform some action/transformation on * this element From 1ee32939fcbd768ee7526425f410a5ae4b3afe85 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 12 Jun 2024 16:39:48 +0200 Subject: [PATCH 50/73] override computeHashCode() --- .../ilkd/key/java/expression/literal/EmptyMapLiteral.java | 5 +++++ .../ilkd/key/java/expression/literal/EmptySeqLiteral.java | 5 +++++ .../ilkd/key/java/expression/literal/EmptySetLiteral.java | 5 +++++ .../de/uka/ilkd/key/java/expression/literal/FreeLiteral.java | 5 +++++ .../de/uka/ilkd/key/java/expression/literal/NullLiteral.java | 5 +++++ 5 files changed, 25 insertions(+) diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java index b923423cf69..624c6bacd83 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptyMapLiteral.java @@ -24,6 +24,11 @@ public boolean equals(Object o) { return o == this; } + @Override + protected int computeHashCode() { + return System.identityHashCode(this); + } + @Override public void visit(Visitor v) { v.performActionOnEmptyMapLiteral(this); diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java index 518a7043587..55977ab30a5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySeqLiteral.java @@ -25,6 +25,11 @@ public boolean equals(Object o) { return o == this; } + @Override + protected int computeHashCode() { + return System.identityHashCode(this); + } + public void visit(Visitor v) { v.performActionOnEmptySeqLiteral(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java index 7ea29d65dbe..9a2b50139f5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/EmptySetLiteral.java @@ -23,6 +23,11 @@ public boolean equals(Object o) { return o == this; } + @Override + protected int computeHashCode() { + return System.identityHashCode(this); + } + public void visit(Visitor v) { v.performActionOnEmptySetLiteral(this); } diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java index 4ef309c9915..9dbf4075cc5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/FreeLiteral.java @@ -25,6 +25,11 @@ public boolean equals(Object o) { return o == this; } + @Override + protected int computeHashCode() { + return System.identityHashCode(this); + } + @Override public void visit(Visitor v) { // TODO Auto-generated method stub diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java index 73f7337b802..7bb242c5201 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/expression/literal/NullLiteral.java @@ -30,6 +30,11 @@ public boolean equals(Object o) { return o == this; } + @Override + protected int computeHashCode() { + return System.identityHashCode(this); + } + /** * calls the corresponding method of a visitor in order to perform some action/transformation on * this element From 672b6b70977f1f7b7eadbae33d767bd481bd1f29 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 13 Jun 2024 15:57:58 +0200 Subject: [PATCH 51/73] move LinkedHashMapWrapper --- .../de/uka/ilkd/key/{logic => }/util/LinkedHashMapWrapper.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename key.core/src/main/java/de/uka/ilkd/key/{logic => }/util/LinkedHashMapWrapper.java (99%) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java similarity index 99% rename from key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java rename to key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java index 77825d3aef3..6d2cfd6a18a 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java @@ -1,14 +1,13 @@ /* This file is part of KeY - https://key-project.org * KeY is licensed under the GNU General Public License Version 2 * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.logic.util; +package de.uka.ilkd.key.util; import java.util.Iterator; import de.uka.ilkd.key.logic.Term; import de.uka.ilkd.key.logic.equality.EqualsModProperty; import de.uka.ilkd.key.logic.equality.Property; -import de.uka.ilkd.key.util.LinkedHashMap; import org.key_project.util.collection.Pair; From e4a563eaeb105ebda70bedabdba88f1ab8398b51 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 13 Jun 2024 15:58:21 +0200 Subject: [PATCH 52/73] start tests for LinkedHashMapWrapper --- .../key/util/TestLinkedHashMapWrapper.java | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java new file mode 100644 index 00000000000..a7590247179 --- /dev/null +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -0,0 +1,75 @@ +package de.uka.ilkd.key.util; + + +import de.uka.ilkd.key.java.Comment; +import de.uka.ilkd.key.java.NameAbstractionTable; +import de.uka.ilkd.key.java.ProgramElement; +import de.uka.ilkd.key.java.expression.literal.StringLiteral; +import de.uka.ilkd.key.logic.*; +import de.uka.ilkd.key.logic.label.*; +import de.uka.ilkd.key.logic.op.*; +import de.uka.ilkd.key.rule.TacletForTests; +import de.uka.ilkd.key.util.HelperClassForTests; + +import org.key_project.util.collection.ImmutableArray; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; +import static de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty.PROOF_IRRELEVANCY_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; +import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY; +import static de.uka.ilkd.key.logic.equality.TermLabelsProperty.TERM_LABELS_PROPERTY; +import static org.junit.jupiter.api.Assertions.*; + +public class TestLinkedHashMapWrapper { + private TermBuilder tb; + + private TermFactory tf; + + final private TermLabel relevantLabel1 = ParameterlessTermLabel.UNDEFINED_VALUE_LABEL; + final private TermLabel relevantLabel2 = ParameterlessTermLabel.SHORTCUT_EVALUATION_LABEL; + private static TermLabel irrelevantLabel = null; + final private static OriginTermLabelFactory factory = new OriginTermLabelFactory(); + + @BeforeAll + public static void setIrrelevantLabel() { + try { + irrelevantLabel = factory.parseInstance(Arrays.stream(new String[] { + "User_Interaction @ node 0 (Test Test)", "[]" }).toList(), + HelperClassForTests.createServices()); + } catch (TermLabelException e) { + fail(e); + } + } + + @BeforeEach + public void setUp() { + tb = TacletForTests.services().getTermBuilder(); + tf = TacletForTests.services().getTermFactory(); + } + + @Test + public void testRenamingProperty() { + + } + + @Test + public void testTermLabelsProperty() { + Term t1 = tb.tt(); + } + + @Test + public void testIrrelevantTermLabelsProperty() { + + } + + @Test + public void testProofIrrelevancyProperty() { + + } +} From c25051653f81585dac74a49dfaa58461452d3e9f Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 17 Jun 2024 13:43:44 +0200 Subject: [PATCH 53/73] write more tests for LinkedHashMapWrapper (WIP) --- .../key/util/TestLinkedHashMapWrapper.java | 106 +++++++++++++++--- 1 file changed, 92 insertions(+), 14 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index a7590247179..6cbff536800 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -1,15 +1,16 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.util; -import de.uka.ilkd.key.java.Comment; -import de.uka.ilkd.key.java.NameAbstractionTable; -import de.uka.ilkd.key.java.ProgramElement; -import de.uka.ilkd.key.java.expression.literal.StringLiteral; +import java.util.Arrays; + +import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; import de.uka.ilkd.key.logic.op.*; import de.uka.ilkd.key.rule.TacletForTests; -import de.uka.ilkd.key.util.HelperClassForTests; import org.key_project.util.collection.ImmutableArray; @@ -17,8 +18,6 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import java.util.Arrays; - import static de.uka.ilkd.key.logic.equality.IrrelevantTermLabelsProperty.IRRELEVANT_TERM_LABELS_PROPERTY; import static de.uka.ilkd.key.logic.equality.ProofIrrelevancyProperty.PROOF_IRRELEVANCY_PROPERTY; import static de.uka.ilkd.key.logic.equality.RenamingSourceElementProperty.RENAMING_SOURCE_ELEMENT_PROPERTY; @@ -40,8 +39,8 @@ public class TestLinkedHashMapWrapper { public static void setIrrelevantLabel() { try { irrelevantLabel = factory.parseInstance(Arrays.stream(new String[] { - "User_Interaction @ node 0 (Test Test)", "[]" }).toList(), - HelperClassForTests.createServices()); + "User_Interaction @ node 0 (Test Test)", "[]" }).toList(), + HelperClassForTests.createServices()); } catch (TermLabelException e) { fail(e); } @@ -54,22 +53,101 @@ public void setUp() { } @Test - public void testRenamingProperty() { + public void testGeneralMethods() { + // exact property does not matter for these tests + LinkedHashMapWrapper wrappedMap = + new LinkedHashMapWrapper<>(TERM_LABELS_PROPERTY); + assertTrue(wrappedMap.isEmpty()); + assertEquals(0, wrappedMap.size()); + Term t1 = tb.tt(); + Term t2 = tb.ff(); + + // add mapping t1 -> 1 + wrappedMap.put(t1, 1); + assertEquals(1, wrappedMap.size()); + assertFalse(wrappedMap.isEmpty()); + assertTrue(wrappedMap.containsKey(t1)); + assertEquals(1, wrappedMap.get(t1)); + assertTrue(wrappedMap.containsValue(1)); + assertFalse(wrappedMap.containsValue(2)); + + // add mapping t2 -> 2 + wrappedMap.put(t2, 2); + assertEquals(2, wrappedMap.size()); + assertFalse(wrappedMap.isEmpty()); + assertTrue(wrappedMap.containsKey(t2)); + assertEquals(2, wrappedMap.get(t2)); + assertTrue(wrappedMap.containsValue(2)); + assertFalse(wrappedMap.containsValue(3)); + + // remove mapping t1 -> 1 + int t1Val = wrappedMap.remove(t1); + assertEquals(1, wrappedMap.size()); + assertFalse(wrappedMap.containsKey(t1)); + assertEquals(1, t1Val); + assertFalse(wrappedMap.containsValue(1)); + + // remove mapping t2 -> 2 + int t2Val = wrappedMap.remove(t2); + assertEquals(0, wrappedMap.size()); + assertTrue(wrappedMap.isEmpty()); + assertFalse(wrappedMap.containsKey(t2)); + assertEquals(2, t2Val); + assertFalse(wrappedMap.containsValue(2)); } @Test - public void testTermLabelsProperty() { - Term t1 = tb.tt(); + public void testRenamingSourceElementProperty() { + LinkedHashMapWrapper renamingSourceElementMap = + new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); + LinkedHashMap basicMap = new LinkedHashMap<>(); + + } @Test - public void testIrrelevantTermLabelsProperty() { - + public void testTermLabelProperties() { + LinkedHashMap basicMap = new LinkedHashMap<>(); + LinkedHashMapWrapper termLabelsMap = + new LinkedHashMapWrapper<>(TERM_LABELS_PROPERTY); + LinkedHashMapWrapper irrelevantTermLabelsMap = + new LinkedHashMapWrapper<>(IRRELEVANT_TERM_LABELS_PROPERTY); + + + Term noLabelTerm = tb.tt(); + ImmutableArray labels = new ImmutableArray<>(irrelevantLabel); + Term irrelevantLabelTerm = tb.label(noLabelTerm, labels); + labels = new ImmutableArray<>(relevantLabel1); + Term relevantLabelTerm = tb.label(noLabelTerm, labels); } @Test public void testProofIrrelevancyProperty() { + LinkedHashMapWrapper ProofIrrelevancyMap = + new LinkedHashMapWrapper<>(PROOF_IRRELEVANCY_PROPERTY); + + } + + @Test + public void testRenamingTermProperty() { + LinkedHashMapWrapper renamingTermMap = + new LinkedHashMapWrapper<>(RENAMING_TERM_PROPERTY); + + } + + @Test + public void testConstructors() { + + } + + @Test + public void testPutAll() { + + } + + @Test + public void testSpecialCases() { } } From cf76f0bcb48fd1ac902c738dbbc1b700b80a5295 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Mon, 17 Jun 2024 15:41:32 +0200 Subject: [PATCH 54/73] fix bug where equals() of ElementWrapper did not function properly --- .../main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java index 6d2cfd6a18a..801628acfe0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java @@ -272,7 +272,10 @@ public ElementWrapper(K key, Property property) { @Override public boolean equals(Object obj) { - return key.equalsModProperty(obj, property); + if (obj instanceof ElementWrapper other) { + return key.equalsModProperty(other.key, property); + } + return false; } @Override From 25c2d0222cd230c982cda9fdb9a1c5632dfe6d12 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 18 Jun 2024 11:11:53 +0200 Subject: [PATCH 55/73] write more tests (WIP) --- .../key/util/TestLinkedHashMapWrapper.java | 71 ++++++++++++++----- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index 6cbff536800..7778dd906fc 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -97,15 +97,6 @@ public void testGeneralMethods() { assertFalse(wrappedMap.containsValue(2)); } - @Test - public void testRenamingSourceElementProperty() { - LinkedHashMapWrapper renamingSourceElementMap = - new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); - LinkedHashMap basicMap = new LinkedHashMap<>(); - - - } - @Test public void testTermLabelProperties() { LinkedHashMap basicMap = new LinkedHashMap<>(); @@ -114,12 +105,50 @@ public void testTermLabelProperties() { LinkedHashMapWrapper irrelevantTermLabelsMap = new LinkedHashMapWrapper<>(IRRELEVANT_TERM_LABELS_PROPERTY); + Term noLabelTT = tb.tt(); + Term noLabelFF = tb.ff(); + + Term irrelevantLabelTT = tb.label(noLabelTT, irrelevantLabel); + Term irrelevantLabelFF = tb.label(noLabelFF, irrelevantLabel); + Term relevantLabelTT = tb.label(noLabelTT, relevantLabel1); + Term relevantLabelFF = tb.label(noLabelFF, relevantLabel2); + + // add mappings without labels to all maps + basicMap.put(noLabelTT, 1); + basicMap.put(noLabelFF, 2); + assertEquals(2, basicMap.size()); + + termLabelsMap.put(noLabelTT, 1); + termLabelsMap.put(noLabelFF, 2); + assertEquals(2, termLabelsMap.size()); + + irrelevantTermLabelsMap.put(noLabelTT, 1); + irrelevantTermLabelsMap.put(noLabelFF, 2); + assertEquals(2, irrelevantTermLabelsMap.size()); + + // add mappings with irrelevant labels to all maps + assertNull(basicMap.put(irrelevantLabelTT, 3), "Nothing should be returned as basicMap should not contain the key"); + assertEquals(3, basicMap.size()); + + assertEquals(1, termLabelsMap.put(irrelevantLabelTT, 3), "Old value should be returned as termLabelsMap should already contain the key"); + assertEquals(2, termLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(3, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); + + assertEquals(1, irrelevantTermLabelsMap.put(irrelevantLabelTT, 3), "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); + assertEquals(2, irrelevantTermLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(3, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key without label should return new value"); + + // add mappings with relevant labels to all maps + + assertNull(basicMap.put(relevantLabelTT, 4), "Nothing should be returned as basicMap should not contain the key"); + assertEquals(4, basicMap.size()); + + assertEquals(3, termLabelsMap.put(relevantLabelTT, 4), "Value 3 should be returned as termLabelsMap was previously updated with irrelevantLabelTT"); + assertEquals(3, termLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(4, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); + assertEquals(4, termLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return new value"); + - Term noLabelTerm = tb.tt(); - ImmutableArray labels = new ImmutableArray<>(irrelevantLabel); - Term irrelevantLabelTerm = tb.label(noLabelTerm, labels); - labels = new ImmutableArray<>(relevantLabel1); - Term relevantLabelTerm = tb.label(noLabelTerm, labels); } @Test @@ -137,13 +166,23 @@ public void testRenamingTermProperty() { } @Test - public void testConstructors() { + public void testRenamingSourceElementProperty() { + LinkedHashMapWrapper renamingSourceElementMap = + new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); + LinkedHashMap basicMap = new LinkedHashMap<>(); + } @Test - public void testPutAll() { + public void testConstructors() { + LinkedHashMapWrapper wrappedMap = + new LinkedHashMapWrapper<>(tb.tt(), 1, TERM_LABELS_PROPERTY); + assertFalse(wrappedMap.isEmpty()); + assertEquals(1, wrappedMap.size()); + assertTrue(wrappedMap.containsKey(tb.tt())); + // putAll is also tested with these constructor calls } @Test From e8b44eb703602d2da33512c519f3326a9a1b563a Mon Sep 17 00:00:00 2001 From: Tobias Date: Tue, 18 Jun 2024 12:55:51 +0200 Subject: [PATCH 56/73] write more tests for LinkedHashMapWrapper (still WIP) --- .../key/util/TestLinkedHashMapWrapper.java | 98 +++++++++++++------ 1 file changed, 70 insertions(+), 28 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index 7778dd906fc..daf818a8719 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -6,12 +6,16 @@ import java.util.Arrays; +import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; import de.uka.ilkd.key.logic.op.*; +import de.uka.ilkd.key.logic.sort.SortImpl; import de.uka.ilkd.key.rule.TacletForTests; +import org.key_project.logic.Name; +import org.key_project.logic.sort.Sort; import org.key_project.util.collection.ImmutableArray; import org.junit.jupiter.api.BeforeAll; @@ -25,7 +29,8 @@ import static de.uka.ilkd.key.logic.equality.TermLabelsProperty.TERM_LABELS_PROPERTY; import static org.junit.jupiter.api.Assertions.*; -public class TestLinkedHashMapWrapper { +public class +TestLinkedHashMapWrapper { private TermBuilder tb; private TermFactory tf; @@ -115,40 +120,41 @@ public void testTermLabelProperties() { // add mappings without labels to all maps basicMap.put(noLabelTT, 1); - basicMap.put(noLabelFF, 2); - assertEquals(2, basicMap.size()); + assertEquals(1, basicMap.size()); termLabelsMap.put(noLabelTT, 1); - termLabelsMap.put(noLabelFF, 2); - assertEquals(2, termLabelsMap.size()); + assertEquals(1, termLabelsMap.size()); irrelevantTermLabelsMap.put(noLabelTT, 1); - irrelevantTermLabelsMap.put(noLabelFF, 2); - assertEquals(2, irrelevantTermLabelsMap.size()); + assertEquals(1, irrelevantTermLabelsMap.size()); // add mappings with irrelevant labels to all maps - assertNull(basicMap.put(irrelevantLabelTT, 3), "Nothing should be returned as basicMap should not contain the key"); - assertEquals(3, basicMap.size()); + assertNull(basicMap.put(irrelevantLabelTT, 2), "Nothing should be returned as basicMap should not contain the key"); + assertEquals(2, basicMap.size()); - assertEquals(1, termLabelsMap.put(irrelevantLabelTT, 3), "Old value should be returned as termLabelsMap should already contain the key"); - assertEquals(2, termLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(3, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); + assertEquals(1, termLabelsMap.put(irrelevantLabelTT, 2), "Old value should be returned as termLabelsMap should already contain the key"); + assertEquals(1, termLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(2, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); - assertEquals(1, irrelevantTermLabelsMap.put(irrelevantLabelTT, 3), "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); - assertEquals(2, irrelevantTermLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(3, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key without label should return new value"); + assertEquals(1, irrelevantTermLabelsMap.put(irrelevantLabelTT, 2), "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); + assertEquals(1, irrelevantTermLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key without label should return new value"); // add mappings with relevant labels to all maps - assertNull(basicMap.put(relevantLabelTT, 4), "Nothing should be returned as basicMap should not contain the key"); - assertEquals(4, basicMap.size()); - - assertEquals(3, termLabelsMap.put(relevantLabelTT, 4), "Value 3 should be returned as termLabelsMap was previously updated with irrelevantLabelTT"); - assertEquals(3, termLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(4, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); - assertEquals(4, termLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return new value"); + assertNull(basicMap.put(relevantLabelTT, 3), "Nothing should be returned as basicMap should not contain the key"); + assertEquals(3, basicMap.size()); + assertEquals(2, termLabelsMap.put(relevantLabelTT, 3), "Value 3 should be returned as termLabelsMap was previously updated with irrelevantLabelTT"); + assertEquals(1, termLabelsMap.size(), "Size should not increase as the key is already in the map"); + assertEquals(3, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); + assertEquals(3, termLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return new value"); + assertNull(irrelevantTermLabelsMap.put(relevantLabelTT, 3), "Nothing should be returned as irrelevantTermLabelsMap should not contain the key"); + assertEquals(2, irrelevantTermLabelsMap.size(), "Size should increase as the key is not in the map"); + assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return old value"); + assertEquals(2, irrelevantTermLabelsMap.get(noLabelTT), "Checking key without label should return old value"); + assertEquals(3, irrelevantTermLabelsMap.get(relevantLabelTT), "Checking key with relevant label should return new value"); } @Test @@ -162,15 +168,55 @@ public void testProofIrrelevancyProperty() { public void testRenamingTermProperty() { LinkedHashMapWrapper renamingTermMap = new LinkedHashMapWrapper<>(RENAMING_TERM_PROPERTY); - + final Sort sort = new SortImpl(new Name("sort")); + final LogicVariable x = new LogicVariable(new Name("x"), sort); + final LogicVariable y = new LogicVariable(new Name("y"), sort); + Term t1 = tb.all(x, tb.and(tf.createTerm(x), tf.createTerm(x))); + Term t2 = tb.all(y, tb.and(tf.createTerm(y), tf.createTerm(y))); + Term t3 = tb.all(y, tb.and(tf.createTerm(y), tf.createTerm(x))); + + // adding \forall x. x && x + assertEquals(0, renamingTermMap.size(), "Map should be empty"); + renamingTermMap.put(t1, 1); + assertEquals(1, renamingTermMap.size(), "Map should contain one element"); + + // adding \forall y. y && y + assertEquals(1, renamingTermMap.put(t2, 2), "Old value should be returned"); + assertEquals(1, renamingTermMap.size(), "Map should still contain one element"); + assertTrue(renamingTermMap.containsKey(t1), "As renaming is ignored, t1 should be in the map"); + assertTrue(renamingTermMap.containsKey(t2), "As renaming is ignored, t2 should be in the map"); + + // adding \forall y. y && x + assertNull(renamingTermMap.put(t3, 3), "Nothing should be returned as the key is not in the map"); + assertEquals(2, renamingTermMap.size(), "Map should contain two elements"); + assertEquals(2, renamingTermMap.get(t1), "Value for t1 should be 2"); + assertEquals(2, renamingTermMap.get(t2), "Value for t2 should be 2"); + assertEquals(3, renamingTermMap.get(t3), "Value for t3 should be 3"); } @Test public void testRenamingSourceElementProperty() { LinkedHashMapWrapper renamingSourceElementMap = new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); - LinkedHashMap basicMap = new LinkedHashMap<>(); + ProgramElement match1 = TacletForTests.parsePrg("{ int i; int j; /*Test*/ }"); + ProgramElement match2 = TacletForTests.parsePrg("{ int i; /*Another test*/ int k; }"); + ProgramElement match3 = TacletForTests.parsePrg("{ int i = 3; int k; }"); + + // adding { int i; int j; /*Test*/ } + assertNull(renamingSourceElementMap.put(match1, 1)); + assertEquals(1, renamingSourceElementMap.size(), "Map should contain one element"); + + // adding { int i = 3; int k; } + assertNull(renamingSourceElementMap.put(match3, 2), "Nothing should be returned as the key is not in the map"); + assertEquals(2, renamingSourceElementMap.size(), "Map should contain two elements"); + + // adding { int i; /*Another test*/ int k; } + assertEquals(1, renamingSourceElementMap.put(match2, 3), "Old value should be returned"); + assertEquals(2, renamingSourceElementMap.size(), "Map should still contain two elements"); + assertEquals(3, renamingSourceElementMap.get(match1), "Value for match1 should be new value 3"); + assertEquals(3, renamingSourceElementMap.get(match3), "Value for match3 should be 3"); + assertEquals(2, renamingSourceElementMap.get(match2), "Value for match2 should be 2"); } @@ -183,10 +229,6 @@ public void testConstructors() { assertTrue(wrappedMap.containsKey(tb.tt())); // putAll is also tested with these constructor calls - } - - @Test - public void testSpecialCases() { } } From cecf12fc05224943b4d3bfdfbbadbcfd9c59c597 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 18 Jun 2024 20:07:19 +0200 Subject: [PATCH 57/73] finish tests for LinkedHashMapWrapper --- .../key/util/TestLinkedHashMapWrapper.java | 191 ++++++++++++------ 1 file changed, 127 insertions(+), 64 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index daf818a8719..4a100c900ea 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -8,6 +8,7 @@ import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.java.SourceElement; +import de.uka.ilkd.key.ldt.JavaDLTheory; import de.uka.ilkd.key.logic.*; import de.uka.ilkd.key.logic.label.*; import de.uka.ilkd.key.logic.op.*; @@ -29,14 +30,12 @@ import static de.uka.ilkd.key.logic.equality.TermLabelsProperty.TERM_LABELS_PROPERTY; import static org.junit.jupiter.api.Assertions.*; -public class -TestLinkedHashMapWrapper { +public class TestLinkedHashMapWrapper { private TermBuilder tb; private TermFactory tf; - final private TermLabel relevantLabel1 = ParameterlessTermLabel.UNDEFINED_VALUE_LABEL; - final private TermLabel relevantLabel2 = ParameterlessTermLabel.SHORTCUT_EVALUATION_LABEL; + final private TermLabel relevantLabel = ParameterlessTermLabel.UNDEFINED_VALUE_LABEL; private static TermLabel irrelevantLabel = null; final private static OriginTermLabelFactory factory = new OriginTermLabelFactory(); @@ -111,12 +110,9 @@ public void testTermLabelProperties() { new LinkedHashMapWrapper<>(IRRELEVANT_TERM_LABELS_PROPERTY); Term noLabelTT = tb.tt(); - Term noLabelFF = tb.ff(); Term irrelevantLabelTT = tb.label(noLabelTT, irrelevantLabel); - Term irrelevantLabelFF = tb.label(noLabelFF, irrelevantLabel); - Term relevantLabelTT = tb.label(noLabelTT, relevantLabel1); - Term relevantLabelFF = tb.label(noLabelFF, relevantLabel2); + Term relevantLabelTT = tb.label(noLabelTT, relevantLabel); // add mappings without labels to all maps basicMap.put(noLabelTT, 1); @@ -129,75 +125,91 @@ public void testTermLabelProperties() { assertEquals(1, irrelevantTermLabelsMap.size()); // add mappings with irrelevant labels to all maps - assertNull(basicMap.put(irrelevantLabelTT, 2), "Nothing should be returned as basicMap should not contain the key"); + assertNull(basicMap.put(irrelevantLabelTT, 2), + "Nothing should be returned as basicMap should not contain the key"); assertEquals(2, basicMap.size()); - assertEquals(1, termLabelsMap.put(irrelevantLabelTT, 2), "Old value should be returned as termLabelsMap should already contain the key"); - assertEquals(1, termLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(2, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); + assertEquals(1, termLabelsMap.put(irrelevantLabelTT, 2), + "Old value should be returned as termLabelsMap should already contain the key"); + assertEquals(1, termLabelsMap.size(), + "Size should not increase as the key is already in the map"); + assertEquals(2, termLabelsMap.get(noLabelTT), + "Checking key without label should return new value"); - assertEquals(1, irrelevantTermLabelsMap.put(irrelevantLabelTT, 2), "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); - assertEquals(1, irrelevantTermLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key without label should return new value"); + assertEquals(1, irrelevantTermLabelsMap.put(irrelevantLabelTT, 2), + "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); + assertEquals(1, irrelevantTermLabelsMap.size(), + "Size should not increase as the key is already in the map"); + assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), + "Checking key without label should return new value"); // add mappings with relevant labels to all maps - assertNull(basicMap.put(relevantLabelTT, 3), "Nothing should be returned as basicMap should not contain the key"); + assertNull(basicMap.put(relevantLabelTT, 3), + "Nothing should be returned as basicMap should not contain the key"); assertEquals(3, basicMap.size()); - assertEquals(2, termLabelsMap.put(relevantLabelTT, 3), "Value 3 should be returned as termLabelsMap was previously updated with irrelevantLabelTT"); - assertEquals(1, termLabelsMap.size(), "Size should not increase as the key is already in the map"); - assertEquals(3, termLabelsMap.get(noLabelTT), "Checking key without label should return new value"); - assertEquals(3, termLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return new value"); - - assertNull(irrelevantTermLabelsMap.put(relevantLabelTT, 3), "Nothing should be returned as irrelevantTermLabelsMap should not contain the key"); - assertEquals(2, irrelevantTermLabelsMap.size(), "Size should increase as the key is not in the map"); - assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), "Checking key with irrelevant label should return old value"); - assertEquals(2, irrelevantTermLabelsMap.get(noLabelTT), "Checking key without label should return old value"); - assertEquals(3, irrelevantTermLabelsMap.get(relevantLabelTT), "Checking key with relevant label should return new value"); + assertEquals(2, termLabelsMap.put(relevantLabelTT, 3), + "Value 3 should be returned as termLabelsMap was previously updated with irrelevantLabelTT"); + assertEquals(1, termLabelsMap.size(), + "Size should not increase as the key is already in the map"); + assertEquals(3, termLabelsMap.get(noLabelTT), + "Checking key without label should return new value"); + assertEquals(3, termLabelsMap.get(irrelevantLabelTT), + "Checking key with irrelevant label should return new value"); + + assertNull(irrelevantTermLabelsMap.put(relevantLabelTT, 3), + "Nothing should be returned as irrelevantTermLabelsMap should not contain the key"); + assertEquals(2, irrelevantTermLabelsMap.size(), + "Size should increase as the key is not in the map"); + assertEquals(2, irrelevantTermLabelsMap.get(irrelevantLabelTT), + "Checking key with irrelevant label should return old value"); + assertEquals(2, irrelevantTermLabelsMap.get(noLabelTT), + "Checking key without label should return old value"); + assertEquals(3, irrelevantTermLabelsMap.get(relevantLabelTT), + "Checking key with relevant label should return new value"); } @Test public void testProofIrrelevancyProperty() { - LinkedHashMapWrapper ProofIrrelevancyMap = + LinkedHashMapWrapper proofIrrelevancyMap = new LinkedHashMapWrapper<>(PROOF_IRRELEVANCY_PROPERTY); - } - - @Test - public void testRenamingTermProperty() { - LinkedHashMapWrapper renamingTermMap = - new LinkedHashMapWrapper<>(RENAMING_TERM_PROPERTY); - final Sort sort = new SortImpl(new Name("sort")); - final LogicVariable x = new LogicVariable(new Name("x"), sort); - final LogicVariable y = new LogicVariable(new Name("y"), sort); - Term t1 = tb.all(x, tb.and(tf.createTerm(x), tf.createTerm(x))); - Term t2 = tb.all(y, tb.and(tf.createTerm(y), tf.createTerm(y))); - Term t3 = tb.all(y, tb.and(tf.createTerm(y), tf.createTerm(x))); - - // adding \forall x. x && x - assertEquals(0, renamingTermMap.size(), "Map should be empty"); - renamingTermMap.put(t1, 1); - assertEquals(1, renamingTermMap.size(), "Map should contain one element"); - - // adding \forall y. y && y - assertEquals(1, renamingTermMap.put(t2, 2), "Old value should be returned"); - assertEquals(1, renamingTermMap.size(), "Map should still contain one element"); - assertTrue(renamingTermMap.containsKey(t1), "As renaming is ignored, t1 should be in the map"); - assertTrue(renamingTermMap.containsKey(t2), "As renaming is ignored, t2 should be in the map"); + Term noLabelTT = tb.tt(); - // adding \forall y. y && x - assertNull(renamingTermMap.put(t3, 3), "Nothing should be returned as the key is not in the map"); - assertEquals(2, renamingTermMap.size(), "Map should contain two elements"); - assertEquals(2, renamingTermMap.get(t1), "Value for t1 should be 2"); - assertEquals(2, renamingTermMap.get(t2), "Value for t2 should be 2"); - assertEquals(3, renamingTermMap.get(t3), "Value for t3 should be 3"); + Term irrelevantLabelTT = tb.label(noLabelTT, irrelevantLabel); + Term relevantLabelTT = tb.label(noLabelTT, relevantLabel); + + // add mapping without label + assertNull(proofIrrelevancyMap.put(noLabelTT, 1), + "Nothing should be returned as proofIrrelevancyMap should not contain the key"); + assertEquals(1, proofIrrelevancyMap.size()); + + // add mapping with irrelevant label + assertEquals(1, proofIrrelevancyMap.put(irrelevantLabelTT, 2), + "Old value should be returned as irrelevantTermLabelsMap should already contain the key"); + assertEquals(1, proofIrrelevancyMap.size(), + "Size should not increase as the key is already in the map"); + assertEquals(2, proofIrrelevancyMap.get(irrelevantLabelTT), + "Checking key without label should return new value"); + + // add mapping with relevant label + assertNull(proofIrrelevancyMap.put(relevantLabelTT, 3), + "Nothing should be returned as irrelevantTermLabelsMap should not contain the key"); + assertEquals(2, proofIrrelevancyMap.size(), + "Size should increase as the key is not in the map"); + assertEquals(2, proofIrrelevancyMap.get(irrelevantLabelTT), + "Checking key with irrelevant label should return old value"); + assertEquals(2, proofIrrelevancyMap.get(noLabelTT), + "Checking key without label should return old value"); + assertEquals(3, proofIrrelevancyMap.get(relevantLabelTT), + "Checking key with relevant label should return new value");; } @Test public void testRenamingSourceElementProperty() { LinkedHashMapWrapper renamingSourceElementMap = - new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); + new LinkedHashMapWrapper<>(RENAMING_SOURCE_ELEMENT_PROPERTY); ProgramElement match1 = TacletForTests.parsePrg("{ int i; int j; /*Test*/ }"); ProgramElement match2 = TacletForTests.parsePrg("{ int i; /*Another test*/ int k; }"); @@ -208,27 +220,78 @@ public void testRenamingSourceElementProperty() { assertEquals(1, renamingSourceElementMap.size(), "Map should contain one element"); // adding { int i = 3; int k; } - assertNull(renamingSourceElementMap.put(match3, 2), "Nothing should be returned as the key is not in the map"); + assertNull(renamingSourceElementMap.put(match3, 2), + "Nothing should be returned as the key is not in the map"); assertEquals(2, renamingSourceElementMap.size(), "Map should contain two elements"); // adding { int i; /*Another test*/ int k; } assertEquals(1, renamingSourceElementMap.put(match2, 3), "Old value should be returned"); assertEquals(2, renamingSourceElementMap.size(), "Map should still contain two elements"); - assertEquals(3, renamingSourceElementMap.get(match1), "Value for match1 should be new value 3"); + assertEquals(3, renamingSourceElementMap.get(match1), + "Value for match1 should be new value 3"); assertEquals(3, renamingSourceElementMap.get(match3), "Value for match3 should be 3"); assertEquals(2, renamingSourceElementMap.get(match2), "Value for match2 should be 2"); } + @Test + public void testRenamingTermProperty() { + LinkedHashMapWrapper renamingTermMap = + new LinkedHashMapWrapper<>(RENAMING_TERM_PROPERTY); + final Sort sort = new SortImpl(new Name("sort")); + final LogicVariable x = new LogicVariable(new Name("x"), sort); + final LogicVariable y = new LogicVariable(new Name("y"), sort); + final Term tx = tf.createTerm(x); + final Term ty = tf.createTerm(y); + final JFunction f = new JFunction(new Name("f"), JavaDLTheory.FORMULA, sort, sort); + final Term t1 = tb.all(x, tf.createTerm(f, tx, tx)); + final Term t2 = tb.all(y, tf.createTerm(f, ty, ty)); + final Term t3 = tb.all(y, tf.createTerm(f, ty, tx)); + + // adding \forall x. x && x + assertEquals(0, renamingTermMap.size(), "Map should be empty"); + renamingTermMap.put(t1, 1); + assertEquals(1, renamingTermMap.size(), "Map should contain one element"); + + // adding \forall y. y && y + assertEquals(1, renamingTermMap.put(t2, 2), "Old value should be returned"); + assertEquals(1, renamingTermMap.size(), "Map should still contain one element"); + assertTrue(renamingTermMap.containsKey(t1), + "As renaming is ignored, t1 should be in the map"); + assertTrue(renamingTermMap.containsKey(t2), + "As renaming is ignored, t2 should be in the map"); + + // adding \forall y. y && x + assertNull(renamingTermMap.put(t3, 3), + "Nothing should be returned as the key is not in the map"); + assertEquals(2, renamingTermMap.size(), "Map should contain two elements"); + assertEquals(2, renamingTermMap.get(t1), "Value for t1 should be 2"); + assertEquals(2, renamingTermMap.get(t2), "Value for t2 should be 2"); + assertEquals(3, renamingTermMap.get(t3), "Value for t3 should be 3"); + } + @Test public void testConstructors() { LinkedHashMapWrapper wrappedMap = - new LinkedHashMapWrapper<>(tb.tt(), 1, TERM_LABELS_PROPERTY); - assertFalse(wrappedMap.isEmpty()); - assertEquals(1, wrappedMap.size()); - assertTrue(wrappedMap.containsKey(tb.tt())); + new LinkedHashMapWrapper<>(tb.tt(), 1, TERM_LABELS_PROPERTY); + assertFalse(wrappedMap.isEmpty(), "Map should not be empty (0)"); + assertEquals(1, wrappedMap.size(), "Map should contain one element"); + assertTrue(wrappedMap.containsKey(tb.tt()), "Map should contain key tt"); // putAll is also tested with these constructor calls - + LinkedHashMapWrapper wrappedMap2 = + new LinkedHashMapWrapper<>(new Term[] { tb.tt(), tb.ff() }, new Integer[] { 1, 2 }, + TERM_LABELS_PROPERTY); + assertFalse(wrappedMap2.isEmpty(), "Map should not be empty (1)"); + assertEquals(2, wrappedMap2.size(), "Map should contain two elements"); + + LinkedHashMapWrapper wrappedMap3 = + new LinkedHashMapWrapper<>(new ImmutableArray<>(tb.tt(), tb.ff(), tb.tt()), + new ImmutableArray<>(1, 2, 3), + TERM_LABELS_PROPERTY); + assertFalse(wrappedMap3.isEmpty(), "Map should not be empty (2)"); + assertEquals(2, wrappedMap3.size(), "Map should contain two elements, as tt is repeated"); + assertFalse(wrappedMap3.containsValue(1), + "Map should not contain value 1 as it should be overwritten by 3"); } } From 7da937c00756fc7cb7b0974f73a0ff19924573f2 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Tue, 18 Jun 2024 21:16:13 +0200 Subject: [PATCH 58/73] write long comment about hashCodeModThisProperty for SourceElements --- .../logic/equality/RenamingSourceElementProperty.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index e71c94759cd..9cffceaf51b 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -97,10 +97,17 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V return next1 == null && next2 == null; } + // TODO: hashCodeModThisProperty currently does not take a NameAbstractionTable as an argument. + // This is because the current implementation of hashCodeModThisProperty is not parameterized + // with a vararg. Variables occurring in multiple formulas and JavaBlocks are considered in + // isolation as a newly created NameAbstractionTable that does not contain entries from previous + // JavaBlocks is used. This could possibly lead to more collisions but if this is a concern, the + // method can be changed to also take a generic vararg. That way, the NameAbstractionTable can + // be passed to the method and hash codes can take previous usage of variables into account. @Override public int hashCodeModThisProperty(SourceElement sourceElement) { /* - * Currently, the best approach seems to walk through the sourceElement with a + * Currently, the best approach seems to be to walk through the SourceElement with a * JavaASTTreeWalker and sum up hash codes. */ JavaASTTreeWalker tw = new JavaASTTreeWalker(sourceElement); @@ -111,7 +118,7 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { int hashCode = 1; while (next != null) { - // Handle special cases so that hashCodeModThisProperty fits equalsModThisProperty + // Handle special cases so that hashCodeModThisProperty follows equalsModThisProperty if (next instanceof LabeledStatement ls) { hashCode = 31 * hashCode + ls.getChildCount(); absMap.add(ls); From 6dd07b88ab7de7eaa6e98526ac931874d10c7298 Mon Sep 17 00:00:00 2001 From: Tobias Date: Fri, 21 Jun 2024 10:02:27 +0200 Subject: [PATCH 59/73] add nullable annotations in LinkedHashMapWrapper --- .../de/uka/ilkd/key/util/LinkedHashMapWrapper.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java index 801628acfe0..5608b0847a6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java +++ b/key.core/src/main/java/de/uka/ilkd/key/util/LinkedHashMapWrapper.java @@ -11,6 +11,9 @@ import org.key_project.util.collection.Pair; +import org.jspecify.annotations.Nullable; + + /** * This class is a wrapper for {@link LinkedHashMap} where the keys are elements that implement * {@link EqualsModProperty}. @@ -27,7 +30,7 @@ public class LinkedHashMapWrapper, V> { /** * The wrapped {@link LinkedHashMap}. */ - private final LinkedHashMap, V> map; + private final LinkedHashMap, @Nullable V> map; /** * The {@link Property} that is used for equality checks and hash codes. @@ -127,7 +130,7 @@ public boolean containsKey(K key) { * @param key the key whose associated value is to be returned * @return the value to which the specified key is mapped */ - public V get(K key) { + public @Nullable V get(K key) { return map.get(wrapKey(key)); } @@ -142,7 +145,7 @@ public V get(K key) { * @return the previous value associated with {@code key}, or {@code null} if there was no * mapping for {@code key} */ - public V put(K key, V value) { + public @Nullable V put(K key, @Nullable V value) { return map.put(wrapKey(key), value); } @@ -195,7 +198,7 @@ public void putAll(Iterable keys, Iterable vals) { * @return the previous value associated with {@code key}, or {@code null} if there was no * mapping for {@code key} */ - public V remove(K key) { + public @Nullable V remove(K key) { return map.remove(wrapKey(key)); } @@ -309,7 +312,7 @@ private static class PairIterator, V> /** * The last key-value pair that was returned by {@link #next()}. */ - private ElementWrapper last = null; + private @Nullable ElementWrapper last = null; /** * Creates a new iterator over the key-value pairs in the {@link LinkedHashMapWrapper}. From 93271194cc40e2d97cd5aac462f7a2d4be9c5f18 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 21 Jun 2024 10:44:09 +0200 Subject: [PATCH 60/73] add to test case for LinkedHashMapWrapper --- .../uka/ilkd/key/util/TestLinkedHashMapWrapper.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index 4a100c900ea..6b9a0246d82 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -5,6 +5,7 @@ import java.util.Arrays; +import java.util.Iterator; import de.uka.ilkd.key.java.ProgramElement; import de.uka.ilkd.key.java.SourceElement; @@ -18,6 +19,7 @@ import org.key_project.logic.Name; import org.key_project.logic.sort.Sort; import org.key_project.util.collection.ImmutableArray; +import org.key_project.util.collection.Pair; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.BeforeEach; @@ -293,5 +295,16 @@ public void testConstructors() { assertEquals(2, wrappedMap3.size(), "Map should contain two elements, as tt is repeated"); assertFalse(wrappedMap3.containsValue(1), "Map should not contain value 1 as it should be overwritten by 3"); + + Iterator> it = wrappedMap3.iterator(); + it.forEachRemaining(pair -> { + if (pair.first.equals(tb.tt())) { + assertEquals(3, pair.second, "Value for tt should be 3"); + } else if (pair.first.equals(tb.ff())) { + assertEquals(2, pair.second, "Value for ff should be 2"); + } else { + fail("Unexpected key in map"); + } + }); } } From 74af6420c875c4d03e8a3cfa606644fd9664856b Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 21 Jun 2024 10:57:24 +0200 Subject: [PATCH 61/73] add test for iterator of LinkedHashMapWrapper --- .../uka/ilkd/key/util/TestLinkedHashMapWrapper.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index 6b9a0246d82..5a7c583100f 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -296,8 +296,8 @@ public void testConstructors() { assertFalse(wrappedMap3.containsValue(1), "Map should not contain value 1 as it should be overwritten by 3"); - Iterator> it = wrappedMap3.iterator(); - it.forEachRemaining(pair -> { + Iterator> it1 = wrappedMap3.iterator(); + it1.forEachRemaining(pair -> { if (pair.first.equals(tb.tt())) { assertEquals(3, pair.second, "Value for tt should be 3"); } else if (pair.first.equals(tb.ff())) { @@ -306,5 +306,12 @@ public void testConstructors() { fail("Unexpected key in map"); } }); + + Iterator> it2 = wrappedMap2.iterator(); + assertTrue(it2.hasNext(), "Iterator should have next element"); + it2.next(); + assertTrue(it2.hasNext(), "Iterator should have next element"); + it2.next(); + assertFalse(it2.hasNext(), "Iterator should not have next element"); } } From 3b611d5f00b94cb1b92cc8408bb4ce88e0fe6d56 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 21 Jun 2024 11:08:34 +0200 Subject: [PATCH 62/73] change behavior of equalsModThisProperty for RenamingSourceElementProperty when no NAT is given --- .../equality/RenamingSourceElementProperty.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 82279627ec6..3597b9f51e0 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -40,20 +40,25 @@ private RenamingSourceElementProperty() {} /** * Checks if {@code se2} is a source element syntactically equal to {@code se1} modulo renaming. + *

    + * When this method is supplied with a {@link NameAbstractionTable}, it will use this table to + * compare the abstract names of the source elements. If no {@link NameAbstractionTable} is + * supplied, a new one will be created. * * @param se1 the first element of the equality check * @param se2 the second element of the equality check - * @param v should be a single {@link NameAbstractionTable} for this equality check + * @param v can be a single {@link NameAbstractionTable} for this equality check * @return {@code true} iff {@code se2} is a source element syntactically equal to {@code se1} * modulo renaming * @param is supposed to be {@link NameAbstractionTable} for this equality check */ @Override public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V... v) { - // For this equality check, v must be a single NameAbstractionTable - if (v.length != 1 || !(v[0] instanceof NameAbstractionTable nat)) { - throw new IllegalArgumentException( - "Expected a single NameAbstractionTable as argument."); + NameAbstractionTable nat; + if (v.length > 0 && (v[0] instanceof NameAbstractionTable n)) { + nat = n; + } else { + nat = new NameAbstractionTable(); } JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); From 98f8008d061a274c02da2b159e6ae17b1e96f820 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Fri, 21 Jun 2024 11:43:30 +0200 Subject: [PATCH 63/73] fix test for LinkedHashMapWrapper --- .../java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java index 5a7c583100f..3624a8e2fdc 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java +++ b/key.core/src/test/java/de/uka/ilkd/key/util/TestLinkedHashMapWrapper.java @@ -231,8 +231,8 @@ public void testRenamingSourceElementProperty() { assertEquals(2, renamingSourceElementMap.size(), "Map should still contain two elements"); assertEquals(3, renamingSourceElementMap.get(match1), "Value for match1 should be new value 3"); - assertEquals(3, renamingSourceElementMap.get(match3), "Value for match3 should be 3"); - assertEquals(2, renamingSourceElementMap.get(match2), "Value for match2 should be 2"); + assertEquals(2, renamingSourceElementMap.get(match3), "Value for match3 should be 2"); + assertEquals(3, renamingSourceElementMap.get(match2), "Value for match2 should be 3"); } From 11fa89918e09908aa154cb04fef2ac0ecbf82d84 Mon Sep 17 00:00:00 2001 From: Wolfram Pfeifer Date: Tue, 25 Jun 2024 17:26:34 +0200 Subject: [PATCH 64/73] ensure that the update is copied to \add part of rules (\sameUpdateLevel) --- .../rules/integerAssignment2UpdateRules.key | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/integerAssignment2UpdateRules.key b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/integerAssignment2UpdateRules.key index 7982511fa67..097408d7e72 100644 --- a/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/integerAssignment2UpdateRules.key +++ b/key.core/src/main/resources/de/uka/ilkd/key/proof/rules/integerAssignment2UpdateRules.key @@ -42,6 +42,7 @@ \find(\modality{#normalassign}{.. #loc = #seCharByteShortInt0 * #seCharByteShortInt1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(mul(#seCharByteShortInt0, #seCharByteShortInt1))) @@ -56,6 +57,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt * #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(mul(#seCharByteShortInt, #seLong))) @@ -70,6 +72,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong * #seCharByteShortInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(mul(#seLong, #seCharByteShortInt))) @@ -84,6 +87,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 * #seLong1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(mul(#seLong0, #seLong1))) @@ -280,6 +284,7 @@ \find(\modality{#normalassign}{.. #loc = #seCharByteShortInt0 - #seCharByteShortInt1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(sub(#seCharByteShortInt0, #seCharByteShortInt1))) @@ -294,6 +299,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt - #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(sub(#seCharByteShortInt, #seLong))) @@ -308,6 +314,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong - #seCharByteShortInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(sub(#seLong, #seCharByteShortInt))) @@ -323,6 +330,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 - #seLong1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(sub(#seLong0, #seLong1))) @@ -339,6 +347,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt0 + #seCharByteShortInt1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(add(#seCharByteShortInt0, #seCharByteShortInt1))) @@ -354,6 +363,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt + #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(add(#seCharByteShortInt, #seLong))) @@ -369,6 +379,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong + #seCharByteShortInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(add(#seLong, #seCharByteShortInt))) @@ -384,6 +395,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 + #seLong1; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(add(#seLong0, #seLong1))) @@ -541,6 +553,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt0 >> #se; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(shiftright(#seLong0, #se))) @@ -556,6 +569,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 >> #se; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(shiftright(#seLong0, #se))) @@ -573,6 +587,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt0 << #se; ...} \endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(shiftleft(#seCharByteShortInt0, #se))) @@ -588,6 +603,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 << #se; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(shiftleft(#seLong0, #se))) @@ -605,6 +621,7 @@ \find(\modality{#normalassign}{.. #loc=#seCharByteShortInt0 >>> #se; ...} \endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(unsignedshiftrightJint(#seCharByteShortInt0, #se))) @@ -620,6 +637,7 @@ \find(\modality{#normalassign}{.. #loc=#seLong0 >>> #se; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(unsignedshiftrightJlong(#seLong0, #se))) @@ -638,6 +656,7 @@ \find(\modality{#normalassign}{.. #loc = - #seCharByteShortInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(neg(#seCharByteShortInt))) @@ -652,6 +671,7 @@ \find(\modality{#normalassign}{.. #loc = - #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inLong(neg(#seLong))) @@ -686,6 +706,7 @@ \find(\modality{#normalassign}{.. #loc = (byte) #seShort; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inByte(#seShort)) @@ -700,6 +721,7 @@ \find(\modality{#normalassign}{.. #loc = (byte) #seInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inByte(#seInt)) @@ -714,6 +736,7 @@ \find(\modality{#normalassign}{.. #loc = (byte) #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inByte(#seLong)) @@ -728,6 +751,7 @@ \find(\modality{#normalassign}{.. #loc = (short) #seInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inShort(#seInt)) @@ -742,6 +766,7 @@ \find(\modality{#normalassign}{.. #loc = (short) #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inShort(#seLong)) @@ -754,6 +779,7 @@ narrowingIntCastLong { \find(\modality{#normalassign}{.. #loc = (int) #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inInt(#seLong)) @@ -768,6 +794,7 @@ \find(\modality{#normalassign}{.. #loc = (char) #seByte; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inChar(#seByte)) @@ -783,6 +810,7 @@ \find(\modality{#normalassign}{.. #loc = (char) #seShort; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inChar(#seShort)) @@ -798,6 +826,7 @@ \find(\modality{#normalassign}{.. #loc = (char) #seInt; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inChar(#seInt)) @@ -812,6 +841,7 @@ \find(\modality{#normalassign}{.. #loc = (char) #seLong; ...}\endmodality (post)) + \sameUpdateLevel (intRules:arithmeticSemanticsCheckingOF) { "Overflow check": \add(==> inChar(#seLong)) From 8ba8a2c38536b77e8c6c39ba0b6fa18fedd6b484 Mon Sep 17 00:00:00 2001 From: Wolfram Pfeifer Date: Tue, 25 Jun 2024 18:31:04 +0200 Subject: [PATCH 65/73] test cases for integer semantics --- .../uka/ilkd/key/rule/IntSemanticsTest.java | 70 +++++ .../checkedOF/IntSemanticsCheckedOF.java | 21 ++ .../intSemantics/checkedOF/mOFCheck.proof | 241 ++++++++++++++++++ .../intSemantics/checkedOF/mOFCheckWrong.key | 28 ++ .../intSemantics/java/IntSemanticsJava.java | 20 ++ .../intSemantics/java/intSemanticsJava.key | 28 ++ .../key/rule/intSemantics/java/mJava.proof | 132 ++++++++++ .../key/rule/intSemantics/java/mJavaWrong.key | 28 ++ .../uncheckedOF/IntSemanticsUncheckedOF.java | 20 ++ .../uncheckedOF/intSemanticsUncheckedOF.key | 28 ++ .../intSemantics/uncheckedOF/mBigint.proof | 121 +++++++++ .../intSemantics/uncheckedOF/mBigintWrong.key | 28 ++ 12 files changed, 765 insertions(+) create mode 100644 key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/IntSemanticsCheckedOF.java create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheck.proof create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheckWrong.key create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/IntSemanticsJava.java create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/intSemanticsJava.key create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJava.proof create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJavaWrong.key create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/IntSemanticsUncheckedOF.java create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/intSemanticsUncheckedOF.key create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigint.proof create mode 100644 key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigintWrong.key diff --git a/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java b/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java new file mode 100644 index 00000000000..70f8b8fffa8 --- /dev/null +++ b/key.core/src/test/java/de/uka/ilkd/key/rule/IntSemanticsTest.java @@ -0,0 +1,70 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ +package de.uka.ilkd.key.rule; + +import java.io.File; + +import de.uka.ilkd.key.api.KeYApi; +import de.uka.ilkd.key.api.ProofApi; +import de.uka.ilkd.key.api.ProofManagementApi; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.io.ProblemLoaderException; + +import org.key_project.util.helper.FindResources; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +/** + * These tests check that the integer taclet options still work as intended, for example that the + * additional branches for overflow checks are still generated correctly. At the moment, for each of + * the three taclet options there is one positive (provable) and one negative (unprovable) test. + * + * @author Wolfram Pfeifer + */ +class IntSemanticsTest { + private static final File TEST_DIR = new File(FindResources.getTestResourcesDirectory(), + "/de/uka/ilkd/key/rule/intSemantics/"); + + /** + * This test checks that certain proofs containing integer corner cases are reloadable. + * + * @param filename name of the .proof file containing a closed proof and also setting the + * desired taclet option for the integer semantics. + * @throws ProblemLoaderException should not happen + */ + @ParameterizedTest + @ValueSource(strings = { "java/mJava.proof", + "uncheckedOF/mBigint.proof", + "checkedOF/mOFCheck.proof" }) + void testSemanticsProvable(String filename) throws ProblemLoaderException { + File proofFile = new File(TEST_DIR, filename); + ProofManagementApi pmapi = KeYApi.loadProof(proofFile); + Proof proof = pmapi.getLoadedProof().getProof(); + // Proof should be reloaded completely now. If not, the int semantics are probably broken. + Assertions.assertTrue(proof.closed()); + } + + /** + * This test checks that certain contracts are not provable with the selected integer semantics. + * + * @param filename name of the .key file that points to the contract. The desired integer + * semantics need to be set correctly here! + * @throws ProblemLoaderException should not happen + */ + @ParameterizedTest + @ValueSource(strings = { "java/mJavaWrong.key", + "uncheckedOF/mBigintWrong.key", + "checkedOF/mOFCheckWrong.key", }) + void testSemanticsUnprovable(String filename) throws ProblemLoaderException { + File keyFile = new File(TEST_DIR, filename); + ProofManagementApi pmapi = KeYApi.loadFromKeyFile(keyFile); + ProofApi proofApi = pmapi.getLoadedProof(); + Proof proof = proofApi.getProof(); + proofApi.getEnv().getProofControl().startAndWaitForAutoMode(proof); + // we expect that exactly one branch (the overflow check) is open now: + Assertions.assertEquals(1, proof.openGoals().size()); + } +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/IntSemanticsCheckedOF.java b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/IntSemanticsCheckedOF.java new file mode 100644 index 00000000000..15b37ab05f9 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/IntSemanticsCheckedOF.java @@ -0,0 +1,21 @@ +/*@ code_safe_math @*/ // this is ignored by KeY currently, just for documentation +/*@ spec_bigint_math @*/ // this is the default +class IntSemanticsCheckedOF { + + // provable with overflow check taclet option, since no overflow can occur with this precondition + /*@ normal_behavior + @ requires Integer.MIN_VALUE <= a + b <= Integer.MAX_VALUE; + @ ensures \result == a + b; + @*/ + int mOFCheck(int a, int b) { + return a + b; + } + + // not provable with overflow check taclet option (separate branch for overflow check stays open) + /*@ normal_behavior + @ ensures \result == a + b; + @*/ + int mOFCheckWrong(int a, int b) { + return a + b; + } +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheck.proof b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheck.proof new file mode 100644 index 00000000000..e656a374036 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheck.proof @@ -0,0 +1,241 @@ +\profile "Java Profile"; + +\settings // Proof-Settings-Config-File +{ + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsCheckingOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "soundDefaultContracts" : "soundDefaultContracts:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "JavaCardDLStrategy", + "MaximumNumberOfAutomaticApplications" : 7000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_DELAYED", + "DEP_OPTIONS_KEY" : "DEP_ON", + "INF_FLOW_CHECK_PROPERTY" : "INF_FLOW_CHECK_FALSE", + "LOOP_OPTIONS_KEY" : "LOOP_SCOPE_INV_TACLET", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_DEF_OPS", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_ON", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } + } + +\javaSource "."; + +\proofObligation +// Proof-Obligation settings +{ + "class" : "de.uka.ilkd.key.proof.init.FunctionalOperationContractPO", + "contract" : "IntSemanticsCheckedOF[IntSemanticsCheckedOF::mOFCheck(int,int)].JML normal_behavior operation contract.0", + "name" : "IntSemanticsCheckedOF[IntSemanticsCheckedOF::mOFCheck(int,int)].JML normal_behavior operation contract.0" + } + +\proof { +(keyLog "0" (keyUser "wolfram" ) (keyVersion "a442cdfee288a794b45d4bdc941b89bf985f3722")) + +(autoModeTime "940") + +(branch "dummy ID" + (builtin "One Step Simplification" (formula "1") (newnames "heapAtPre,o,f")) +(rule "expandInRangeInt" (formula "1") (term "1,1,0,0,0")) +(rule "expandInRangeInt" (formula "1") (term "0,1,0,0,0")) +(rule "replace_int_MIN" (formula "1") (term "0,1,1,1,0,0,0")) +(rule "replace_int_MAX" (formula "1") (term "1,0,1,1,0,0,0")) +(rule "replace_int_MIN" (formula "1") (term "0,1,0,1,0,0,0")) +(rule "replace_int_MAX" (formula "1") (term "1,0,0,1,0,0,0")) +(rule "impRight" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "3")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "4")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "3")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "4")) +(rule "andLeft" (formula "6")) +(rule "andLeft" (formula "1")) +(rule "notLeft" (formula "2")) +(rule "inEqSimp_commuteLeq" (formula "5")) +(rule "inEqSimp_commuteLeq" (formula "7")) +(rule "inEqSimp_homoInEq0" (formula "10")) +(rule "polySimp_mulComm0" (formula "10") (term "1,0")) +(rule "polySimp_rightDist" (formula "10") (term "1,0")) +(rule "polySimp_mulComm0" (formula "10") (term "0,1,0")) +(rule "polySimp_addAssoc" (formula "10") (term "0")) +(rule "inEqSimp_homoInEq0" (formula "9")) +(rule "mul_literals" (formula "9") (term "1,0")) +(rule "polySimp_addComm1" (formula "9") (term "0")) +(rule "polySimp_addComm0" (formula "9") (term "0,0")) +(rule "assignment" (formula "13") (term "1")) + (builtin "One Step Simplification" (formula "13")) +(rule "inEqSimp_sepNegMonomial1" (formula "10")) +(rule "polySimp_mulLiterals" (formula "10") (term "0")) +(rule "polySimp_elimOne" (formula "10") (term "0")) +(rule "inEqSimp_sepPosMonomial1" (formula "9")) +(rule "polySimp_mulComm0" (formula "9") (term "1")) +(rule "polySimp_rightDist" (formula "9") (term "1")) +(rule "mul_literals" (formula "9") (term "0,1")) +(rule "inEqSimp_exactShadow3" (formula "9") (ifseqformula "6")) +(rule "polySimp_rightDist" (formula "9") (term "0,0")) +(rule "polySimp_mulLiterals" (formula "9") (term "1,0,0")) +(rule "mul_literals" (formula "9") (term "0,0,0")) +(rule "polySimp_elimOne" (formula "9") (term "1,0,0")) +(rule "polySimp_addComm1" (formula "9") (term "0")) +(rule "add_literals" (formula "9") (term "0,0")) +(rule "inEqSimp_sepPosMonomial1" (formula "9")) +(rule "mul_literals" (formula "9") (term "1")) +(rule "inEqSimp_subsumption1" (formula "9") (ifseqformula "5")) +(rule "leq_literals" (formula "9") (term "0")) + (builtin "One Step Simplification" (formula "9")) +(rule "true_left" (formula "9")) +(rule "inEqSimp_exactShadow3" (formula "7") (ifseqformula "10")) +(rule "mul_literals" (formula "7") (term "0,0")) +(rule "polySimp_addAssoc" (formula "7") (term "0")) +(rule "add_literals" (formula "7") (term "0,0")) +(rule "inEqSimp_sepNegMonomial1" (formula "7")) +(rule "polySimp_mulLiterals" (formula "7") (term "0")) +(rule "polySimp_elimOne" (formula "7") (term "0")) +(rule "inEqSimp_subsumption0" (formula "7") (ifseqformula "4")) +(rule "leq_literals" (formula "7") (term "0")) + (builtin "One Step Simplification" (formula "7")) +(rule "true_left" (formula "7")) +(rule "methodBodyExpand" (formula "13") (term "1") (newnames "heapBefore_mOFCheck,savedHeapBefore_mOFCheck")) + (builtin "One Step Simplification" (formula "13")) +(rule "returnUnfold" (formula "13") (term "1") (inst "#v0=i")) +(rule "variableDeclarationAssign" (formula "13") (term "1")) +(rule "variableDeclaration" (formula "13") (term "1") (newnames "i")) +(rule "assignmentAdditionInt" (formula "13") (term "1")) +(branch "Overflow check" + (builtin "One Step Simplification" (formula "13")) + (rule "expandInRangeInt" (formula "13")) + (rule "replace_int_MIN" (formula "13") (term "0,1")) + (rule "replace_int_MAX" (formula "13") (term "1,0")) + (rule "inEqSimp_homoInEq0" (formula "13") (term "1")) + (rule "mul_literals" (formula "13") (term "1,0,1")) + (rule "polySimp_addComm1" (formula "13") (term "0,1")) + (rule "polySimp_addComm0" (formula "13") (term "0,0,1")) + (rule "inEqSimp_homoInEq0" (formula "13") (term "0")) + (rule "polySimp_mulComm0" (formula "13") (term "1,0,0")) + (rule "polySimp_rightDist" (formula "13") (term "1,0,0")) + (rule "polySimp_mulComm0" (formula "13") (term "0,1,0,0")) + (rule "polySimp_addAssoc" (formula "13") (term "0,0")) + (rule "inEqSimp_sepPosMonomial1" (formula "13") (term "1")) + (rule "polySimp_mulComm0" (formula "13") (term "1,1")) + (rule "polySimp_rightDist" (formula "13") (term "1,1")) + (rule "mul_literals" (formula "13") (term "0,1,1")) + (rule "replace_known_left" (formula "13") (term "1") (ifseqformula "9")) + (builtin "One Step Simplification" (formula "13")) + (rule "inEqSimp_geqRight" (formula "13")) + (rule "times_zero_1" (formula "1") (term "1,0,0")) + (rule "add_zero_right" (formula "1") (term "0,0")) + (rule "polySimp_addAssoc" (formula "1") (term "0")) + (rule "polySimp_addAssoc" (formula "1") (term "0,0")) + (rule "add_literals" (formula "1") (term "0,0,0")) + (rule "inEqSimp_sepNegMonomial0" (formula "1")) + (rule "polySimp_mulLiterals" (formula "1") (term "0")) + (rule "polySimp_elimOne" (formula "1") (term "0")) + (rule "inEqSimp_subsumption1" (formula "10") (ifseqformula "1")) + (rule "inEqSimp_homoInEq0" (formula "10") (term "0")) + (rule "polySimp_mulComm0" (formula "10") (term "1,0,0")) + (rule "polySimp_rightDist" (formula "10") (term "1,0,0")) + (rule "mul_literals" (formula "10") (term "0,1,0,0")) + (rule "polySimp_mulLiterals" (formula "10") (term "1,1,0,0")) + (rule "polySimp_elimOne" (formula "10") (term "1,1,0,0")) + (rule "polySimp_addAssoc" (formula "10") (term "0,0")) + (rule "polySimp_addComm1" (formula "10") (term "0,0,0")) + (rule "add_literals" (formula "10") (term "0,0,0,0")) + (rule "polySimp_pullOutFactor2b" (formula "10") (term "0,0")) + (rule "add_literals" (formula "10") (term "1,1,0,0")) + (rule "times_zero_1" (formula "10") (term "1,0,0")) + (rule "add_zero_right" (formula "10") (term "0,0")) + (rule "qeq_literals" (formula "10") (term "0")) + (builtin "One Step Simplification" (formula "10")) + (rule "true_left" (formula "10")) + (rule "inEqSimp_contradInEq0" (formula "1") (ifseqformula "10")) + (rule "andLeft" (formula "1")) + (rule "inEqSimp_homoInEq1" (formula "1")) + (rule "polySimp_mulComm0" (formula "1") (term "1,0")) + (rule "polySimp_rightDist" (formula "1") (term "1,0")) + (rule "polySimp_mulLiterals" (formula "1") (term "1,1,0")) + (rule "mul_literals" (formula "1") (term "0,1,0")) + (rule "polySimp_elimOne" (formula "1") (term "1,1,0")) + (rule "polySimp_addAssoc" (formula "1") (term "0")) + (rule "polySimp_addComm1" (formula "1") (term "0,0")) + (rule "add_literals" (formula "1") (term "0,0,0")) + (rule "polySimp_pullOutFactor2b" (formula "1") (term "0")) + (rule "add_literals" (formula "1") (term "1,1,0")) + (rule "times_zero_1" (formula "1") (term "1,0")) + (rule "add_zero_right" (formula "1") (term "0")) + (rule "leq_literals" (formula "1")) + (rule "closeFalse" (formula "1")) +) +(branch "Case 2" + (builtin "One Step Simplification" (formula "13")) + (rule "translateJavaAddInt" (formula "13") (term "0,1,0")) + (rule "methodCallReturn" (formula "13") (term "1")) + (rule "assignment" (formula "13") (term "1")) + (builtin "One Step Simplification" (formula "13")) + (rule "methodCallEmpty" (formula "13") (term "1")) + (rule "tryEmpty" (formula "13") (term "1")) + (rule "emptyModality" (formula "13") (term "1")) + (builtin "One Step Simplification" (formula "13") (ifInst "" (formula "11"))) + (rule "closeTrue" (formula "13")) +) +) +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheckWrong.key b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheckWrong.key new file mode 100644 index 00000000000..487f88372d2 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/checkedOF/mOFCheckWrong.key @@ -0,0 +1,28 @@ +\settings { + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsCheckingOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + } +} + +\javaSource "."; + +\chooseContract "IntSemanticsCheckedOF[IntSemanticsCheckedOF::mOFCheckWrong(int,int)].JML normal_behavior operation contract.0"; diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/IntSemanticsJava.java b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/IntSemanticsJava.java new file mode 100644 index 00000000000..d15fba954b9 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/IntSemanticsJava.java @@ -0,0 +1,20 @@ +/*@ code_java_math @*/ // this is ignored by KeY currently, just for documentation +/*@ spec_bigint_math @*/ // this is the default +class IntSemanticsJava { + + // provable with java integer semantics in code (wraparound of int) + /*@ normal_behavior + @ ensures \result == Integer.MIN_VALUE; + @*/ + int mJava() { + return Integer.MAX_VALUE + 1; + } + + // not provable with java integer semantics in code + /*@ normal_behavior + @ ensures \result == Integer.MAX_VALUE + 1; + @*/ + int mJavaWrong() { + return Integer.MAX_VALUE + 1; + } +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/intSemanticsJava.key b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/intSemanticsJava.key new file mode 100644 index 00000000000..2f57bd54d2e --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/intSemanticsJava.key @@ -0,0 +1,28 @@ +\settings { + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:javaSemantics", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + } +} + +\javaSource "."; + +\chooseContract diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJava.proof b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJava.proof new file mode 100644 index 00000000000..6b1d128cfdf --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJava.proof @@ -0,0 +1,132 @@ +\profile "Java Profile"; + +\settings // Proof-Settings-Config-File +{ + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:javaSemantics", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "JavaCardDLStrategy", + "MaximumNumberOfAutomaticApplications" : 10000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_DELAYED", + "DEP_OPTIONS_KEY" : "DEP_ON", + "INF_FLOW_CHECK_PROPERTY" : "INF_FLOW_CHECK_FALSE", + "LOOP_OPTIONS_KEY" : "LOOP_SCOPE_INV_TACLET", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_DEF_OPS", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_ON", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } + } + +\javaSource "."; + +\proofObligation +// Proof-Obligation settings +{ + "class" : "de.uka.ilkd.key.proof.init.FunctionalOperationContractPO", + "contract" : "IntSemanticsJava[IntSemanticsJava::mJava()].JML normal_behavior operation contract.0", + "name" : "IntSemanticsJava[IntSemanticsJava::mJava()].JML normal_behavior operation contract.0" + } + +\proof { +(keyLog "0" (keyUser "wolfram" ) (keyVersion "7f892ecb2af976fa9780876087af8978f3eed91b")) + +(autoModeTime "147") + +(branch "dummy ID" + (builtin "One Step Simplification" (formula "1") (newnames "heapAtPre,o,f")) +(rule "impRight" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "notLeft" (formula "2")) +(rule "assignment" (formula "7")) +(rule "methodBodyExpand" (formula "7") (term "1") (newnames "heapBefore_mJava,savedHeapBefore_mJava")) + (builtin "One Step Simplification" (formula "7")) +(rule "returnUnfold" (formula "7") (term "1") (inst "#v0=i")) +(rule "variableDeclarationAssign" (formula "7") (term "1")) +(rule "variableDeclaration" (formula "7") (term "1") (newnames "i")) +(rule "assignmentAdditionInt" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7")) +(rule "translateJavaAddInt" (formula "7") (term "0,1,0")) +(rule "expand_addJint" (formula "7") (term "0,1,0")) +(rule "add_literals" (formula "7") (term "0,0,1,0")) +(rule "expand_moduloInteger" (formula "7") (term "0,1,0")) +(rule "replace_int_RANGE" (formula "7") (term "1,1,0,1,0")) +(rule "replace_int_HALFRANGE" (formula "7") (term "0,0,1,0,1,0")) +(rule "replace_int_MIN" (formula "7") (term "0,0,1,0")) +(rule "add_literals" (formula "7") (term "0,1,0,1,0")) +(rule "mod_axiom" (formula "7") (term "1,0,1,0")) +(rule "polySimp_mulLiterals" (formula "7") (term "1,1,0,1,0")) +(rule "div_literals" (formula "7") (term "0,1,1,0,1,0")) +(rule "mul_literals" (formula "7") (term "1,1,0,1,0")) +(rule "add_literals" (formula "7") (term "1,0,1,0")) +(rule "add_zero_right" (formula "7") (term "0,1,0")) +(rule "methodCallReturn" (formula "7") (term "1")) +(rule "assignment" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7")) +(rule "methodCallEmpty" (formula "7") (term "1")) +(rule "tryEmpty" (formula "7") (term "1")) +(rule "emptyModality" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7") (ifInst "" (formula "5"))) +(rule "closeTrue" (formula "7")) +) +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJavaWrong.key b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJavaWrong.key new file mode 100644 index 00000000000..7dfbcaa6042 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/java/mJavaWrong.key @@ -0,0 +1,28 @@ +\settings { + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:javaSemantics", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + } +} + +\javaSource "."; + +\chooseContract "IntSemanticsJava[IntSemanticsJava::mJavaWrong()].JML normal_behavior operation contract.0"; diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/IntSemanticsUncheckedOF.java b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/IntSemanticsUncheckedOF.java new file mode 100644 index 00000000000..8eb56eeaf71 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/IntSemanticsUncheckedOF.java @@ -0,0 +1,20 @@ +/*@ code_bigint_math @*/ // this is ignored by KeY currently, just for documentation +/*@ spec_bigint_math @*/ // this is the default +class IntSemanticsUncheckedOF { + + // provable with bigint semantics in code and in spec + /*@ normal_behavior + @ ensures \result == Integer.MAX_VALUE + 1; + @*/ + int mBigint() { + return Integer.MAX_VALUE + 1; + } + + // not provable with bigint semantics in code and in spec + /*@ normal_behavior + @ ensures \result == Integer.MIN_VALUE; + @*/ + int mBigintWrong() { + return Integer.MAX_VALUE + 1; + } +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/intSemanticsUncheckedOF.key b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/intSemanticsUncheckedOF.key new file mode 100644 index 00000000000..2b1787d0531 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/intSemanticsUncheckedOF.key @@ -0,0 +1,28 @@ +\settings { + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + } +} + +\javaSource "."; + +\chooseContract diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigint.proof b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigint.proof new file mode 100644 index 00000000000..9a1f69c94e0 --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigint.proof @@ -0,0 +1,121 @@ +\profile "Java Profile"; + +\settings // Proof-Settings-Config-File +{ + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + }, + "Labels" : { + "UseOriginLabels" : true + }, + "NewSMT" : { + + }, + "SMTSettings" : { + "SelectedTaclets" : [ + + ], + "UseBuiltUniqueness" : false, + "explicitTypeHierarchy" : false, + "instantiateHierarchyAssumptions" : true, + "integersMaximum" : 2147483645, + "integersMinimum" : -2147483645, + "invariantForall" : false, + "maxGenericSorts" : 2, + "useConstantsForBigOrSmallIntegers" : true, + "useUninterpretedMultiplication" : true + }, + "Strategy" : { + "ActiveStrategy" : "JavaCardDLStrategy", + "MaximumNumberOfAutomaticApplications" : 10000, + "Timeout" : -1, + "options" : { + "AUTO_INDUCTION_OPTIONS_KEY" : "AUTO_INDUCTION_OFF", + "BLOCK_OPTIONS_KEY" : "BLOCK_CONTRACT_INTERNAL", + "CLASS_AXIOM_OPTIONS_KEY" : "CLASS_AXIOM_DELAYED", + "DEP_OPTIONS_KEY" : "DEP_ON", + "INF_FLOW_CHECK_PROPERTY" : "INF_FLOW_CHECK_FALSE", + "LOOP_OPTIONS_KEY" : "LOOP_SCOPE_INV_TACLET", + "METHOD_OPTIONS_KEY" : "METHOD_CONTRACT", + "MPS_OPTIONS_KEY" : "MPS_MERGE", + "NON_LIN_ARITH_OPTIONS_KEY" : "NON_LIN_ARITH_DEF_OPS", + "OSS_OPTIONS_KEY" : "OSS_ON", + "QUANTIFIERS_OPTIONS_KEY" : "QUANTIFIERS_NON_SPLITTING_WITH_PROGS", + "QUERYAXIOM_OPTIONS_KEY" : "QUERYAXIOM_ON", + "QUERY_NEW_OPTIONS_KEY" : "QUERY_ON", + "SPLITTING_OPTIONS_KEY" : "SPLITTING_DELAYED", + "STOPMODE_OPTIONS_KEY" : "STOPMODE_DEFAULT", + "SYMBOLIC_EXECUTION_ALIAS_CHECK_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_ALIAS_CHECK_NEVER", + "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OPTIONS_KEY" : "SYMBOLIC_EXECUTION_NON_EXECUTION_BRANCH_HIDING_OFF", + "USER_TACLETS_OPTIONS_KEY1" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY2" : "USER_TACLETS_OFF", + "USER_TACLETS_OPTIONS_KEY3" : "USER_TACLETS_OFF", + "VBT_PHASE" : "VBT_SYM_EX" + } + } + } + +\javaSource "."; + +\proofObligation +// Proof-Obligation settings +{ + "class" : "de.uka.ilkd.key.proof.init.FunctionalOperationContractPO", + "contract" : "IntSemanticsUncheckedOF[IntSemanticsUncheckedOF::mBigint()].JML normal_behavior operation contract.0", + "name" : "IntSemanticsUncheckedOF[IntSemanticsUncheckedOF::mBigint()].JML normal_behavior operation contract.0" + } + +\proof { +(keyLog "0" (keyUser "wolfram" ) (keyVersion "7f892ecb2af976fa9780876087af8978f3eed91b")) + +(autoModeTime "126") + +(branch "dummy ID" + (builtin "One Step Simplification" (formula "1") (newnames "heapAtPre,o,f")) +(rule "add_literals" (formula "1") (term "1,0,0,0,1")) +(rule "impRight" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "andLeft" (formula "1")) +(rule "notLeft" (formula "2")) +(rule "assignment" (formula "7")) +(rule "methodBodyExpand" (formula "7") (term "1") (newnames "heapBefore_mBigint,savedHeapBefore_mBigint")) + (builtin "One Step Simplification" (formula "7")) +(rule "returnUnfold" (formula "7") (term "1") (inst "#v0=i")) +(rule "variableDeclarationAssign" (formula "7") (term "1")) +(rule "variableDeclaration" (formula "7") (term "1") (newnames "i")) +(rule "assignmentAdditionInt" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7")) +(rule "translateJavaAddInt" (formula "7") (term "0,1,0")) +(rule "add_literals" (formula "7") (term "0,1,0")) +(rule "methodCallReturn" (formula "7") (term "1")) +(rule "assignment" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7")) +(rule "methodCallEmpty" (formula "7") (term "1")) +(rule "tryEmpty" (formula "7") (term "1")) +(rule "emptyModality" (formula "7") (term "1")) + (builtin "One Step Simplification" (formula "7") (ifInst "" (formula "5"))) +(rule "closeTrue" (formula "7")) +) +} diff --git a/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigintWrong.key b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigintWrong.key new file mode 100644 index 00000000000..299ed6b8d2d --- /dev/null +++ b/key.core/src/test/resources/de/uka/ilkd/key/rule/intSemantics/uncheckedOF/mBigintWrong.key @@ -0,0 +1,28 @@ +\settings { + "Choice" : { + "JavaCard" : "JavaCard:off", + "Strings" : "Strings:on", + "assertions" : "assertions:safe", + "bigint" : "bigint:on", + "floatRules" : "floatRules:strictfpOnly", + "initialisation" : "initialisation:disableStaticInitialisation", + "intRules" : "intRules:arithmeticSemanticsIgnoringOF", + "integerSimplificationRules" : "integerSimplificationRules:full", + "javaLoopTreatment" : "javaLoopTreatment:efficient", + "mergeGenerateIsWeakeningGoal" : "mergeGenerateIsWeakeningGoal:off", + "methodExpansion" : "methodExpansion:modularOnly", + "modelFields" : "modelFields:treatAsAxiom", + "moreSeqRules" : "moreSeqRules:off", + "permissions" : "permissions:off", + "programRules" : "programRules:Java", + "reach" : "reach:on", + "runtimeExceptions" : "runtimeExceptions:ban", + "sequences" : "sequences:on", + "wdChecks" : "wdChecks:off", + "wdOperator" : "wdOperator:L" + } +} + +\javaSource "."; + +\chooseContract "IntSemanticsUncheckedOF[IntSemanticsUncheckedOF::mBigintWrong()].JML normal_behavior operation contract.0"; From d3a1d283ad08b01a94030bde7352c941bb0bc90e Mon Sep 17 00:00:00 2001 From: Wolfram Pfeifer Date: Wed, 26 Jun 2024 12:46:28 +0200 Subject: [PATCH 66/73] adapt test oracle to changed taclets --- .../de/uka/ilkd/key/nparser/taclets.old.txt | 78 +++++++++---------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/key.core/src/test/resources/de/uka/ilkd/key/nparser/taclets.old.txt b/key.core/src/test/resources/de/uka/ilkd/key/nparser/taclets.old.txt index f17dc2bbc68..2e397ca646a 100644 --- a/key.core/src/test/resources/de/uka/ilkd/key/nparser/taclets.old.txt +++ b/key.core/src/test/resources/de/uka/ilkd/key/nparser/taclets.old.txt @@ -1,5 +1,5 @@ # This files contains representation of taclets, which are accepted and revised. -# Date: Fri Jun 21 16:10:16 CEST 2024 +# Date: Wed Jun 26 12:45:30 CEST 2024 == abortJavaCardTransactionAPI (abortJavaCardTransactionAPI) ========================================= abortJavaCardTransactionAPI { @@ -1304,7 +1304,7 @@ assignmentAdditionInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 + #seCharByteShortInt1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaAddInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaAddInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1313,7 +1313,7 @@ assignmentAdditionLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt + #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seCharByteShortInt,#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seCharByteShortInt,#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1322,7 +1322,7 @@ assignmentAdditionLong2 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong + #seCharByteShortInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seLong,#seCharByteShortInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seLong,#seCharByteShortInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1331,7 +1331,7 @@ assignmentAdditionLong3 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 + #seLong1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seLong0,#seLong1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaAddLong(#seLong0,#seLong1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1644,7 +1644,7 @@ assignmentMultiplicationInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 * #seCharByteShortInt1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaMulInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaMulInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1653,7 +1653,7 @@ assignmentMultiplicationLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt * #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seCharByteShortInt,#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seCharByteShortInt,#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1662,7 +1662,7 @@ assignmentMultiplicationLong2 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong * #seCharByteShortInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seLong,#seCharByteShortInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seLong,#seCharByteShortInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1671,7 +1671,7 @@ assignmentMultiplicationLong3 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 * #seLong1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seLong0,#seLong1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaMulLong(#seLong0,#seLong1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1680,7 +1680,7 @@ assignmentShiftLeftInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 << #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftLeftInt(#seCharByteShortInt0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftLeftInt(#seCharByteShortInt0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1689,7 +1689,7 @@ assignmentShiftLeftLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 << #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftLeftLong(#seLong0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftLeftLong(#seLong0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1698,7 +1698,7 @@ assignmentShiftRightInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 >> #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftRightInt(#seCharByteShortInt0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftRightInt(#seCharByteShortInt0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1707,7 +1707,7 @@ assignmentShiftRightLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 >> #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftRightLong(#seLong0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaShiftRightLong(#seLong0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1774,7 +1774,7 @@ assignmentSubtractionInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 - #seCharByteShortInt1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaSubInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaSubInt(#seCharByteShortInt0,#seCharByteShortInt1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1783,7 +1783,7 @@ assignmentSubtractionLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt - #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seCharByteShortInt,#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seCharByteShortInt,#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1792,7 +1792,7 @@ assignmentSubtractionLong2 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong - #seCharByteShortInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seLong,#seCharByteShortInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seLong,#seCharByteShortInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1801,7 +1801,7 @@ assignmentSubtractionLong3 { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 - #seLong1; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seLong0,#seLong1)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaSubLong(#seLong0,#seLong1)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1810,7 +1810,7 @@ assignmentUnsignedShiftRightInt { \find(#normalassign ((modal operator))|{{ .. #loc = #seCharByteShortInt0 >>> #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaUnsignedShiftRightInt(#seCharByteShortInt0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaUnsignedShiftRightInt(#seCharByteShortInt0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -1819,7 +1819,7 @@ assignmentUnsignedShiftRightLong { \find(#normalassign ((modal operator))|{{ .. #loc = #seLong0 >>> #se; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaUnsignedShiftRightLong(#seLong0,#se)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaUnsignedShiftRightLong(#seLong0,#se)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -5400,7 +5400,7 @@ Choices: sequences:on} defOfSeqUpd { \find(seqUpd(seq,idx,value)) \varcond(\notFreeIn(uSub (variable), seq (Seq term)), \notFreeIn(uSub (variable), value (any term)), \notFreeIn(uSub (variable), idx (int term))) -\replacewith(seqDef{uSub (variable)}(Z(0(#)),seqLen(seq),if-then-else(equals(uSub,idx),value,any::seqGet(seq,uSub)))) +\replacewith(seqDef{uSub (variable)}(Z(0(#)),seqLen(seq),if-then-else(equals(uSub,idx),value,any::seqGet(seq,uSub)))) Choices: sequences:on} ----------------------------------------------------- @@ -9697,7 +9697,7 @@ Choices: sequences:on} == getOfSeqUpd (getOfSeqUpd) ========================================= getOfSeqUpd { \find(alpha::seqGet(seqUpd(seq,idx,value),jdx)) -\replacewith(if-then-else(and(and(leq(Z(0(#)),jdx),lt(jdx,seqLen(seq))),equals(idx,jdx)),alpha::cast(value),alpha::seqGet(seq,jdx))) +\replacewith(if-then-else(and(and(leq(Z(0(#)),jdx),lt(jdx,seqLen(seq))),equals(idx,jdx)),alpha::cast(value),alpha::seqGet(seq,jdx))) \heuristics(simplify_enlarging) Choices: sequences:on} ----------------------------------------------------- @@ -12135,7 +12135,7 @@ Choices: sequences:on} == lenOfSeqUpd (lenOfSeqUpd) ========================================= lenOfSeqUpd { \find(seqLen(seqUpd(seq,idx,value))) -\replacewith(seqLen(seq)) +\replacewith(seqLen(seq)) \heuristics(simplify) Choices: sequences:on} ----------------------------------------------------- @@ -13516,7 +13516,7 @@ narrowingByteCastInt { \find(#normalassign ((modal operator))|{{ .. #loc = (byte) #seInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13525,7 +13525,7 @@ narrowingByteCastLong { \find(#normalassign ((modal operator))|{{ .. #loc = (byte) #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13534,7 +13534,7 @@ narrowingByteCastShort { \find(#normalassign ((modal operator))|{{ .. #loc = (byte) #seShort; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seShort)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastByte(#seShort)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13570,7 +13570,7 @@ narrowingCharCastByte { \find(#normalassign ((modal operator))|{{ .. #loc = (char) #seByte; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seByte)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seByte)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13579,7 +13579,7 @@ narrowingCharCastInt { \find(#normalassign ((modal operator))|{{ .. #loc = (char) #seInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13588,7 +13588,7 @@ narrowingCharCastLong { \find(#normalassign ((modal operator))|{{ .. #loc = (char) #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13597,7 +13597,7 @@ narrowingCharCastShort { \find(#normalassign ((modal operator))|{{ .. #loc = (char) #seShort; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seShort)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastChar(#seShort)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13615,7 +13615,7 @@ narrowingIntCastLong { \find(#normalassign ((modal operator))|{{ .. #loc = (int) #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastInt(#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastInt(#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13642,7 +13642,7 @@ narrowingShortCastInt { \find(#normalassign ((modal operator))|{{ .. #loc = (short) #seInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastShort(#seInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastShort(#seInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -13651,7 +13651,7 @@ narrowingShortCastLong { \find(#normalassign ((modal operator))|{{ .. #loc = (short) #seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaCastShort(#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaCastShort(#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -16555,7 +16555,7 @@ Choices: true} == ssubsortDirect (ssubsortDirect) ========================================= ssubsortDirect { \find(ssubsort(alphSub::ssort,alph::ssort)) -\replacewith(true) +\replacewith(true) \heuristics(simplify) Choices: true} ----------------------------------------------------- @@ -16563,14 +16563,14 @@ Choices: true} ssubsortSup { \find(ssubsort(alph::ssort,alphSub::ssort)) \varcond(\not\same(alphSub, alph)) -\replacewith(false) +\replacewith(false) \heuristics(simplify) Choices: true} ----------------------------------------------------- == ssubsortTop (ssubsortTop) ========================================= ssubsortTop { \find(ssubsort(s,anySORT)) -\replacewith(true) +\replacewith(true) \heuristics(simplify) Choices: true} ----------------------------------------------------- @@ -17071,8 +17071,8 @@ Choices: programRules:Java} ----------------------------------------------------- == subsortTrans (subsortTrans) ========================================= subsortTrans { -\assumes ([ssubsort(s1,s2),ssubsort(s2,s3)]==>[]) -\add [ssubsort(s1,s3)]==>[] +\assumes ([ssubsort(s1,s2),ssubsort(s2,s3)]==>[]) +\add [ssubsort(s1,s3)]==>[] \heuristics(simplify_enlarging) Choices: true} ----------------------------------------------------- @@ -18209,7 +18209,7 @@ unaryMinusInt { \find(#normalassign ((modal operator))|{{ .. #loc = -#seCharByteShortInt; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaUnaryMinusInt(#seCharByteShortInt)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaUnaryMinusInt(#seCharByteShortInt)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- @@ -18218,7 +18218,7 @@ unaryMinusLong { \find(#normalassign ((modal operator))|{{ .. #loc = -#seLong; ... }}| (post)) -\replacewith(update-application(elem-update(#loc (program Variable))(javaUnaryMinusLong(#seLong)),#normalassign(post))) +\sameUpdateLevel\replacewith(update-application(elem-update(#loc (program Variable))(javaUnaryMinusLong(#seLong)),#normalassign(post))) \heuristics(executeIntegerAssignment) Choices: programRules:Java} ----------------------------------------------------- From dd8d2ef9dd90bed6be188ef1be70ac3988c17063 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Wed, 26 Jun 2024 19:50:10 +0200 Subject: [PATCH 67/73] delete TreeWalker and use general navigation structure in RenamingSourceElementProperty --- .../de/uka/ilkd/key/java/SourceElement.java | 4 +- .../key/java/visitor/JavaASTTreeWalker.java | 326 ------------------ .../uka/ilkd/key/java/visitor/TreeWalker.java | 106 ------ .../RenamingSourceElementProperty.java | 63 ++-- .../java/visitor/TestJavaASTTreeWalker.java | 99 ------ 5 files changed, 35 insertions(+), 563 deletions(-) delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java delete mode 100644 key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java delete mode 100644 key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java index ce823018a39..5e53075ed15 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java +++ b/key.core/src/main/java/de/uka/ilkd/key/java/SourceElement.java @@ -4,11 +4,11 @@ package de.uka.ilkd.key.java; import de.uka.ilkd.key.java.visitor.Visitor; - -import org.key_project.logic.SyntaxElement; import de.uka.ilkd.key.logic.equality.EqualsModProperty; import de.uka.ilkd.key.logic.equality.Property; +import org.key_project.logic.SyntaxElement; + /** * A source element is a piece of syntax. It does not necessarily have a semantics, at least none * that is machinable, for instance a {@link recoder.java.Comment}. taken from RECODER and changed diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java deleted file mode 100644 index 87bc7a8bcd3..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/JavaASTTreeWalker.java +++ /dev/null @@ -1,326 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.java.visitor; - -import de.uka.ilkd.key.java.NonTerminalProgramElement; -import de.uka.ilkd.key.java.SourceElement; - -/** - * This class is used to walk a tree of {@link SourceElement}s. The tree is - * traversed in depth-first order, and the walker can be used to visit the - * children of a node, the siblings of a node and the parent of a node. - *

    - * The walker is backed by a stack, which is used to store the path from the root to the current - * node. - * - * @author Tobias Reinhold - */ -public class JavaASTTreeWalker implements TreeWalker { - /** - * The root of the tree that is being walked. - */ - private final SourceElement root; - - /** - * The node of the tree the walker is currently at. - */ - private SourceElement currentNode; - - /** - * The stack used to store the path from the root to the current node. - */ - private final Stack stack; - - /** - * Creates a new {@link JavaASTTreeWalker} with the given {@code root} as the root of the tree. - */ - public JavaASTTreeWalker(SourceElement root) { - this.root = root; - currentNode = root; - stack = new Stack(); - } - - @Override - public SourceElement root() { - return root; - } - - @Override - public SourceElement currentNode() { - return currentNode; - } - - @Override - public SourceElement firstChild() { - if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { - // The index of the next child of the stored node to be visited is 1, as the first child - // at index 0 is visited. - stack.push(new NonTerminalProgramElementChildIndexPair(ntpe, 1)); - currentNode = ntpe.getChildAt(0); - return currentNode; - } - return null; - } - - @Override - public SourceElement lastChild() { - if (currentNode instanceof NonTerminalProgramElement ntpe && ntpe.getChildCount() > 0) { - // The index of the next child of the stored node to be visited is childCount, as the - // last child at index childCount - 1 is visited. - // This signals that no more children are left to be visited. - stack.push( - new NonTerminalProgramElementChildIndexPair(ntpe, ntpe.getChildCount())); - currentNode = ntpe.getChildAt(ntpe.getChildCount() - 1); - return currentNode; - } - return null; - } - - @Override - public SourceElement nextNode() { - // TreeWalker is depth-first, so if the current node has children, the first child is taken - SourceElement node = firstChild(); - if (node != null) { - return node; - } - // As the current node has no children, the next sibling would be the next node - node = nextSibling(); - if (node != null) { - return node; - } - // As the current node has no children and no next sibling, we have to go up the tree and - // find siblings of the ancestors - while (!stack.empty()) { - parentNode(); - node = nextSibling(); - if (node != null) { - return node; - } - } - // The current node is the last node in the tree - return null; - } - - @Override - public SourceElement previousNode() { - // If the current node is the root, there is no previous node - if (currentNode == root) { - return null; - } - // If the current node has no previous sibling, it is a first child, and we must therefore - // go to the parent - SourceElement node = previousSibling(); - if (node == null) { - node = parentNode(); - return node; - } - // As the current node has a previous sibling, we must go down the tree through all last - // children to find the real previous node - while (true) { - SourceElement lastChild = lastChild(); - if (lastChild != null) { - node = lastChild; - } else { - return node; - } - } - } - - @Override - public SourceElement nextSibling() { - if (currentNode != root && !stack.empty()) { - final NonTerminalProgramElementChildIndexPair parent = stack.peek(); - final NonTerminalProgramElement parentNode = parent.getNonTerminalProgramElement(); - final int parentChildIndex = parent.getNextChildToVisitIndex(); - if (parentChildIndex < parentNode.getChildCount()) { - // The index of the next child of the parent on the stack that should be visited is - // increased by one - parent.setNextChildToVisitIndex(parentChildIndex + 1); - currentNode = parentNode.getChildAt(parentChildIndex); - return currentNode; - } - } - return null; - } - - @Override - public SourceElement previousSibling() { - if (currentNode != root && !stack.empty()) { - final NonTerminalProgramElementChildIndexPair parent = stack.peek(); - final NonTerminalProgramElement parentNode = parent.getNonTerminalProgramElement(); - final int parentChildIndex = parent.getNextChildToVisitIndex(); - // parentChildIndex > 1 means that the current node is not the first child of its parent - // => it has a previous sibling - if (parentChildIndex > 1) { - // The index of the next child of the parent on the stack that should be visited is - // decreased by one - parent.setNextChildToVisitIndex(parentChildIndex - 1); - currentNode = parentNode.getChildAt(parentChildIndex - 2); - return currentNode; - } - } - return null; - } - - @Override - public SourceElement parentNode() { - if (stack.empty()) { - return null; - } - final NonTerminalProgramElementChildIndexPair parent = stack.pop(); - currentNode = parent.getNonTerminalProgramElement(); - return currentNode; - } - - - // ----------------- internal classes for easier handling of the tree ----------------- // - - /** - * A pair consisting of a {@link NonTerminalProgramElement} and how many children of it have - * already been visited. - */ - private static class NonTerminalProgramElementChildIndexPair { - /** - * The {@link NonTerminalProgramElement} of the pair. - */ - final NonTerminalProgramElement nonTerminalProgramElement; - - /** - * The index of the next child of {@code nonTerminalProgramElement} that should be visited. - */ - int nextChildToVisitIndex; - - /** - * Constructs a new pair with the given {@code nonTerminalProgramElement} and index of the - * next child to be visited. - * - * @param nonTerminalProgramElement the {@link NonTerminalProgramElement} of the pair - * @param nextChildToVisitIndex the index of the next child of - * {@code nonTerminalProgramElement} that - * should to be visited - */ - NonTerminalProgramElementChildIndexPair(NonTerminalProgramElement nonTerminalProgramElement, - int nextChildToVisitIndex) { - this.nonTerminalProgramElement = nonTerminalProgramElement; - this.nextChildToVisitIndex = nextChildToVisitIndex; - } - - /** - * Sets the index of the next child of {@code nonTerminalProgramElement} that should to be - * visited. - * - * @param nextChildToVisitIndex the index of the next child of - * {@code nonTerminalProgramElement} that - * should to be visited - */ - void setNextChildToVisitIndex(int nextChildToVisitIndex) { - this.nextChildToVisitIndex = nextChildToVisitIndex; - } - - /** - * Returns the index of the next child of {@code nonTerminalProgramElement} that should to - * be visited. - * - * @return the index of the next child of {@code nonTerminalProgramElement} that should to - * be visited - */ - int getNextChildToVisitIndex() { - return nextChildToVisitIndex; - } - - /** - * Returns the {@link NonTerminalProgramElement} of the pair. - * - * @return the {@link NonTerminalProgramElement} of the pair - */ - NonTerminalProgramElement getNonTerminalProgramElement() { - return nonTerminalProgramElement; - } - } - - /** - * Class used to store pairs of {@link NonTerminalProgramElement}s and how many children of each - * have been already visited. - */ - private static class Stack { - /** - * The array that is backing the stack. - */ - NonTerminalProgramElementChildIndexPair[] stack; - - /** - * The number of elements contained in the stack. - *

    - * {@code count} therefore points to the next free spot available in the {@code stack}. - */ - int count; - - /** - * Constructs a new {@link Stack} with an initial capacity of 16 elements. - */ - public Stack() { - final int standardInitialCapacity = 16; - stack = new NonTerminalProgramElementChildIndexPair[standardInitialCapacity]; - } - - /** - * Pushes a new element onto the stack. - * - * @param element the element to be pushed onto the stack - */ - void push(NonTerminalProgramElementChildIndexPair element) { - if (count >= stack.length) { - resizeStack(); - } - stack[count++] = element; - } - - /** - * Removes and returns the topmost element of the stack or {@code null} if the stack is - * empty. - * - * @return the topmost element of the stack or {@code null} if the stack is empty - */ - NonTerminalProgramElementChildIndexPair pop() { - if (count == 0) { - return null; - } - return stack[--count]; - } - - /** - * Returns the topmost element of the stack without removing it or {@code null} if the stack - * is empty. - * - * @return the topmost element of the stack or {@code null} if the stack is empty - */ - NonTerminalProgramElementChildIndexPair peek() { - if (count == 0) { - return null; - } - return stack[count - 1]; - } - - /** - * Returns whether the stack is empty. - * - * @return {@code true} if the stack is empty, {@code false} otherwise - */ - boolean empty() { - return count == 0; - } - - /** - * Increases the capacity of the stack. - *

    - * Currently, the stack size is simply doubled. - */ - void resizeStack() { - NonTerminalProgramElementChildIndexPair[] newStack = - new NonTerminalProgramElementChildIndexPair[stack.length * 2]; - System.arraycopy(stack, 0, newStack, 0, count); - stack = newStack; - } - } -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java b/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java deleted file mode 100644 index 154ad7eda08..00000000000 --- a/key.core/src/main/java/de/uka/ilkd/key/java/visitor/TreeWalker.java +++ /dev/null @@ -1,106 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.java.visitor; - -import de.uka.ilkd.key.java.SourceElement; - -/** - * This interface is used to walk a tree of {@link SourceElement}s. The tree is - * traversed in depth-first order, and the walker can be used to visit the - * children of a node, the siblings of a node and the parent of a node. - * - * @author Tobias Reinhold - */ -public interface TreeWalker { - /** - * Returns the root of the tree that is being walked. - * - * @return the root of the tree that is being walked - */ - SourceElement root(); - - /** - * Returns the node of the tree the walker is currently at. - * - * @return the node of the tree the walker is currently at - */ - SourceElement currentNode(); - - /** - * Walks to the first child of the current node, or stays in place if the current node has no - * children. - * - * @return the first child of the current node, or {@code null} if the current node has no - * children - */ - SourceElement firstChild(); - - /** - * Walks to the last child of the current node, or stays in place if the current node has no - * children. - * - * @return the last child of the current node, or {@code null} if the current node has no - * children - */ - SourceElement lastChild(); - - /** - * Walks to the next node in the tree, or stays in place if the current node is the last node in - * the tree. - *

    - * Possible candidates for the next node are (in this order): - *

      - *
    1. The first child of the current node
    2. - *
    3. The next sibling of the current node
    4. - *
    5. The first found next sibling of some ancestor of the current node from bottom to top
    6. - *
    - * - * @return the next node in the tree, or {@code null} if the current node is the last node in - * the tree - */ - SourceElement nextNode(); - - /** - * Walks to the previous node in the tree, or stays in place if the current node is the first - * node in the tree. - *

    - * Possible candidates for the previous node are (in this order): - *

      - *
    1. The furthest down last descendant of the previous sibling of the current node in the tree - *
    2. - *
    3. The previous sibling of the current node
    4. - *
    5. The parent of the current node
    6. - *
    - * - * @return the previous node in the tree, or {@code null} if the current node is the last node - * in the tree - */ - SourceElement previousNode(); - - /** - * Walks to the next sibling of the current node, or stays in place if the current node has no - * next sibling. - * - * @return the next sibling of the current node, or {@code null} if the current node has no next - * sibling - */ - SourceElement nextSibling(); - - /** - * Walks to the previous sibling of the current node, or stays in place if the current node has - * no previous sibling. - * - * @return the previous sibling of the current node, or {@code null} if the current node has no - * previous sibling - */ - SourceElement previousSibling(); - - /** - * Walks to the parent of the current node, or stays in place if the current node has no parent. - * - * @return the parent of the current node, or {@code null} if the current node - * has no parent - */ - SourceElement parentNode(); -} diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 3597b9f51e0..aab6b6499a6 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -8,10 +8,12 @@ import de.uka.ilkd.key.java.SourceElement; import de.uka.ilkd.key.java.declaration.VariableSpecification; import de.uka.ilkd.key.java.statement.LabeledStatement; -import de.uka.ilkd.key.java.visitor.JavaASTTreeWalker; import de.uka.ilkd.key.logic.ProgramElementName; import de.uka.ilkd.key.logic.op.ProgramVariable; +import org.key_project.logic.SyntaxElement; +import org.key_project.logic.SyntaxElementCursor; + /** * A property that can be used in * {@link EqualsModProperty#equalsModProperty(Object, Property, Object[])} for @@ -61,13 +63,14 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V nat = new NameAbstractionTable(); } - JavaASTTreeWalker tw1 = new JavaASTTreeWalker(se1); - JavaASTTreeWalker tw2 = new JavaASTTreeWalker(se2); - - SourceElement next1 = tw1.currentNode(); - SourceElement next2 = tw2.currentNode(); + SyntaxElementCursor c1 = se1.getCursor(), c2 = se2.getCursor(); + SyntaxElement next1, next2; + boolean hasNext1, hasNext2; // Check at the end if both cursors have reached the end - while (next1 != null && next2 != null) { + do { + // First nodes can never be null as cursor is initialized with 'this' + next1 = c1.getCurrentNode(); + next2 = c2.getCurrentNode(); // Handle special cases of prior equalsModRenaming implementation if (next1 instanceof LabeledStatement ls) { if (!handleLabeledStatement(ls, next2, nat)) { @@ -91,13 +94,10 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V return false; } } - // walk to the next nodes in the tree - next1 = tw1.nextNode(); - next2 = tw2.nextNode(); - } + } while ((hasNext1 = c1.goToNext()) & (hasNext2 = c2.goToNext())); - return next1 == null && next2 == null; + return hasNext1 == hasNext2; } @Override @@ -108,14 +108,14 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { /* --------------------- Helper methods for special cases ---------------------- */ /** - * Handles the standard case of comparing two {@link SourceElement}s modulo renaming. + * Handles the standard case of comparing two {@link SyntaxElement}s modulo renaming. * - * @param se1 the first {@link SourceElement} to be compared - * @param se2 the second {@link SourceElement} to be compared + * @param se1 the first {@link SyntaxElement} to be compared + * @param se2 the second {@link SyntaxElement} to be compared * @return {@code true} iff the two source elements are equal under the standard {@code equals} * method */ - private boolean handleStandard(SourceElement se1, SourceElement se2) { + private boolean handleStandard(SyntaxElement se1, SyntaxElement se2) { /* * As the prior implementations of equalsModRenaming for SourceElements were mostly the same * as their normal equals methods, we decided to move equalsModRenaming completely into the @@ -127,15 +127,15 @@ private boolean handleStandard(SourceElement se1, SourceElement se2) { /** * Handles the special case of comparing a {@link JavaNonTerminalProgramElement} to a - * {@link SourceElement}. + * {@link SyntaxElement}. * * @param jnte the {@link JavaNonTerminalProgramElement} to be compared - * @param se the {@link SourceElement} to be compared + * @param se the {@link SyntaxElement} to be compared * @return {@code true} iff {@code se} is of the same class and has the same number of children * as {@code jnte} */ private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramElement jnte, - SourceElement se) { + SyntaxElement se) { /* * A JavaNonTerminalProgramElement is a special case of a SourceElement, as we must not * traverse the children recursively through the normal equals method. This is the case @@ -153,15 +153,15 @@ private boolean handleJavaNonTerminalProgramElements(JavaNonTerminalProgramEleme } /** - * Handles the special case of comparing a {@link LabeledStatement} to a {@link SourceElement}. + * Handles the special case of comparing a {@link LabeledStatement} to a {@link SyntaxElement}. * * @param ls the {@link LabeledStatement} to be compared - * @param se the {@link SourceElement} to be compared + * @param se the {@link SyntaxElement} to be compared * @param nat the {@link NameAbstractionTable} the label of {@code ls} should be added to * @return {@code true} iff {@code se} is also a {@link LabeledStatement} and has the same * number of children as {@code ls} */ - private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, + private boolean handleLabeledStatement(LabeledStatement ls, SyntaxElement se, NameAbstractionTable nat) { /* * A LabeledStatement is a special case of a JavaNonTerminalProgramElement, as we must also @@ -183,15 +183,15 @@ private boolean handleLabeledStatement(LabeledStatement ls, SourceElement se, /** * Handles the special case of comparing a {@link VariableSpecification} to a - * {@link SourceElement}. + * {@link SyntaxElement}. * * @param vs the {@link VariableSpecification} to be compared - * @param se the {@link SourceElement} to be compared + * @param se the {@link SyntaxElement} to be compared * @param nat the {@link NameAbstractionTable} the variable of {@code vs} should be added to * @return {@code true} iff {@code se} is of the same class as {@code vs} and has the same * number of children, dimensions and type */ - private boolean handleVariableSpecification(VariableSpecification vs, SourceElement se, + private boolean handleVariableSpecification(VariableSpecification vs, SyntaxElement se, NameAbstractionTable nat) { /* * A VariableSpecification is a special case of a JavaNonTerminalProgramElement similar to @@ -226,16 +226,16 @@ private boolean handleVariableSpecification(VariableSpecification vs, SourceElem /** * Handles the special case of comparing a {@link ProgramVariable} or a - * {@link ProgramElementName} to a {@link SourceElement}. + * {@link ProgramElementName} to a {@link SyntaxElement}. * - * @param se1 the first {@link SourceElement} which is either a {@link ProgramVariable} or a + * @param se1 the first {@link SyntaxElement} which is either a {@link ProgramVariable} or a * {@link ProgramElementName} - * @param se2 the second {@link SourceElement} to be compared + * @param se2 the second {@link SyntaxElement} to be compared * @param nat the {@link NameAbstractionTable} that should be used to check whether {@code se1} * and {@code se2} have the same abstract name * @return {@code true} iff {@code se1} and {@code se2} have the same abstract name */ - private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElement se2, + private boolean handleProgramVariableOrElementName(SyntaxElement se1, SyntaxElement se2, NameAbstractionTable nat) { /* * A ProgramVariable or a ProgramElementName is a special case of a SourceElement and one @@ -245,7 +245,10 @@ private boolean handleProgramVariableOrElementName(SourceElement se1, SourceElem if (se1.getClass() != se2.getClass()) { return false; } - return nat.sameAbstractName(se1, se2); + // We can cast here as se1 is either a ProgramVariable or a ProgramElementName + // (this method is only called for these two classes in equalsModThisProperty) + // and se2 is of the same class as se1 + return nat.sameAbstractName((SourceElement) se1, (SourceElement) se2); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java b/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java deleted file mode 100644 index 3817af80b68..00000000000 --- a/key.core/src/test/java/de/uka/ilkd/key/java/visitor/TestJavaASTTreeWalker.java +++ /dev/null @@ -1,99 +0,0 @@ -/* This file is part of KeY - https://key-project.org - * KeY is licensed under the GNU General Public License Version 2 - * SPDX-License-Identifier: GPL-2.0-only */ -package de.uka.ilkd.key.java.visitor; - -import de.uka.ilkd.key.java.SourceElement; -import de.uka.ilkd.key.java.StatementBlock; -import de.uka.ilkd.key.java.declaration.LocalVariableDeclaration; -import de.uka.ilkd.key.java.expression.literal.IntLiteral; -import de.uka.ilkd.key.rule.TacletForTests; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -/** - * Tests for {@link JavaASTTreeWalker}. - * - * @author Tobias Reinhold - */ -public class TestJavaASTTreeWalker { - @Test - public void walker() { - final SourceElement se = TacletForTests - .parsePrg("{int i; int j = 1; i = j; if (i == j) { i = 2; } else { j = 2; } }"); - JavaASTTreeWalker walker = new JavaASTTreeWalker(se); - - // The root node should be a StatementBlock - assertEquals(StatementBlock.class, walker.root().getClass()); - StatementBlock root = (StatementBlock) walker.root(); - SourceElement currentNode = walker.currentNode(); - assertEquals(currentNode, root, - "In the beginning, the current node should be the root node."); - - // For the following assertions, I drew the AST of the source element on paper and used that - // to verify the correctness of the walker. - - // First child of the root is a LocalVariableDeclaration; should be the next visited - SourceElement firstChild = walker.firstChild(); - assertEquals(LocalVariableDeclaration.class, firstChild.getClass(), - "The first child of the root should be a LocalVariableDeclaration."); - assertEquals(root.getChildAt(0), firstChild, - "walker.firstChild() should return the first child of the current node."); - - // The parent of the first child should be the root - currentNode = walker.parentNode(); - assertEquals(root, currentNode, "The parent of the first child should be the root."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (0)"); - - // The next node should be the first child again - currentNode = walker.nextNode(); - assertEquals(firstChild, currentNode, "The next node should be the first child."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (1)"); - - // Going back, we should be at the root again - currentNode = walker.previousNode(); - assertEquals(root, currentNode, "The previous node should be the root again."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (2)"); - - // The last child (the fourth) of the root should be an If - currentNode = walker.lastChild(); - assertEquals(root.getChildAt(3), currentNode, - "walker.lastChild() should here return the last (fourth) child of the root."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (3)"); - - // Interesting step: moving to the previous sibling should yield the CopyAssignment 'i = j;' - currentNode = walker.previousSibling(); - assertEquals(root.getChildAt(2), currentNode, - "walker.previousSibling() should here return the second to last (third) child of the root."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (4)"); - - // Even more interesting: the previous node should now be deeper in the tree, namely a - // descendant of the second LocalVariableDeclaration 'int j = 1:' - // To be exact, it should be the IntLiteral '1' - currentNode = walker.previousNode(); - assertEquals(IntLiteral.class, currentNode.getClass(), - "The previous node should be an IntLiteral."); - assertEquals(1, ((IntLiteral) currentNode).getValue(), - "The previous node should be the IntLiteral '1'."); - assertEquals(currentNode, walker.currentNode(), - "The worker should not just return the new node but also visit it. (5)"); - - // The next sibling should then be null, as the currentNode is the last node in the subtree - // of 'int j = 1;' - assertNull(walker.nextSibling(), - "walker.nextSibling() should return null as there is no next sibling."); - - // Also interesting: the walker did not move, the next node should then again be the - // CopyAssignment (third child) of the root - currentNode = walker.nextNode(); - assertEquals(root.getChildAt(2), currentNode, - "The next node should again be the third child of the root."); - } -} From c04215260bdfd5781ea7ea64793d53104d5b3be6 Mon Sep 17 00:00:00 2001 From: Tobias Reinhold Date: Thu, 27 Jun 2024 16:05:37 +0200 Subject: [PATCH 68/73] use general navigation structure for hashCodeModThisProperty in RenamingSourceElementProperty --- .../equality/RenamingSourceElementProperty.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java index 3958134f94a..530297d1c41 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java +++ b/key.core/src/main/java/de/uka/ilkd/key/logic/equality/RenamingSourceElementProperty.java @@ -113,16 +113,18 @@ public boolean equalsModThisProperty(SourceElement se1, SourceElement se2, V public int hashCodeModThisProperty(SourceElement sourceElement) { /* * Currently, the best approach seems to be to walk through the SourceElement with a - * JavaASTTreeWalker and sum up hash codes. + * SyntaxElementCursor and sum up hash codes. */ - JavaASTTreeWalker tw = new JavaASTTreeWalker(sourceElement); - SourceElement next = tw.currentNode(); NameAbstractionMap absMap = new NameAbstractionMap(); int hashCode = 1; + SyntaxElementCursor c = sourceElement.getCursor(); + SyntaxElement next; - while (next != null) { + do { + // First node can never be null as cursor is initialized with 'this' + next = c.getCurrentNode(); // Handle special cases so that hashCodeModThisProperty follows equalsModThisProperty if (next instanceof LabeledStatement ls) { hashCode = 31 * hashCode + ls.getChildCount(); @@ -134,17 +136,15 @@ public int hashCodeModThisProperty(SourceElement sourceElement) { + vs.getDimensions(); absMap.add(vs); } else if (next instanceof ProgramVariable || next instanceof ProgramElementName) { - hashCode = 31 * hashCode + absMap.getAbstractName(next); + hashCode = 31 * hashCode + absMap.getAbstractName((SourceElement) next); } else if (next instanceof JavaNonTerminalProgramElement jnte) { hashCode = 31 * hashCode + jnte.getChildCount(); } else { // In the standard case, we just use the default hashCode implementation hashCode = 31 * hashCode + next.hashCode(); } - // walk to the next nodes in the tree - next = tw.nextNode(); - } + } while (c.goToNext()); return hashCode; } From b4112577415ef154b8e3a5c7d58dd217ee2a657d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 20:05:33 +0000 Subject: [PATCH 69/73] Bump the gradle-deps group with 4 updates Bumps the gradle-deps group with 4 updates: [org.junit.jupiter:junit-jupiter-api](https://github.com/junit-team/junit5), [org.junit.jupiter:junit-jupiter-params](https://github.com/junit-team/junit5), [org.junit.jupiter:junit-jupiter-engine](https://github.com/junit-team/junit5) and org.checkerframework. Updates `org.junit.jupiter:junit-jupiter-api` from 5.10.2 to 5.10.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3) Updates `org.junit.jupiter:junit-jupiter-params` from 5.10.2 to 5.10.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3) Updates `org.junit.jupiter:junit-jupiter-engine` from 5.10.2 to 5.10.3 - [Release notes](https://github.com/junit-team/junit5/releases) - [Commits](https://github.com/junit-team/junit5/compare/r5.10.2...r5.10.3) Updates `org.checkerframework` from 0.6.39 to 0.6.41 --- updated-dependencies: - dependency-name: org.junit.jupiter:junit-jupiter-api dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-deps - dependency-name: org.junit.jupiter:junit-jupiter-params dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-deps - dependency-name: org.junit.jupiter:junit-jupiter-engine dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-deps - dependency-name: org.checkerframework dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gradle-deps ... Signed-off-by: dependabot[bot] --- build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle b/build.gradle index 935addaa9a8..6df46bffc01 100644 --- a/build.gradle +++ b/build.gradle @@ -24,7 +24,7 @@ plugins { id "com.diffplug.spotless" version "6.25.0" // EISOP Checker Framework - id "org.checkerframework" version "0.6.39" + id "org.checkerframework" version "0.6.41" } // Configure this project for use inside IntelliJ: @@ -90,11 +90,11 @@ subprojects { checkerFramework "io.github.eisop:checker:$eisop_version" testImplementation("ch.qos.logback:logback-classic:1.5.6") - testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.2' - testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.2' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.10.3' + testImplementation 'org.junit.jupiter:junit-jupiter-params:5.10.3' testImplementation project(':key.util') - testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.2' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.10.3' } tasks.withType(JavaCompile) { From c6ffa71e1ad4af153bcd4ecdecdc28585833c275 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 1 Jul 2024 20:24:59 +0000 Subject: [PATCH 70/73] Bump gradle/actions from 3.3.2 to 3.4.2 in the github-actions-deps group Bumps the github-actions-deps group with 1 update: [gradle/actions](https://github.com/gradle/actions). Updates `gradle/actions` from 3.3.2 to 3.4.2 - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/v3.3.2...v3.4.2) --- updated-dependencies: - dependency-name: gradle/actions dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-deps ... Signed-off-by: dependabot[bot] --- .github/workflows/code_quality.yml | 8 ++++---- .github/workflows/gradle-publish.yml | 2 +- .github/workflows/javadoc.yml | 2 +- .github/workflows/nightlydeploy.yml | 2 +- .github/workflows/opttest.yml | 2 +- .github/workflows/tests.yml | 4 ++-- .github/workflows/tests_winmac.yml | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index a13aecf615f..327890ba723 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -20,7 +20,7 @@ jobs: distribution: 'corretto' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Build with Gradle run: ./gradlew -DENABLE_NULLNESS=true compileTest @@ -49,7 +49,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: SpotlessCheck run: ./gradlew --continue spotlessCheck @@ -81,7 +81,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Checkstyle run: ./gradlew --continue checkstyleMainChanged - run: | @@ -108,7 +108,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: PMD checks run: ./gradlew --continue pmdMainChanged diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index e46dd959484..ab43091e529 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -22,7 +22,7 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Assemble with Gradle run: ./gradlew assemble diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 82e5a48f7be..1ebbb82c9fe 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -19,7 +19,7 @@ jobs: distribution: 'corretto' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Build Documentation with Gradle run: ./gradlew alldoc diff --git a/.github/workflows/nightlydeploy.yml b/.github/workflows/nightlydeploy.yml index 97cd713ffac..f60a7fc2762 100644 --- a/.github/workflows/nightlydeploy.yml +++ b/.github/workflows/nightlydeploy.yml @@ -31,7 +31,7 @@ jobs: distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Build with Gradle run: ./gradlew --parallel assemble diff --git a/.github/workflows/opttest.yml b/.github/workflows/opttest.yml index 360cb718d81..8093ed2b328 100644 --- a/.github/workflows/opttest.yml +++ b/.github/workflows/opttest.yml @@ -25,7 +25,7 @@ jobs: cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Test with Gradle run: ./gradlew --continue ${{ matrix.tests }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index a9f68ed0541..e45ebec48c2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,7 +38,7 @@ jobs: cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: Test with Gradle run: ./gradlew --continue -DjacocoEnabled=true -x :key.core.symbolic_execution:test -x :key.core.proof_references:test test @@ -87,7 +87,7 @@ jobs: shell: bash - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: "Running tests: ${{ matrix.test }}" run: ./gradlew --continue ${{ matrix.test }} diff --git a/.github/workflows/tests_winmac.yml b/.github/workflows/tests_winmac.yml index 96a248d0b2c..fd4cbb74b31 100644 --- a/.github/workflows/tests_winmac.yml +++ b/.github/workflows/tests_winmac.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Gradle uses: - gradle/actions/setup-gradle@v3.3.2 + gradle/actions/setup-gradle@v3.4.2 - name: Test with Gradle run: ./gradlew --continue -x :key.core.symbolic_execution:test -x :key.core.proof_references:test test @@ -76,7 +76,7 @@ jobs: run: .github/dlsmt.sh - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.3.2 + uses: gradle/actions/setup-gradle@v3.4.2 - name: "Running tests: ${{ matrix.test }}" run: ./gradlew --continue ${{ matrix.test }} From dc486e411e98319a9d65de7e72d4d9404b763f57 Mon Sep 17 00:00:00 2001 From: Mattias Ulbrich Date: Sun, 7 Jul 2024 14:35:28 +0200 Subject: [PATCH 71/73] saving proofs for sequent problems Parsing sequents in \problem{...} has been supported for a while now. This commit adapts the saving routine accordingly. --- .../key/proof/io/OutputStreamProofSaver.java | 8 ++- .../uka/ilkd/key/proof/io/ProofSaverTest.java | 52 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java index 9bfd785e9e4..90223c6dbb5 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java @@ -209,7 +209,13 @@ public void save(OutputStream out) throws IOException { } final Sequent problemSeq = proof.root().sequent(); ps.println("\\problem {"); - printer.printSemisequent(problemSeq.succedent()); + if(problemSeq.antecedent().isEmpty() && problemSeq.succedent().size() == 1) { + // Problem statement is a single formula ... + printer.printSemisequent(problemSeq.succedent()); + } else { + // Problem statement is a proper sequent ... + printer.printSequent(problemSeq); + } ps.println(printer.result()); ps.println("}\n"); } diff --git a/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java b/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java new file mode 100644 index 00000000000..97add25bbbb --- /dev/null +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java @@ -0,0 +1,52 @@ +package de.uka.ilkd.key.proof.io; + +import de.uka.ilkd.key.java.Services; +import de.uka.ilkd.key.logic.Sequent; +import de.uka.ilkd.key.nparser.KeyIO; +import de.uka.ilkd.key.proof.Proof; +import de.uka.ilkd.key.proof.init.AbstractProfile; +import de.uka.ilkd.key.proof.init.InitConfig; +import de.uka.ilkd.key.rule.TacletForTests; +import de.uka.ilkd.key.util.KeYConstants; +import org.jspecify.annotations.Nullable; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.IOException; + +import static org.junit.jupiter.api.Assertions.*; + +class ProofSaverTest { + + void testSaveProblemToFile(String content) throws IOException { + Services services = TacletForTests.services(); + KeyIO io = new KeyIO(services); + KeyIO.Loader loader = io.load(content); + Sequent seq = loader.parseFile().loadProblem().getProblem(); + final InitConfig initConfig = + new InitConfig(new Services(AbstractProfile.getDefaultProfile())); + Proof proof = new Proof("test", seq, "", initConfig, null); + File file = File.createTempFile("proofSaveTest", ".key"); + file.deleteOnExit(); + String status = new ProofSaver(proof, file).save(); + assertNull(status); + + KeyIO io2 = new KeyIO(services); + KeyIO.Loader loader2 = io2.load(content); + Sequent seq2 = loader2.parseFile().loadProblem().getProblem(); + + assertEquals(seq, seq2); + } + + @Test + void saveTermProblemToFile() throws IOException { + String content = "\\problem { true }"; + testSaveProblemToFile(content); + } + + @Test + void saveSequentProblemToFile() throws IOException { + String content = "\\problem { true, false ==> false, false }"; + testSaveProblemToFile(content); + } +} \ No newline at end of file From ea0879b48926a6a5ebe4761e807042600153a97a Mon Sep 17 00:00:00 2001 From: Mattias Ulbrich Date: Sun, 7 Jul 2024 17:02:15 +0200 Subject: [PATCH 72/73] spotlessing ... --- .../key/proof/io/OutputStreamProofSaver.java | 2 +- .../de/uka/ilkd/key/proof/io/ProofSaverTest.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java b/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java index 90223c6dbb5..82ee5ef01ad 100644 --- a/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java +++ b/key.core/src/main/java/de/uka/ilkd/key/proof/io/OutputStreamProofSaver.java @@ -209,7 +209,7 @@ public void save(OutputStream out) throws IOException { } final Sequent problemSeq = proof.root().sequent(); ps.println("\\problem {"); - if(problemSeq.antecedent().isEmpty() && problemSeq.succedent().size() == 1) { + if (problemSeq.antecedent().isEmpty() && problemSeq.succedent().size() == 1) { // Problem statement is a single formula ... printer.printSemisequent(problemSeq.succedent()); } else { diff --git a/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java b/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java index 97add25bbbb..d55f9f78743 100644 --- a/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java +++ b/key.core/src/test/java/de/uka/ilkd/key/proof/io/ProofSaverTest.java @@ -1,5 +1,11 @@ +/* This file is part of KeY - https://key-project.org + * KeY is licensed under the GNU General Public License Version 2 + * SPDX-License-Identifier: GPL-2.0-only */ package de.uka.ilkd.key.proof.io; +import java.io.File; +import java.io.IOException; + import de.uka.ilkd.key.java.Services; import de.uka.ilkd.key.logic.Sequent; import de.uka.ilkd.key.nparser.KeyIO; @@ -7,12 +13,8 @@ import de.uka.ilkd.key.proof.init.AbstractProfile; import de.uka.ilkd.key.proof.init.InitConfig; import de.uka.ilkd.key.rule.TacletForTests; -import de.uka.ilkd.key.util.KeYConstants; -import org.jspecify.annotations.Nullable; -import org.junit.jupiter.api.Test; -import java.io.File; -import java.io.IOException; +import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; @@ -24,7 +26,7 @@ void testSaveProblemToFile(String content) throws IOException { KeyIO.Loader loader = io.load(content); Sequent seq = loader.parseFile().loadProblem().getProblem(); final InitConfig initConfig = - new InitConfig(new Services(AbstractProfile.getDefaultProfile())); + new InitConfig(new Services(AbstractProfile.getDefaultProfile())); Proof proof = new Proof("test", seq, "", initConfig, null); File file = File.createTempFile("proofSaveTest", ".key"); file.deleteOnExit(); @@ -49,4 +51,4 @@ void saveSequentProblemToFile() throws IOException { String content = "\\problem { true, false ==> false, false }"; testSaveProblemToFile(content); } -} \ No newline at end of file +} From 2ff13cb13cc8afccda71ea9fb19932ec65ede59a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Aug 2024 20:25:22 +0000 Subject: [PATCH 73/73] Bump the github-actions-deps group with 2 updates Bumps the github-actions-deps group with 2 updates: [gradle/actions](https://github.com/gradle/actions) and [JetBrains/qodana-action](https://github.com/jetbrains/qodana-action). Updates `gradle/actions` from 3.4.2 to 3.5.0 - [Release notes](https://github.com/gradle/actions/releases) - [Commits](https://github.com/gradle/actions/compare/v3.4.2...v3.5.0) Updates `JetBrains/qodana-action` from 2024.1.5 to 2024.1.8 - [Release notes](https://github.com/jetbrains/qodana-action/releases) - [Commits](https://github.com/jetbrains/qodana-action/compare/v2024.1.5...v2024.1.8) --- updated-dependencies: - dependency-name: gradle/actions dependency-type: direct:production update-type: version-update:semver-minor dependency-group: github-actions-deps - dependency-name: JetBrains/qodana-action dependency-type: direct:production update-type: version-update:semver-patch dependency-group: github-actions-deps ... Signed-off-by: dependabot[bot] --- .github/workflows/code_quality.yml | 10 +++++----- .github/workflows/gradle-publish.yml | 2 +- .github/workflows/javadoc.yml | 2 +- .github/workflows/nightlydeploy.yml | 2 +- .github/workflows/opttest.yml | 2 +- .github/workflows/tests.yml | 4 ++-- .github/workflows/tests_winmac.yml | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/code_quality.yml b/.github/workflows/code_quality.yml index 327890ba723..c6fd0d577c3 100644 --- a/.github/workflows/code_quality.yml +++ b/.github/workflows/code_quality.yml @@ -20,7 +20,7 @@ jobs: distribution: 'corretto' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Build with Gradle run: ./gradlew -DENABLE_NULLNESS=true compileTest @@ -32,7 +32,7 @@ jobs: with: fetch-depth: 0 - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2024.1.5 + uses: JetBrains/qodana-action@v2024.1.8 - uses: github/codeql-action/upload-sarif@v3 if: success() || failure() @@ -49,7 +49,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: SpotlessCheck run: ./gradlew --continue spotlessCheck @@ -81,7 +81,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Checkstyle run: ./gradlew --continue checkstyleMainChanged - run: | @@ -108,7 +108,7 @@ jobs: java-version: '21' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: PMD checks run: ./gradlew --continue pmdMainChanged diff --git a/.github/workflows/gradle-publish.yml b/.github/workflows/gradle-publish.yml index ab43091e529..0a1ed3eb07e 100644 --- a/.github/workflows/gradle-publish.yml +++ b/.github/workflows/gradle-publish.yml @@ -22,7 +22,7 @@ jobs: server-id: github # Value of the distributionManagement/repository/id field of the pom.xml - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Assemble with Gradle run: ./gradlew assemble diff --git a/.github/workflows/javadoc.yml b/.github/workflows/javadoc.yml index 1ebbb82c9fe..8c3ed455250 100644 --- a/.github/workflows/javadoc.yml +++ b/.github/workflows/javadoc.yml @@ -19,7 +19,7 @@ jobs: distribution: 'corretto' cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Build Documentation with Gradle run: ./gradlew alldoc diff --git a/.github/workflows/nightlydeploy.yml b/.github/workflows/nightlydeploy.yml index f60a7fc2762..33b62b2c5c9 100644 --- a/.github/workflows/nightlydeploy.yml +++ b/.github/workflows/nightlydeploy.yml @@ -31,7 +31,7 @@ jobs: distribution: 'temurin' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Build with Gradle run: ./gradlew --parallel assemble diff --git a/.github/workflows/opttest.yml b/.github/workflows/opttest.yml index 8093ed2b328..75839cd76c5 100644 --- a/.github/workflows/opttest.yml +++ b/.github/workflows/opttest.yml @@ -25,7 +25,7 @@ jobs: cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Test with Gradle run: ./gradlew --continue ${{ matrix.tests }} diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e45ebec48c2..e5f0041c442 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -38,7 +38,7 @@ jobs: cache: 'gradle' - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: Test with Gradle run: ./gradlew --continue -DjacocoEnabled=true -x :key.core.symbolic_execution:test -x :key.core.proof_references:test test @@ -87,7 +87,7 @@ jobs: shell: bash - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: "Running tests: ${{ matrix.test }}" run: ./gradlew --continue ${{ matrix.test }} diff --git a/.github/workflows/tests_winmac.yml b/.github/workflows/tests_winmac.yml index fd4cbb74b31..28335bd0998 100644 --- a/.github/workflows/tests_winmac.yml +++ b/.github/workflows/tests_winmac.yml @@ -30,7 +30,7 @@ jobs: - name: Setup Gradle uses: - gradle/actions/setup-gradle@v3.4.2 + gradle/actions/setup-gradle@v3.5.0 - name: Test with Gradle run: ./gradlew --continue -x :key.core.symbolic_execution:test -x :key.core.proof_references:test test @@ -76,7 +76,7 @@ jobs: run: .github/dlsmt.sh - name: Setup Gradle - uses: gradle/actions/setup-gradle@v3.4.2 + uses: gradle/actions/setup-gradle@v3.5.0 - name: "Running tests: ${{ matrix.test }}" run: ./gradlew --continue ${{ matrix.test }}