Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proof caching: external database #3265

Draft
wants to merge 27 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9e72425
More work on the cache database
FliegendeWurst Jul 14, 2023
8f0ae90
Basic database UI
FliegendeWurst Jul 18, 2023
077d061
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Oct 30, 2023
4184797
Context action to add proof to caching database
FliegendeWurst Oct 30, 2023
9d94113
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Nov 2, 2023
084b201
New JSON interface
FliegendeWurst Nov 2, 2023
e5e2f01
Reword slicing warning for state merging
FliegendeWurst Nov 2, 2023
f45fbb0
Logging in reference searcher
FliegendeWurst Nov 2, 2023
1e88e33
WIP
FliegendeWurst Nov 2, 2023
4f01f0a
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Jan 18, 2024
2d23710
Hacky switch to JSON storage
FliegendeWurst Jan 18, 2024
c2ff84c
Make proof caching work end-to-end
FliegendeWurst Feb 8, 2024
1701765
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Feb 21, 2024
b15cc04
Track types in cached proof branch
FliegendeWurst Feb 21, 2024
5b2ec60
Save type metadata in proof caching metadata
FliegendeWurst Feb 21, 2024
6a56041
WIP changes to load off mediator
FliegendeWurst Feb 21, 2024
95644bc
More work on the caching database
FliegendeWurst Mar 11, 2024
caf1962
Fixes after making database non-static
FliegendeWurst Mar 15, 2024
19f1da1
Extend ext. cache candidates to higher branches
FliegendeWurst Mar 15, 2024
c2b8c9e
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Mar 15, 2024
cb0ec41
Automatically add proofs to the database
FliegendeWurst Mar 21, 2024
f540a14
More work on proof caching
FliegendeWurst Mar 21, 2024
0117122
Fix loading of cached branches from DB
FliegendeWurst Mar 27, 2024
97191d9
Javadocs
FliegendeWurst Mar 27, 2024
0bcba4f
Add 'size on disk' column to DB UI
FliegendeWurst Mar 27, 2024
f329965
Prevent going to proof not in task list
FliegendeWurst Mar 28, 2024
d61ed21
Merge remote-tracking branch 'origin/main' into proofCachingDatabase
FliegendeWurst Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package de.uka.ilkd.key.control;

import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
import java.util.function.Consumer;
Expand Down Expand Up @@ -298,7 +299,19 @@ public static KeYEnvironment<DefaultUserInterfaceControl> load(File keyFile)
}

/**
* Disposes this {@link KeYEnvironment}.
* Load a proof from the specified file.
*
* @param keyFile file to load
* @return environment with loaded proof
* @throws ProblemLoaderException on error during proof loading
*/
public static KeYEnvironment<DefaultUserInterfaceControl> load(Path keyFile)
throws ProblemLoaderException {
return load(keyFile.toFile());
}

