Skip to content

Commit 043c97c

Browse files
authored
Proof Slicing: make dependency tracking optional (#3309)
Fixes #3301 by adding an option to disable the dependency tracker and adding a way to create the dependency graph after the proof is done. cc @unp1
2 parents e8321cf + 5d76195 commit 043c97c

11 files changed

Lines changed: 415 additions & 72 deletions

File tree

key.core/src/main/java/de/uka/ilkd/key/logic/Sequent.java

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
public class Sequent implements Iterable<SequentFormula> {
2626

27-
public static final Sequent EMPTY_SEQUENT = new NILSequent();
27+
public static final Sequent EMPTY_SEQUENT = NILSequent.INSTANCE;
2828

2929
/**
3030
* creates a new Sequent with empty succedent
@@ -184,6 +184,7 @@ public SequentChangeInfo addFormula(ImmutableList<SequentFormula> insertions,
184184
* have been added or removed
185185
*/
186186
public SequentChangeInfo replaceFormula(int formulaNr, SequentFormula replacement) {
187+
checkFormulaIndex(formulaNr);
187188
formulaNr--;
188189
boolean inAntec = formulaNr < antecedent.size();
189190

@@ -326,9 +327,7 @@ public int formulaNumberInSequent(PosInOccurrence pio) {
326327
* @return the sequent formula at that position
327328
*/
328329
public SequentFormula getFormulabyNr(int formulaNumber) {
329-
if (formulaNumber <= 0 || formulaNumber > size()) {
330-
throw new RuntimeException("No formula nr. " + formulaNumber + " in seq. " + this);
331-
}
330+
checkFormulaIndex(formulaNumber);
332331
if (formulaNumber <= antecedent.size()) {
333332
return antecedent.get(formulaNumber - 1);
334333
}
@@ -357,7 +356,12 @@ public Iterator<SequentFormula> iterator() {
357356
return new SequentIterator(antecedent(), succedent());
358357
}
359358

359+
/**
360+
* @param formulaNumber formula number (1-based)
361+
* @return whether that formula is in the antecedent
362+
*/
360363
public boolean numberInAntec(int formulaNumber) {
364+
checkFormulaIndex(formulaNumber);
361365
return formulaNumber <= antecedent.size();
362366
}
363367

@@ -419,7 +423,11 @@ public boolean varIsBound(QuantifiableVariable v) {
419423
return false;
420424
}
421425

422-
static class NILSequent extends Sequent {
426+
private static final class NILSequent extends Sequent {
427+
private static final NILSequent INSTANCE = new NILSequent();
428+
429+
private NILSequent() {
430+
}
423431

424432
@Override
425433
public boolean isEmpty() {
@@ -530,4 +538,17 @@ public boolean contains(SequentFormula form) {
530538
public ImmutableList<SequentFormula> asList() {
531539
return antecedent.asList().append(succedent.asList());
532540
}
541+
542+
/**
543+
* Check that the provided formula number is a 1-based index and in bounds.
544+
* Throws an {@link IllegalArgumentException} otherwise.
545+
*
546+
* @param formulaNumber the formula number
547+
*/
548+
private void checkFormulaIndex(int formulaNumber) {
549+
if (formulaNumber <= 0 || formulaNumber > size()) {
550+
throw new IllegalArgumentException(
551+
"No formula nr. " + formulaNumber + " in seq. " + this);
552+
}
553+
}
533554
}

key.core/src/main/java/de/uka/ilkd/key/proof/Goal.java

Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ private void fireAutomaticStateChanged(boolean oldAutomatic, boolean newAutomati
255255
private void setNode(Node p_node) {
256256
if (node().sequent() != p_node.sequent()) {
257257
node = p_node;
258-
resetTagManager();
258+
tagManager = new FormulaTagManager(this);
259259
} else {
260260
node = p_node;
261261
}
@@ -458,18 +458,6 @@ public void clearAndDetachRuleAppIndex() {
458458
ruleAppIndex.clearAndDetachCache();
459459
}
460460

461-
// @Deprecated
462-
// public void setProgramVariables(Namespace ns) {
463-
// // final Iterator<Named> it=ns.elements().iterator();
464-
// // ImmutableSet<ProgramVariable> s = DefaultImmutableSet.<ProgramVariable>nil();
465-
// // while (it.hasNext()) {
466-
// // s = s.add((ProgramVariable)it.next());
467-
// // }
468-
// // node().setGlobalProgVars(DefaultImmutableSet.<ProgramVariable>nil());
469-
// // proof().getNamespaces().programVariables().set(s);
470-
// // setGlobalProgVars(s);
471-
// }
472-
473461
public void addProgramVariable(ProgramVariable pv) {
474462
localNamespaces.programVariables().addSafely(pv);
475463
}
@@ -532,6 +520,7 @@ public void removeLastAppliedRuleApp() {
532520
* creates n new nodes as children of the referenced node and new n goals that have references
533521
* to these new nodes.
534522
*
523+
* @param n number of goals to create
535524
* @return the list of new created goals.
536525
*/
537526
@Nonnull
@@ -571,10 +560,6 @@ public ImmutableList<Goal> split(int n) {
571560
return goalList;
572561
}
573562

574-
private void resetTagManager() {
575-
tagManager = new FormulaTagManager(this);
576-
}
577-
578563
public void setBranchLabel(String s) {
579564
node.getNodeInfo().setBranchLabel(s);
580565
}
@@ -600,14 +585,21 @@ private void resetLocalSymbols() {
600585
localNamespaces = newNS.copyWithParent();
601586
}
602587

588+
/**
589+
* Perform the provided rule application on this goal.
590+
* Returns the new goal(s), if any.
591+
* This will also populate a {@link RuleAppInfo} object and fire the corresponding event.
592+
* The state of the proof is also updated.
593+
*
594+
* @param ruleApp the rule app
595+
* @return new goal(s)
596+
*/
603597
public ImmutableList<Goal> apply(final RuleApp ruleApp) {
604-
605598
final Proof proof = proof();
606599

607600
final NodeChangeJournal journal = new NodeChangeJournal(proof, this);
608601
addGoalListener(journal);
609602

610-
611603
final Node n = node;
612604

613605
/*
@@ -630,19 +622,14 @@ public ImmutableList<Goal> apply(final RuleApp ruleApp) {
630622

631623
proof.getServices().saveNameRecorder(n);
632624

633-
if (goalList != null) { // TODO: can goalList be null?
634-
if (goalList.isEmpty()) {
635-
proof.closeGoal(this);
636-
} else {
637-
proof.replace(this, goalList);
638-
if (ruleApp instanceof TacletApp && ((TacletApp) ruleApp).taclet().closeGoal()) {
639-
// the first new goal is the one to be closed
640-
proof.closeGoal(goalList.head());
641-
}
642-
if (ruleApp instanceof SMTRuleApp) {
643-
// the first new goal is the one to be closed
644-
proof.closeGoal(goalList.head());
645-
}
625+
if (goalList.isEmpty()) {
626+
proof.closeGoal(this);
627+
} else {
628+
proof.replace(this, goalList);
629+
if (ruleApp instanceof TacletApp tacletApp && tacletApp.taclet().closeGoal()
630+
|| ruleApp instanceof SMTRuleApp) {
631+
// the first new goal is the one to be closed
632+
proof.closeGoal(goalList.head());
646633
}
647634
}
648635

@@ -680,6 +667,7 @@ private void adaptNamespacesNewGoals(final ImmutableList<Goal> goalList) {
680667
}
681668
}
682669

670+
@Override
683671
public String toString() {
684672
LogicPrinter lp = LogicPrinter.purePrinter(new NotationInfo(), proof().getServices());
685673
lp.printSequent(node.sequent());
@@ -711,9 +699,6 @@ public void makeLocalNamespacesFrom(NamespaceSet ns) {
711699
this.localNamespaces = ns.copyWithParent().copyWithParent();
712700
}
713701

714-
/**
715-
*
716-
*/
717702
public List<RuleApp> getAllBuiltInRuleApps() {
718703
final BuiltInRuleAppIndex index = ruleAppIndex().builtInRuleAppIndex();
719704
LinkedList<RuleApp> ruleApps = new LinkedList<>();

key.core/src/main/java/de/uka/ilkd/key/proof/Node.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,13 @@ public Iterator<Node> childrenIterator() {
456456
return new NodeIterator(children.iterator());
457457
}
458458

459+
/**
460+
* @return the direct children of this node.
461+
*/
462+
public Collection<Node> children() {
463+
return Collections.unmodifiableList(children);
464+
}
465+
459466
/**
460467
* @return an iterator for all nodes in the subtree.
461468
*/

key.core/src/main/java/de/uka/ilkd/key/rule/Taclet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public RuleJustification getRuleJustification() {
8686
}
8787
}
8888

89-
/** name of the taclet */
89+
/** unique name of the taclet */
9090
private final Name name;
9191

9292
/** name displayed by the pretty printer */
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/* This file is part of KeY - https://key-project.org
2+
* KeY is licensed under the GNU General Public License Version 2
3+
* SPDX-License-Identifier: GPL-2.0-only */
4+
package org.key_project.util.collection;
5+
6+
import java.util.Collection;
7+
import java.util.IdentityHashMap;
8+
import java.util.Iterator;
9+
import java.util.Set;
10+
11+
/**
12+
* Hash set using the object's identity instead of their hashcode to determine uniqueness.
13+
*
14+
* @param <T> elmeent type
15+
* @author Arne Keller
16+
*/
17+
public class IdentityHashSet<T> implements Set<T> {
18+
/**
19+
* Backing store.
20+
*/
21+
private final IdentityHashMap<T, Object> innerMap = new IdentityHashMap<>();
22+
23+
/**
24+
* Construct an empty set.
25+
*/
26+
public IdentityHashSet() {
27+
28+
}
29+
30+
/**
31+
* Copy provided elements into a new set.
32+
*
33+
* @param list elements to add
34+
*/
35+
public IdentityHashSet(ImmutableList<T> list) {
36+
list.forEach(this::add);
37+
}
38+
39+
@Override
40+
public int size() {
41+
return innerMap.size();
42+
}
43+
44+
@Override
45+
public boolean isEmpty() {
46+
return innerMap.isEmpty();
47+
}
48+
49+
@Override
50+
public boolean contains(Object o) {
51+
return innerMap.containsKey(o);
52+
}
53+
54+
@Override
55+
public Iterator<T> iterator() {
56+
return innerMap.keySet().iterator();
57+
}
58+
59+
@Override
60+
public Object[] toArray() {
61+
return innerMap.keySet().toArray();
62+
}
63+
64+
@Override
65+
public <T1> T1[] toArray(T1[] a) {
66+
return innerMap.keySet().toArray(a);
67+
}
68+
69+
@Override
70+
public boolean add(T o) {
71+
return innerMap.put(o, o) == null;
72+
}
73+
74+
@Override
75+
public boolean remove(Object o) {
76+
var contained = innerMap.containsKey(o);
77+
innerMap.remove(o);
78+
return contained;
79+
}
80+
81+
@Override
82+
public boolean addAll(Collection<? extends T> c) {
83+
var changed = false;
84+
for (T o : c) {
85+
changed |= add(o);
86+
}
87+
return changed;
88+
}
89+
90+
@Override
91+
public void clear() {
92+
innerMap.clear();
93+
}
94+
95+
@Override
96+
public boolean removeAll(Collection<?> c) {
97+
var changed = false;
98+
for (Object o : c) {
99+
changed |= remove(o);
100+
}
101+
return changed;
102+
}
103+
104+
@Override
105+
public boolean retainAll(Collection<?> c) {
106+
return innerMap.keySet().retainAll(c);
107+
}
108+
109+
@Override
110+
public boolean containsAll(Collection<?> c) {
111+
return innerMap.keySet().containsAll(c);
112+
}
113+
}

0 commit comments

Comments
 (0)