forked from runtimeverification/k
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathKProve.java
More file actions
117 lines (104 loc) · 5.24 KB
/
KProve.java
File metadata and controls
117 lines (104 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright (c) 2015-2016 K Team. All Rights Reserved.
package org.kframework.kprove;
import com.google.inject.Inject;
import org.apache.commons.io.FilenameUtils;
import org.kframework.attributes.Att;
import org.kframework.compile.*;
import org.kframework.definition.*;
import org.kframework.kompile.CompiledDefinition;
import org.kframework.kompile.Kompile;
import org.kframework.kore.K;
import org.kframework.kore.KApply;
import org.kframework.krun.KRun;
import org.kframework.main.GlobalOptions;
import org.kframework.rewriter.Rewriter;
import org.kframework.utils.Stopwatch;
import org.kframework.utils.errorsystem.KEMException;
import org.kframework.utils.errorsystem.KExceptionManager;
import org.kframework.utils.file.FileUtil;
import org.kframework.utils.file.TTYInfo;
import scala.Option;
import scala.Tuple2;
import scala.collection.Set;
import java.io.File;
import java.util.*;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static org.kframework.Collections.*;
/**
* Class that implements the "--prove" option.
*/
public class KProve {
private final KExceptionManager kem;
private final Stopwatch sw;
private final FileUtil files;
private TTYInfo tty;
@Inject
public KProve(KExceptionManager kem, Stopwatch sw, FileUtil files, TTYInfo tty) {
this.kem = kem;
this.sw = sw;
this.files = files;
this.tty = tty;
}
public int run(KProveOptions options, CompiledDefinition compiledDefinition, Backend backend, Function<Module, Rewriter> rewriterGenerator) {
Tuple2<Definition, Module> compiled = getProofDefinition(options.specFile(files), options.defModule, options.specModule, compiledDefinition, backend, options.global, files, kem, sw);
Rewriter rewriter = rewriterGenerator.apply(compiled._1().mainModule());
Module specModule = compiled._2();
K results = rewriter.prove(specModule);
int exit;
if (results instanceof KApply) {
KApply kapp = (KApply) results;
exit = kapp.klabel().name().equals("#True") ? 0 : 1;
} else {
exit = 1;
}
KRun.prettyPrint(compiled._1().getModule("LANGUAGE-PARSING").get(), options.prettyPrint.output, s -> KRun.outputFile(s, options.prettyPrint, files), results, options.prettyPrint.color(tty.stdout, files.getEnv()));
return exit;
}
private static Module getModule(String defModule, Map<String, Module> modules, Definition oldDef) {
if (modules.containsKey(defModule))
return modules.get(defModule);
Option<Module> mod = oldDef.getModule(defModule);
if (mod.isDefined()) {
return mod.get();
}
throw KEMException.criticalError("Module " + defModule + " does not exist.");
}
public static Map<Definition, Definition> cache = Collections.synchronizedMap(new LinkedHashMap<Definition, Definition>() {
@Override
protected boolean removeEldestEntry(Map.Entry entry) {
return size() > 10;
}
});
public static Tuple2<Definition, Module> getProofDefinition(File proofFile, String defModuleName, String specModuleName, CompiledDefinition compiledDefinition, Backend backend, GlobalOptions options, FileUtil files, KExceptionManager kem, Stopwatch sw) {
Kompile kompile = new Kompile(compiledDefinition.kompileOptions, options, files, kem, sw, true);
if (defModuleName == null) {
defModuleName = compiledDefinition.kompiledDefinition.mainModule().name();
}
if (specModuleName == null) {
specModuleName = FilenameUtils.getBaseName(proofFile.getName()).toUpperCase();
}
java.util.Set<Module> modules = kompile.parseModules(compiledDefinition, defModuleName, files.resolveWorkingDirectory(proofFile).getAbsoluteFile());
Map<String, Module> modulesMap = new HashMap<>();
modules.forEach(m -> modulesMap.put(m.name(), m));
Module defModule = getModule(defModuleName, modulesMap, compiledDefinition.getParsedDefinition());
Module specModule = getModule(specModuleName, modulesMap, compiledDefinition.getParsedDefinition());
specModule = backend.specificationSteps(compiledDefinition.kompiledDefinition).apply(specModule);
specModule = spliceModule(specModule, compiledDefinition.kompiledDefinition);
Definition combinedDef = Definition.apply(defModule, (Set<Module>) immutable(modules).$bar(compiledDefinition.getParsedDefinition().entryModules()), Att.empty());
Definition compiled = compileDefinition(backend, combinedDef);
return Tuple2.apply(compiled, specModule);
}
private static Definition compileDefinition(Backend backend, Definition combinedDef) {
Definition compiled = cache.get(combinedDef);
if (compiled == null) {
compiled = backend.steps().apply(combinedDef);
cache.put(combinedDef, compiled);
}
return compiled;
}
private static Module spliceModule(Module specModule, Definition kompiledDefinition) {
return ModuleTransformer.from(mod -> kompiledDefinition.getModule(mod.name()).isDefined() ? kompiledDefinition.getModule(mod.name()).get() : mod, "splice imports of specification module").apply(specModule);
}
}