/**
* Disposes this {@link KeYEnvironment} by disposing the loaded proof.
*/
public void dispose() {
if (loadedProof != null && !loadedProof.isDisposed()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +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.gui.plugins.caching;

import java.nio.file.Path;

/**
* A file used by some cached proof as part of the {@link CachingDatabase}.
*
* @param file path to the file (always located in ~/.key/cachedProofs)
* @param hash {@link String#hashCode()} of this file's content
* @author Arne Keller
*/
public record CachedFile(Path file, int hash) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
/* 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.gui.plugins.caching;

import java.nio.file.Path;
import java.util.*;

import de.uka.ilkd.key.java.Services;
import de.uka.ilkd.key.logic.Sequent;
import de.uka.ilkd.key.pp.LogicPrinter;

/**
* Data object about a proof branch cached on disk.
*
* @author Arne Keller
*/
public class CachedProofBranch {

/**
* File the cached proof is stored in.
*/
public final Path proofFile;
/**
* Name of the cached proof.
*/
public final String proofName;
/**
* The choice settings used in the proof.
*/
public final String choiceSettings;
/**
* KeY version used to create the proof.
*/
public final String keyVersion;
/**
* Step index of the cached branch.
*/
public final int stepIndex;

/**
* Referenced files the proof depends on.
*/
private final Collection<CachedFile> referencedFiles;
/**
* Java classes the proof loaded.
*/
private final List<String> javaClasses;
/**
* Antecedent part of the sequent of the cached branch.
*/
private final List<String> sequentAnte;
/**
* Succedent part of the sequent of the cached branch.
*/
private final List<String> sequentSucc;
/**
* Types of the functions present on the sequent.
*/
private final Map<String, String> typesFunctions;
/**
* Types of the location variables present on the sequent.
*/
private final Map<String, String> typesLocVars;

/**
* Create a new data object about a cached proof branch.
*
* @param proofFile the file the proof is stored in
* @param proofName the name of the cached proof
* @param referencedFiles java/key files referenced by the proof
* @param keyVersion KeY version used to save the proof
* @param choiceSettings choice settings of the proof
* @param stepIndex step index of the referenced node
* @param sequent sequent of that node
* @param services services of that node's proof
* @param javaClasses java classes the proof loaded
*/
public CachedProofBranch(Path proofFile, String proofName,
Collection<CachedFile> referencedFiles,
String choiceSettings,
String keyVersion,
int stepIndex, Sequent sequent, Services services, List<String> javaClasses) {
this.proofFile = proofFile;
this.proofName = proofName;
this.referencedFiles = referencedFiles;
this.keyVersion = keyVersion;
this.choiceSettings = choiceSettings;
this.stepIndex = stepIndex;
this.sequentAnte = new ArrayList<>();
var ante = sequent.antecedent();
for (int i = 0; i < ante.size(); i++) {
sequentAnte.add(
LogicPrinter.quickPrintTerm(ante.get(i).formula(), services, true, false, false));
}
this.sequentSucc = new ArrayList<>();
var succ = sequent.succedent();
for (int i = 0; i < succ.size(); i++) {
sequentSucc.add(
LogicPrinter.quickPrintTerm(succ.get(i).formula(), services, true, false, false));
}
var typeCollector = new TypeCollectingVisitor();
typeCollector.visit(sequent);

this.typesFunctions = typeCollector.getTypes();
this.typesLocVars = typeCollector.getTypesLocVars();
this.javaClasses = javaClasses;
}

/**
* Create a new data object about a cached proof branch.
*
* @param proofFile the file the proof is stored in
* @param proofName name of the cached proof
* @param referencedFiles files referenced by the proof
* @param choiceSettings choice settings of the proof
* @param keyVersion KeY version used to save the cached proof branch
* @param stepIndex step index of the referenced node
* @param sequentAnte antecedent part of the sequent of that node
* @param sequentSucc succedent part of the sequent of that node
* @param typesFunctions types of the functions present in the sequent
* @param typesLocVars types of the location variables present in the sequent
* @param javaClasses java classes the proof depends on
*/
public CachedProofBranch(Path proofFile, String proofName,
Collection<CachedFile> referencedFiles,
String choiceSettings,
String keyVersion,
int stepIndex, List<String> sequentAnte, List<String> sequentSucc,
Map<String, String> typesFunctions,
Map<String, String> typesLocVars,
List<String> javaClasses) {
this.proofFile = proofFile;
this.proofName = proofName;
this.referencedFiles = referencedFiles;
this.keyVersion = keyVersion;
this.choiceSettings = choiceSettings;
this.stepIndex = stepIndex;
this.sequentAnte = sequentAnte;
this.sequentSucc = sequentSucc;
this.typesFunctions = typesFunctions;
this.typesLocVars = typesLocVars;
this.javaClasses = javaClasses;
}

/**
* Determine whether this cached proof branch can be used to close the provided sequent.
* Returns true if the provided formulas are a superset of this branch.
*
* @param anteFormulas antecedent
* @param succFormulas succedent
* @param sequent the sequent
* @return whether this cached proof branch can close the new proof branch
*/
public boolean isCacheHitFor(Set<String> anteFormulas, Set<String> succFormulas,
Sequent sequent) {
var typeCollector = new TypeCollectingVisitor();
typeCollector.visit(sequent);
for (var entry : typeCollector.getTypes().entrySet()) {
var ourType = typesFunctions.get(entry.getKey());
if (ourType == null) {
continue;
}
if (!ourType.equals(entry.getValue())) {
return false;
}
}
for (var entry : typeCollector.getTypesLocVars().entrySet()) {
var ourType = typesLocVars.get(entry.getKey());
if (ourType == null) {
continue;
}
if (!ourType.equals(entry.getValue())) {
return false;
}
}
for (var ante : sequentAnte) {
if (!anteFormulas.contains(ante)) {
return false;
}
}
for (var succ : sequentSucc) {
if (!succFormulas.contains(succ)) {
return false;
}
}
return true;
}

public Map<String, String> getTypesFunctions() {
return Collections.unmodifiableMap(typesFunctions);
}

public Map<String, String> getTypesLocVars() {
return Collections.unmodifiableMap(typesLocVars);
}

public Collection<CachedFile> getReferencedFiles() {
return Collections.unmodifiableCollection(referencedFiles);
}

public List<String> getSequentAnte() {
return Collections.unmodifiableList(sequentAnte);
}

public List<String> getSequentSucc() {
return Collections.unmodifiableList(sequentSucc);
}

public List<String> getJavaClasses() {
return Collections.unmodifiableList(javaClasses);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* 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.gui.plugins.caching;

import java.util.HashMap;
import java.util.Map;

import de.uka.ilkd.key.logic.Sequent;
import de.uka.ilkd.key.logic.Term;
import de.uka.ilkd.key.logic.op.LocationVariable;

import org.key_project.logic.Visitor;
import org.key_project.logic.op.Function;

public class TypeCollectingVisitor implements Visitor<Term> {
private final Map<String, String> types = new HashMap<>();
private final Map<String, String> typesLocVars = new HashMap<>();

public void visit(Sequent sequent) {
for (int i = 1; i <= sequent.size(); i++) {
var f = sequent.getFormulabyNr(i);
f.formula().execPreOrder(this);
}
}

@Override
public void visit(Term visited) {
var op = visited.op();
if (op instanceof Function function) {
types.put(function.name().toString(), function.argsToString());
}
if (op instanceof LocationVariable locationVariable) {
typesLocVars.put(locationVariable.name().toString(),
locationVariable.getKeYJavaType().toString());
}
}

@Override
public void subtreeEntered(Term subtreeRoot) {

}

@Override
public void subtreeLeft(Term subtreeRoot) {

}

public Map<String, String> getTypes() {
return types;
}

public Map<String, String> getTypesLocVars() {
return typesLocVars;
}
}
19 changes: 11 additions & 8 deletions key.core/src/main/java/de/uka/ilkd/key/pp/LogicPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,8 @@ public PosTableLayouter layouter() {
return layouter;
}

public static SequentViewLogicPrinter quickPrinter(Services services,
boolean usePrettyPrinting, boolean useUnicodeSymbols) {
private static SequentViewLogicPrinter quickPrinter(Services services,
boolean usePrettyPrinting, boolean useUnicodeSymbols, boolean printLabels) {
final NotationInfo ni = new NotationInfo();
if (services != null) {
ni.refresh(services, usePrettyPrinting, useUnicodeSymbols);
Expand All @@ -129,7 +129,9 @@ public static SequentViewLogicPrinter quickPrinter(Services services,
// Use a SequentViewLogicPrinter instead of a plain LogicPrinter,
// because the SequentViewLogicPrinter respects default TermLabel visibility
// settings.
return SequentViewLogicPrinter.purePrinter(ni, services, new TermLabelVisibilityManager());
var visibilityManager = new TermLabelVisibilityManager();
visibilityManager.setShowLabels(printLabels);
return SequentViewLogicPrinter.purePrinter(ni, services, visibilityManager);
}

/**
Expand All @@ -141,7 +143,7 @@ public static SequentViewLogicPrinter quickPrinter(Services services,
*/
public static String quickPrintTerm(Term t, Services services) {
return quickPrintTerm(t, services, NotationInfo.DEFAULT_PRETTY_SYNTAX,
NotationInfo.DEFAULT_UNICODE_ENABLED);
NotationInfo.DEFAULT_UNICODE_ENABLED, true);
}

/**
Expand All @@ -151,11 +153,12 @@ public static String quickPrintTerm(Term t, Services services) {
* @param services services.
* @param usePrettyPrinting whether to use pretty-printing.
* @param useUnicodeSymbols whether to use unicode symbols.
* @param printLabels whether to print labels.
* @return the printed term.
*/
public static String quickPrintTerm(Term t, Services services, boolean usePrettyPrinting,
boolean useUnicodeSymbols) {
var p = quickPrinter(services, usePrettyPrinting, useUnicodeSymbols);
boolean useUnicodeSymbols, boolean printLabels) {
var p = quickPrinter(services, usePrettyPrinting, useUnicodeSymbols, printLabels);
p.printTerm(t);
return p.result();
}
Expand All @@ -169,7 +172,7 @@ public static String quickPrintTerm(Term t, Services services, boolean usePretty
*/
public static String quickPrintSemisequent(Semisequent s, Services services) {
var p = quickPrinter(services, NotationInfo.DEFAULT_PRETTY_SYNTAX,
NotationInfo.DEFAULT_UNICODE_ENABLED);
NotationInfo.DEFAULT_UNICODE_ENABLED, true);
p.printSemisequent(s);
return p.result();
}
Expand All @@ -183,7 +186,7 @@ public static String quickPrintSemisequent(Semisequent s, Services services) {
*/
public static String quickPrintSequent(Sequent s, Services services) {
var p = quickPrinter(services, NotationInfo.DEFAULT_PRETTY_SYNTAX,
NotationInfo.DEFAULT_UNICODE_ENABLED);
NotationInfo.DEFAULT_UNICODE_ENABLED, true);
p.printSequent(s);
return p.result();
}
Expand Down
4 changes: 2 additions & 2 deletions key.core/src/main/java/de/uka/ilkd/key/pp/NotationInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,8 @@ public final class NotationInfo {

public static boolean DEFAULT_PRETTY_SYNTAX = true;
/**
* Whether the very fancy notation is enabled in which Unicode characters for logical operators
* are printed.
* Whether the very fancy notation is enabled by default in which Unicode characters for logical
* operators are printed.
*/
public static boolean DEFAULT_UNICODE_ENABLED = false;

Expand Down
Loading
Loading