Commit 0c1e07d3 authored by Alexander Weigl's avatar Alexander Weigl

Refactoring; Contrapositon works!

* remove errorstate and abstractstate
* parameterization of interpreter (related) classes
* interpreter.data package
* finished Rule and ProofScriptCommandBuilder
* VariableAssignment use Variable as key data type
* Contrapositon as test case
parent 61d52f08
Pipeline #10765 failed with stage
in 2 minutes and 29 seconds
......@@ -179,6 +179,13 @@
<scope>system</scope>
<systemPath>${basedir}/lib/recoderKey.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
</dependencies>
......
package edu.kit.formal.interpreter;
import java.util.List;
/**
* Represents a script state
*/
public abstract class AbstractState {
/**
* Returns whether the state is an ErrorState
*
* @return
*/
public abstract boolean isErrorState();
/**
* Returns all GoalNodes in a state
*
* @return
*/
public abstract List<GoalNode> getGoals();
/**
* Returns the selected GoalNode to which the next statement should be applied
* Can be null if no selector was applied or state is an ErrorState
*
* @return GoalNode or null
*/
public abstract GoalNode getSelectedGoalNode();
public abstract State copy();
}
package edu.kit.formal.interpreter;
import java.util.List;
/**
* State representing error states
*
* @author S.Grebing
*/
public class ErrorState extends AbstractState {
@Override
public boolean isErrorState() {
return true;
}
@Override
public List<GoalNode> getGoals() {
return null;
}
@Override
public GoalNode getSelectedGoalNode() {
return null;
}
@Override
public State copy() {
return null;
}
}
package edu.kit.formal.interpreter;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.Value;
import edu.kit.formal.interpreter.data.VariableAssignment;
import edu.kit.formal.proofscriptparser.DefaultASTVisitor;
import edu.kit.formal.proofscriptparser.Visitor;
import edu.kit.formal.proofscriptparser.ast.*;
......@@ -15,19 +18,19 @@ import java.util.List;
* @author S.Grebing
* @author A. Weigl
*/
public class Evaluator extends DefaultASTVisitor<Value> implements ScopeObservable {
public class Evaluator<T> extends DefaultASTVisitor<Value> implements ScopeObservable {
@Getter
private final List<VariableAssignment> matchedVariables = new ArrayList<>();
private final GoalNode goal;
private final VariableAssignment state;
@Getter
private final GoalNode<T> goal;
@Getter
@Setter
private MatcherApi matcher;
private MatcherApi<T> matcher;
@Getter
private List<Visitor> entryListeners = new ArrayList<>(),
exitListeners = new ArrayList<>();
public Evaluator(VariableAssignment assignment, GoalNode node) {
public Evaluator(VariableAssignment assignment, GoalNode<T> node) {
state = new VariableAssignment(assignment); // unmodifiable version of assignment
goal = node;
}
......@@ -58,6 +61,10 @@ public class Evaluator extends DefaultASTVisitor<Value> implements ScopeObservab
*/
@Override
public Value visit(MatchExpression match) {
if (match.getSignature() != null && !match.getSignature().isEmpty()) {
throw new IllegalStateException("not supported");
}
Value pattern = (Value) match.getPattern().accept(this);
List<VariableAssignment> va = null;
......@@ -73,6 +80,7 @@ public class Evaluator extends DefaultASTVisitor<Value> implements ScopeObservab
/**
* TODO Connect with KeY
* TODO remove return
*
* @param term
* @return
*/
......@@ -89,8 +97,7 @@ public class Evaluator extends DefaultASTVisitor<Value> implements ScopeObservab
@Override
public Value visit(Variable variable) {
//get variable value
String id = variable.getIdentifier();
Value v = state.lookupVarValue(id);
Value v = state.getValue(variable);
if (v != null) {
return v;
} else {
......
package edu.kit.formal.interpreter;
import de.uka.ilkd.key.api.KeYApi;
import de.uka.ilkd.key.api.ProjectedNode;
import de.uka.ilkd.key.api.ProofApi;
import de.uka.ilkd.key.api.ProofManagementApi;
import de.uka.ilkd.key.proof.io.ProblemLoaderException;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.KeyData;
import edu.kit.formal.proofscriptparser.Facade;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import java.io.File;
import java.io.IOException;
import java.util.List;
/**
* @author Alexander Weigl
* @version 1 (28.05.17)
*/
public class Execute {
private InterpreterBuilder interpreterBuilder = new InterpreterBuilder();
private List<String> keyFiles;
private File scriptFile;
public static void main(String[] args) throws IOException, ParseException {
Execute execute = new Execute();
execute.init(args);
execute.run();
}
public Interpreter<KeyData> run() {
try {
ProofManagementApi pma = KeYApi.loadFromKeyFile(new File(keyFiles.get(0)));
ProofApi pa = pma.getLoadedProof();
ProjectedNode root = pa.getFirstOpenGoal();
interpreterBuilder.proof(pa).macros().scriptCommands();
pa.getProof().getProofIndependentSettings().getGeneralSettings().setOneStepSimplification(false);
Interpreter<KeyData> inter = interpreterBuilder.build();
KeyData keyData = new KeyData(root.getProofNode(), pa.getEnv(), pa.getProof());
inter.interpret(Facade.getAST(scriptFile), new GoalNode<>(null, keyData));
return inter;
} catch (ProblemLoaderException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void init(String[] args) throws ParseException, IOException {
Options o = argparse();
DefaultParser parser = new DefaultParser();
CommandLine cli = parser.parse(o, args);
keyFiles = cli.getArgList();
scriptFile = new File(cli.getOptionValue("s"));
if (cli.getOptionValue('p') != null)
interpreterBuilder.scriptSearchPath(new File(cli.getOptionValue('p')));
}
public static Options argparse() {
Options options = new Options();
options.addOption("h", "--help", false, "print help text");
options.addOption("p", "--script-path", true, "include folder for scripts");
options.addOption("l", "--linter", false, "run linter before execute");
options.addOption("s", "--script", true, "script file");
return options;
}
}
......@@ -17,7 +17,7 @@ public class HistoryListener extends DefaultASTVisitor<Void> {
@Getter
private final List<ASTNode> queueNode = new LinkedList<>();
@Getter
private final List<AbstractState> queueState = new LinkedList<>();
private final List<State> queueState = new LinkedList<>();
private final Interpreter interpreter;
......
......@@ -2,12 +2,13 @@ package edu.kit.formal.interpreter;
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.api.ScriptApi;
import de.uka.ilkd.key.control.KeYEnvironment;
import de.uka.ilkd.key.macros.ProofMacro;
import de.uka.ilkd.key.macros.scripts.ProofScriptCommand;
import de.uka.ilkd.key.proof.Proof;
import edu.kit.formal.ScopeLogger;
import edu.kit.formal.interpreter.data.KeyData;
import edu.kit.formal.interpreter.funchdl.*;
import edu.kit.formal.proofscriptparser.Facade;
import edu.kit.formal.proofscriptparser.Visitor;
......@@ -46,8 +47,7 @@ public class InterpreterBuilder {
private ScopeLogger logger;
@Getter
private DefaultLookup lookup = new DefaultLookup(psh, pmh, pmr, pmc);
private Interpreter interpreter = new Interpreter(lookup);
private Interpreter<KeyData> interpreter = new Interpreter<>(lookup);
public InterpreterBuilder addProofScripts(File file) throws IOException {
return addProofScripts(Facade.getAST(file));
......@@ -63,7 +63,7 @@ public class InterpreterBuilder {
return this;
}
public Interpreter build() {
public Interpreter<KeyData> build() {
return interpreter;
}
......@@ -72,10 +72,9 @@ public class InterpreterBuilder {
return this;
}
//TODO
public InterpreterBuilder proof(KeYEnvironment env, Proof proof) {
this.proof = proof;
this.keyEnvironment = env;
//TODO relax constructor of proofapi
//return proof(new ProofApi(proof, env));
return this;
}
......@@ -97,6 +96,12 @@ public class InterpreterBuilder {
return this;
}
public InterpreterBuilder addKeyMatcher(ProofApi api) {
ScriptApi scriptApi = api.getScriptApi();
interpreter.setMatcherApi(new KeYMatcher(scriptApi, interpreter));
return this;
}
public InterpreterBuilder register(ProofScript... script) {
psh.addScripts(Arrays.asList(script));
return this;
......@@ -126,4 +131,10 @@ public class InterpreterBuilder {
logger = new ScopeLogger("interpreter");
return onEntry(logger);
}
public InterpreterBuilder proof(ProofApi pa) {
addKeyMatcher(pa);
pa.getRules().forEach(s -> pmr.getRules().put(s, null));
return this;
}
}
package edu.kit.formal.interpreter;
import de.uka.ilkd.key.api.ProjectedNode;
import de.uka.ilkd.key.api.ScriptApi;
import de.uka.ilkd.key.api.VariableAssignments;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.KeyData;
import edu.kit.formal.interpreter.data.VariableAssignment;
import edu.kit.formal.proofscriptparser.ast.Signature;
import java.util.List;
......@@ -13,29 +15,29 @@ import java.util.Map;
*
* @author S. Grebing
*/
public class KeYMatcher implements MatcherApi {
public class KeYMatcher implements MatcherApi<KeyData> {
private ScriptApi scrapi;
private Interpreter<KeyData> interpreter;
ScriptApi scrapi;
Interpreter interpreter;
public KeYMatcher(ScriptApi scrapi, Interpreter interpreter) {
public KeYMatcher(ScriptApi scrapi, Interpreter<KeyData> interpreter) {
this.scrapi = scrapi;
this.interpreter = interpreter;
}
@Override
public List<VariableAssignment> matchLabel(GoalNode currentState, String label) {
public List<VariableAssignment> matchLabel(GoalNode<KeyData> currentState,
String label) {
return null;
}
@Override
public List<VariableAssignment> matchSeq(GoalNode currentState, String data, Signature signature) {
public List<VariableAssignment> matchSeq(GoalNode<KeyData> currentState,
String term,
Signature signature) {
VariableAssignment assignments = currentState.getAssignments();
ProjectedNode pNode = currentState.getActualKeYGoalNode();
//ProjectedNode pNode = currentState.getData();
//Gemeinsame VariableAssignments
//scrapi.matchPattern(data, pNode.getSequent(), assignments);
//scrapi.matchPattern(data, pNode.getData(), assignments);
return null;
}
......@@ -50,12 +52,15 @@ public class KeYMatcher implements MatcherApi {
Map<String, VariableAssignments.VarType> keyTypeMap = keyAssignments.getTypeMap();
//find type needs to be rewritten
keyTypeMap.forEach((k, v) -> interpreterAssignments.addVarDecl(k, interpreter.transKeYFormType(v.getKeYDeclarationPrefix())));
/* weigl: getKeYDeclarationPrefix is missing in latest jar
keyTypeMap.forEach((k, v) -> interpreterAssignments.declare(
new Variable(k),
interpreter.transKeYFormType(v.getKeYDeclarationPrefix())));
*/
/*interpreterAssignments.getTypes().forEach((k, v) -> {
try {
//TODO cast is not valid
interpreterAssignments.setVarValue(k, (Value) keyAssignments.getVarValue(k));
interpreterAssignments.setVariableValue(k, (Value) keyAssignments.getVarValue(k));
} catch (Exception e) {
e.printStackTrace();
}
......
package edu.kit.formal.interpreter;
import de.uka.ilkd.key.api.ProofManagementApi;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.StringScriptSequent;
import edu.kit.formal.interpreter.funchdl.BuiltinCommands;
import edu.kit.formal.interpreter.funchdl.DefaultLookup;
import edu.kit.formal.proofscriptparser.Facade;
......@@ -28,7 +30,7 @@ public class Main {
ScriptApi scrapi = papi.getScriptApi();
*/
/*System.out.println(papi.getFirstOpenGoal().getSequent().toString());
/*System.out.println(papi.getFirstOpenGoal().getData().toString());
ProjectedNode openGoal = papi.getFirstOpenGoal();
RuleCommand rc = (RuleCommand) KeYApi.getScriptCommandApi().getScriptCommands("rule");
Map cArgs = new HashMap();
......@@ -40,14 +42,14 @@ public class Main {
va2.addType("X", VariableAssignments.VarType.FORMULA);
va2.addType("Y", VariableAssignments.VarType.FORMULA);
List<VariableAssignments> matches = scrapi.matchPattern("==> X -> Y", openGoal.getSequent(), va2);
List<VariableAssignments> matches = scrapi.matchPattern("==> X -> Y", openGoal.getData(), va2);
for (VariableAssignments match : matches) {
System.out.println(match);
}
if (matches.isEmpty()) {
System.out.println("No match found");
} else {
List<VariableAssignments> matches2 = scrapi.matchPattern("==> X -> Y", openGoal.getSequent(), va2);
List<VariableAssignments> matches2 = scrapi.matchPattern("==> X -> Y", openGoal.getData(), va2);
}*/
/* } catch (ProblemLoaderException e) {
......@@ -69,7 +71,7 @@ public class Main {
new BuiltinCommands.SplitCommand());
Interpreter inter = new Interpreter(lookup);
inter.interpret(l, "TestSeq");
inter.interpret(l, new GoalNode<String>(null, "abc"));
} catch (IOException e) {
e.printStackTrace();
}
......
package edu.kit.formal.interpreter;
import de.uka.ilkd.key.api.VariableAssignments;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.Value;
import edu.kit.formal.interpreter.data.VariableAssignment;
import edu.kit.formal.proofscriptparser.DefaultASTVisitor;
import edu.kit.formal.proofscriptparser.Visitor;
import edu.kit.formal.proofscriptparser.ast.*;
......@@ -149,7 +152,7 @@ public class MatchEvaluator extends DefaultASTVisitor<List<VariableAssignment>>
public List<VariableAssignment> visit(MatchExpression match) {
List<VariableAssignments> resultOfMatch;
//TODO transform assignments
Value pattern = (Value) eval.eval(match.getPattern());
Value pattern = eval.eval(match.getPattern());
// Value pattern = (Value) match.getPattern().accept(this);
List<VariableAssignment> va = null;
......@@ -164,8 +167,7 @@ public class MatchEvaluator extends DefaultASTVisitor<List<VariableAssignment>>
@Override
public List<VariableAssignment> visit(Variable variable) {
//get variable value
String id = variable.getIdentifier();
Value v = state.lookupVarValue(id);
Value v = state.getValue(variable);
if (v != null) {
// return v;
return null;
......
package edu.kit.formal.interpreter;
import edu.kit.formal.interpreter.data.GoalNode;
import edu.kit.formal.interpreter.data.ScriptSequent;
import edu.kit.formal.interpreter.data.VariableAssignment;
import edu.kit.formal.proofscriptparser.ast.Signature;
import java.util.List;
......@@ -8,8 +11,7 @@ import java.util.List;
* @author Alexander Weigl
* @version 1 (16.05.17)
*/
public interface MatcherApi {
List<VariableAssignment> matchLabel(GoalNode currentState, String label);
List<VariableAssignment> matchSeq(GoalNode currentState, String data, Signature sig);
public interface MatcherApi<T> {
List<VariableAssignment> matchLabel(GoalNode<T> currentState, String label);
List<VariableAssignment> matchSeq(GoalNode<T> currentState, String data, Signature sig);
}
package edu.kit.formal.interpreter;
import edu.kit.formal.interpreter.data.GoalNode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
......@@ -8,37 +14,48 @@ import java.util.List;
*
* @author S.Grebing
*/
public class State extends AbstractState {
@ToString
public class State<T> {
/**
* All goalnodes in this state
*/
private List<GoalNode> goals;
@Getter
private List<GoalNode<T>> goals;
/**
* Currently selected GoalNode
*/
private GoalNode selectedGoalNode;
@Getter
@Setter
private GoalNode<T> selectedGoalNode;
@Getter
private boolean errorState;
public State(List<GoalNode> goals, GoalNode selected) {
this.goals = goals;
public State(Collection<GoalNode<T>> goals, GoalNode selected) {
this.goals = new ArrayList<>(goals);
this.selectedGoalNode = selected;
assert selected == null || goals.contains(selected);
}
@Override
public boolean isErrorState() {
return false;
public State(List<GoalNode<T>> goals, int n) {
this(goals, goals.get(n));
}
@Override
public List<GoalNode> getGoals() {
public State(GoalNode<T> goal) {
assert goal != null;
goals = new ArrayList<>();
goals.add(goal);
setSelectedGoalNode(goal);
}
public List<GoalNode<T>> getGoals() {
return goals;
}
@Override
public GoalNode getSelectedGoalNode() {
public GoalNode<T> getSelectedGoalNode() {
if (selectedGoalNode == null) {
throw new IllegalStateException("no selected node");
} else {
......@@ -46,8 +63,8 @@ public class State extends AbstractState {
}
}
public void setSelectedGoalNode(GoalNode selectedGoalNode) {
this.selectedGoalNode = selectedGoalNode;
public void setSelectedGoalNode(GoalNode<T> gn) {
this.selectedGoalNode = gn;
}
/**
......@@ -55,11 +72,10 @@ public class State extends AbstractState {
*
* @return
*/
@Override
public State copy() {
List<GoalNode> copiedGoals = new ArrayList<>();
GoalNode refToSelGoal = selectedGoalNode;
return new State(copiedGoals, refToSelGoal);
public State<T> copy() {
List<GoalNode<T>> copiedGoals = new ArrayList<>();
GoalNode<T> refToSelGoal = selectedGoalNode;
return new State<T>(copiedGoals, refToSelGoal);
}
}
......
package edu.kit.formal.interpreter;
package edu.kit.formal.interpreter.data;
import de.uka.ilkd.key.api.ProjectedNode;
import edu.kit.formal.proofscriptparser.ast.Type;
import edu.kit.formal.proofscriptparser.ast.Variable;
import lombok.Getter;
import lombok.ToString;
/**
* Objects of this class represent a GoalNode in a script state
......@@ -10,37 +11,29 @@ import lombok.Getter;
*
* @author S.Grebing
*/
public class GoalNode {
@ToString
public class GoalNode<T> {
private VariableAssignment assignments;
@Getter
private String sequent; //TODO this is only for testing, when connected with key using projectednode
private VariableAssignment assignments;
private GoalNode<T> parent;
private GoalNode parent;
@Getter
private ProjectedNode actualKeYGoalNode;
private T data;
/**
* This conctructur will be replaced with concrete one that uses projectedNode
*
* @param parent
* @param seq
* @param data
*/
public GoalNode(GoalNode parent, String seq) {
public GoalNode(GoalNode<T> parent, T data) {
//BUG: Hier muesste deepcopy der assignments passieren
this.assignments = new VariableAssignment(parent == null ? null : parent.deepCopyAssignments());
this.parent = parent;
this.sequent = seq;
actualKeYGoalNode = null;
this.data = data;
}
public GoalNode(GoalNode parent, String seq, ProjectedNode pNode) {
this.actualKeYGoalNode = pNode;
this.assignments = new VariableAssignment(parent == null ? null : parent.deepCopyAssignments());
this.parent = parent;
this.sequent = seq;
}
private VariableAssignment deepCopyAssignments() {
return assignments.deepCopy();
}
......@@ -49,41 +42,25 @@ public class GoalNode {
return assignments;
}
public GoalNode getParent() {
return parent;
}
public String toString() {
String s = "Seq: " + sequent + "\n" +
assignments.asMap();
return s;
}
/**
* @param varname
* @return value of variable if it exists
*/
public Value lookupVarValue(String varname) {
Value v = assignments.lookupVarValue(varname);
if (v != null) {
return v;
} else {
throw new RuntimeException("Value of variable " + varname + " is not defined in goal node " + this.toString());
}
public Value getVariableValue(Variable varname) {
return assignments.getValue(varname);
}
/**
* Lookup the type of the variable in the type map
*
* @param id
* @param varname
* @return
*/
public Type lookUpType(String id) {
Type t = this.getAssignments().lookupType(id);
public Type getVariableType(Variable varname) {
Type t = this.getAssignments().getType(varname);
if (t == null) {
throw new RuntimeException("Variable " + id + " must be declared first");
throw new RuntimeException("Variable " + varname + " must be declared first");
} else {
return t;
......@@ -95,49 +72,43 @@ public class GoalNode {
* Add a variable declaration to the type map (TODO Default value in map?)
*
* @param name
* @param t
* @param type
* @throws NullPointerException
*/
public void addVarDecl(String name, Type t) {
VariableAssignment assignments = this.getAssignments().addVarDecl(name, t);
if (assignments == null) {
throw new RuntimeException("Could not add var decl " + name);
} else {
this.assignments = assignments;
}
public void declareVariable(Variable name, Type type) {
this.getAssignments().declare(name, type);
}
/**
* Set