Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
9b1230d
wip
wadoon Jul 26, 2025
fd01159
wip
wadoon Jul 26, 2025
0a61132
more further exploration
wadoon Jul 30, 2025
6abbf38
compiles again
wadoon Aug 7, 2025
68093f9
move RunAllProofsInfFlow.java
wadoon Aug 18, 2025
e098cbd
set profile in infflow files + spotless
wadoon Nov 22, 2025
df8c1e3
fixing separation issues
wadoon Nov 22, 2025
55e810b
fix proof storage, UseOperationContractRule.java
wadoon Nov 27, 2025
f2db00e
old proof was not reloadable.
wadoon Dec 30, 2025
544bf63
spotless
wadoon Dec 31, 2025
56a0c30
fix proof
wadoon Dec 31, 2025
50aa8c6
i do not understand these assertion in the test case
wadoon Dec 31, 2025
49f7abc
spotless
wadoon Dec 31, 2025
e016a27
fix services
wadoon Dec 31, 2025
675cdc7
rip out of WD intro extra module
wadoon Jan 1, 2026
7abe581
fix tests
wadoon Jan 1, 2026
e11d7f5
fix infflow tests
wadoon Jan 1, 2026
b68c97f
fix bug in WhileInvariantRule
wadoon Jan 2, 2026
b65046a
fixing justification problem
wadoon Jan 4, 2026
a590dd4
working on WD
wadoon Jan 7, 2026
55d765d
fixing InfFlowWhileInvariantRule and App
wadoon Jan 8, 2026
34fae87
IDX_GOAL_WD constant
wadoon Jan 9, 2026
20dbd68
disable functional tests in infflow
wadoon Jan 9, 2026
259d522
activate WD proofs
wadoon Jan 9, 2026
fc7ade3
formatting
wadoon Jan 9, 2026
b4158f4
loading options improvements, renaming of Profile methods
wadoon Jan 9, 2026
3cb36d8
fix ProofReplayer
wadoon Jan 10, 2026
b531ffc
fix Taclet generation
wadoon Jan 12, 2026
14362f1
using getUseDependencyContractRule in replay
wadoon Jan 12, 2026
44966c9
spotless
wadoon Jan 12, 2026
c6d74ee
fix IntermediateProofReplayer
wadoon Jan 12, 2026
2575f96
fix cost computation
wadoon Jan 12, 2026
0ed0eed
replace identify with sub-class for cost computation
wadoon Jan 12, 2026
7edf5e3
further fixes on WD profile
wadoon Jan 12, 2026
d79c330
clean-up Proof Replayer
wadoon Jan 12, 2026
d8fa7de
change Taclet base to list of RuleSource
wadoon Jan 12, 2026
3577077
externalize wd rules
wadoon Jan 12, 2026
d8f9b55
fixes #3714 -- maybe
wadoon Jan 13, 2026
0bf8ca5
Don't check VarCondNotFreeIn for TermLabelSVs
Drodt Jan 15, 2026
6c6472e
spotless
wadoon Jan 15, 2026
e4a980e
Remove pointless error logging; cast instead
Drodt Jan 15, 2026
258199b
fix naming problems
wadoon Jan 18, 2026
62f7876
spotless
wadoon Jan 18, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ jobs:
strategy:
fail-fast: false
matrix:
test: [ testProveRules, testRunAllFunProofs, testRunAllInfProofs ]
test: [ testProveRules, testRunAllFunProofs, testRunAllInfProofs, testRunAllWdProofs ]
os: [ ubuntu-latest ]
java: [ 21 ]
runs-on: ${{ matrix.os }}
Expand Down
25 changes: 25 additions & 0 deletions key.core.infflow/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@


dependencies {
api(project(":key.core"))
testImplementation(project(":key.core").sourceSets.test.output)
}


tasks.register('testRunAllInfProofs', Test) {
description = 'Prove/reload all keyfiles tagged for regression testing'
group = "verification"
filter {
includeTestsMatching "RunAllProofsInfFlow"
}
}


def rapDir = layout.buildDirectory.dir("generated-src/rap/").getOrNull()
sourceSets.test.java.srcDirs(rapDir)

tasks.register('generateRAPUnitTests', JavaExec) {
classpath = sourceSets.test.runtimeClasspath
mainClass.set("de.uka.ilkd.key.informationflow.GenerateUnitTests")
args(rapDir)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* 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;

import java.util.List;

import de.uka.ilkd.key.informationflow.proof.InfFlowProof;
import de.uka.ilkd.key.informationflow.proof.SideProofStatistics;
import de.uka.ilkd.key.proof.Node;
import de.uka.ilkd.key.proof.Proof;
import de.uka.ilkd.key.proof.Statistics;

import org.jspecify.annotations.NullMarked;

/**
* @author Alexander Weigl
* @version 1 (8/3/25)
*/
@NullMarked
public class InfFlowStatistics extends Statistics {
private boolean sideProofs;
private Statistics stat;

protected InfFlowStatistics(int nodes, int branches, int cachedBranches, int interactiveSteps,
int symbExApps, int quantifierInstantiations, int ossApps, int mergeRuleApps,
int totalRuleApps, int smtSolverApps, int dependencyContractApps,
int operationContractApps, int blockLoopContractApps, int loopInvApps,
long autoModeTimeInMillis, long timeInMillis, float timePerStepInMillis) {
super(nodes, branches, cachedBranches, interactiveSteps, symbExApps,
quantifierInstantiations, ossApps, mergeRuleApps, totalRuleApps, smtSolverApps,
dependencyContractApps, operationContractApps, blockLoopContractApps, loopInvApps,
autoModeTimeInMillis, timeInMillis, timePerStepInMillis);
}

public InfFlowStatistics(List<Node> startNodes) {
super(startNodes);
}

@Override
protected void generateSummary(Proof proof) {
super.generateSummary(proof);
if (proof instanceof InfFlowProof ifp) { // TODO: get rid of that instanceof by subclassing
generateSummary(ifp);
}
}

protected void generateSummary(InfFlowProof proof) {
sideProofs = proof.hasSideProofs();
if (sideProofs) {
final long autoTime = proof.getAutoModeTime()
+ proof.getSideProofStatistics().autoModeTimeInMillis;
final SideProofStatistics side = proof.getSideProofStatistics()
.add(this).setAutoModeTime(autoTime);
stat = create(side, proof.getCreationTime());
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* 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;

import de.uka.ilkd.key.informationflow.ProofObligationVars;
import de.uka.ilkd.key.informationflow.proof.InfFlowCheckInfo;
import de.uka.ilkd.key.informationflow.proof.InfFlowProof;
import de.uka.ilkd.key.informationflow.proof.init.StateVars;
import de.uka.ilkd.key.informationflow.rule.tacletbuilder.InfFlowMethodContractTacletBuilder;
import de.uka.ilkd.key.logic.JTerm;
import de.uka.ilkd.key.proof.Goal;
import de.uka.ilkd.key.proof.rules.ComplexJustificationable;
import de.uka.ilkd.key.rule.Taclet;
import de.uka.ilkd.key.rule.UseOperationContractRule;
import de.uka.ilkd.key.rule.inst.SVInstantiations;

import org.key_project.logic.Name;
import org.key_project.prover.rules.RuleApp;
import org.key_project.prover.sequent.SequentFormula;
import org.key_project.util.collection.ImmutableList;

import org.jspecify.annotations.NullMarked;

/**
* @author Alexander Weigl
* @version 1 (8/3/25)
*/
@NullMarked
public class InfFlowUseOperationContractRule extends UseOperationContractRule
implements ComplexJustificationable {
private static final Name NAME = new Name("InfFlow Use Operation Contract");

public static InfFlowUseOperationContractRule INSTANCE = new InfFlowUseOperationContractRule();

protected InfFlowUseOperationContractRule() {
}

@Override
public Name name() {
return NAME;
}

@Override
public ImmutableList<Goal> apply(Goal goal, RuleApp ruleApp) {
return new InfFlowUseOperationContractRuleApplier(goal, ruleApp).apply();
}

protected static class InfFlowUseOperationContractRuleApplier
extends UseOperationContractRuleApplier {
protected InfFlowUseOperationContractRuleApplier(Goal goal, RuleApp ruleApp) {
super(goal, ruleApp);
}

@Override
protected JTerm getFinalPreTerm() {
// termination has already been shown in the functional proof,
// thus we do not need to show it again in information flow proofs.
return tb.applySequential(new JTerm[] { inst.u(), atPreUpdates },
tb.and(new JTerm[] { pre, reachableState }));
}

private void applyInfFlow(Goal goal) {
if (!InfFlowCheckInfo.isInfFlow(goal)) {
return;
}

var exception = tb.var(excVar);

// prepare information flow analysis
assert anonUpdateDatas.size() == 1
: "information flow extension " + "is at the moment not "
+ "compatible with the " + "non-base-heap setting";
AnonUpdateData anonUpdateData = anonUpdateDatas.head();

final JTerm heapAtPre = anonUpdateData.methodHeapAtPre();
final JTerm heapAtPost = anonUpdateData.methodHeap();

// generate proof obligation variables
final boolean hasSelf = contractSelf != null;
final boolean hasRes = contractResult != null;
final boolean hasExc = exception != null;

final StateVars preVars = new StateVars(hasSelf ? contractSelf : null, contractParams,
hasRes ? contractResult : null, hasExc ? exception : null, heapAtPre, mby);
final StateVars postVars = new StateVars(hasSelf ? contractSelf : null, contractParams,
hasRes ? contractResult : null, hasExc ? exception : null, heapAtPost, mby);
final ProofObligationVars poVars = new ProofObligationVars(preVars, postVars, services);

// generate information flow contract application predicate
// and associated taclet
InfFlowMethodContractTacletBuilder ifContractBuilder =
new InfFlowMethodContractTacletBuilder(services);
ifContractBuilder.setContract(contract);
ifContractBuilder.setContextUpdate(atPreUpdates, inst.u());
ifContractBuilder.setProofObligationVars(poVars);

JTerm contractApplPredTerm = ifContractBuilder.buildContractApplPredTerm();
Taclet informationFlowContractApp = ifContractBuilder.buildTaclet(goal);

// add term and taclet to post goal
goal.addFormula(new SequentFormula(contractApplPredTerm), true, false);
goal.addTaclet(informationFlowContractApp, SVInstantiations.EMPTY_SVINSTANTIATIONS,
true);

// information flow proofs might get easier if we add the (proved)
// method contract precondition as an assumption to the post goal
// (in case the precondition cannot be proved easily)
goal.addFormula(new SequentFormula(finalPreTerm), true, false);
final InfFlowProof proof = (InfFlowProof) goal.proof();
proof.addIFSymbol(contractApplPredTerm);
proof.addIFSymbol(informationFlowContractApp);
proof.addGoalTemplates(informationFlowContractApp);
}


@Override
protected void createPostGoal(Goal postGoal) {
super.createPostGoal(postGoal);
applyInfFlow(postGoal);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
/* 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.strategy.feature;
package de.uka.ilkd.key.informationflow;

import de.uka.ilkd.key.informationflow.rule.executor.InfFlowContractAppTacletExecutor;
import de.uka.ilkd.key.logic.DefaultVisitor;
import de.uka.ilkd.key.logic.JTerm;
import de.uka.ilkd.key.logic.equality.RenamingTermProperty;
import de.uka.ilkd.key.rule.TacletApp;

import org.key_project.logic.Term;
Expand All @@ -21,7 +22,6 @@

import org.jspecify.annotations.NonNull;

import static de.uka.ilkd.key.logic.equality.RenamingTermProperty.RENAMING_TERM_PROPERTY;


/**
Expand Down Expand Up @@ -90,7 +90,8 @@ public SubFormulaVisitor(Term potentialSub) {

@Override
public void visit(Term visited) {
isSubFormula |= RENAMING_TERM_PROPERTY.equalsModThisProperty(visited, potentialSub);
isSubFormula |= RenamingTermProperty.RENAMING_TERM_PROPERTY
.equalsModThisProperty(visited, potentialSub);
}


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* 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.strategy.feature;
package de.uka.ilkd.key.informationflow;

import java.util.ArrayList;
import java.util.Iterator;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* 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.informationflow;

import de.uka.ilkd.key.proof.init.DefaultProfileResolver;
import de.uka.ilkd.key.proof.init.Profile;

public class InfFlowProfileResolver implements DefaultProfileResolver {
@Override
public String getProfileName() {
return JavaInfFlowProfile.PROFILE_ID;
}

@Override
public Profile getDefaultProfile() {
return new JavaInfFlowProfile();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* 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.informationflow;

import de.uka.ilkd.key.InfFlowUseOperationContractRule;
import de.uka.ilkd.key.informationflow.rule.InfFlowBlockContractInternalRule;
import de.uka.ilkd.key.informationflow.rule.InfFlowWhileInvariantRule;
import de.uka.ilkd.key.proof.init.JavaProfile;
import de.uka.ilkd.key.rule.*;

import org.key_project.util.collection.ImmutableList;

/**
* This profile sets up KeY for verification of JavaCard programs.
*/
public class JavaInfFlowProfile extends JavaProfile {
public static final String NAME = "Java InfFlow Profile";
public static final String PROFILE_ID = "java-infflow";

@Override
public String ident() {
return PROFILE_ID;
}

@Override
public String displayName() {
return NAME;
}

@Override
public String description() {
return "Profile with Built-In rules for Information Flow proofs. " +
"Required for 'non-inference' proof obligations.";
}

@Override
public UseOperationContractRule getUseOperationContractRule() {
return InfFlowUseOperationContractRule.INSTANCE;
}

@Override
protected ImmutableList<BuiltInRule> initBuiltInRules() {
var rules = super.initBuiltInRules();
return rules.map(it -> {
if (it == BlockContractInternalRule.INSTANCE) {
return InfFlowBlockContractInternalRule.INSTANCE;
}
if (it instanceof UseOperationContractRule) {
return InfFlowUseOperationContractRule.INSTANCE;
}
if (it instanceof WhileInvariantRule) {
return InfFlowWhileInvariantRule.INSTANCE;
}

return it;
})
.filter(it -> it != BlockContractExternalRule.INSTANCE)
.filter(it -> !(it instanceof LoopScopeInvariantRule))
.filter(it -> !(it instanceof LoopContractExternalRule));
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* 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.init;
package de.uka.ilkd.key.informationflow;

import de.uka.ilkd.key.informationflow.proof.init.StateVars;
import de.uka.ilkd.key.java.JavaInfo;
Expand All @@ -20,6 +20,8 @@
import org.key_project.util.collection.ImmutableList;
import org.key_project.util.collection.ImmutableSLList;

import org.jspecify.annotations.Nullable;


/**
*
Expand Down Expand Up @@ -76,7 +78,7 @@ public ProofObligationVars(StateVars pre, StateVars post, JTerm exceptionParamet
}

public ProofObligationVars(StateVars pre, StateVars post, JTerm exceptionParameter,
ImmutableList<JTerm> formalParams, TermBuilder tb) {
@Nullable ImmutableList<JTerm> formalParams, TermBuilder tb) {
this.pre = pre;
this.post = post;
this.exceptionParameter = exceptionParameter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* 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.speclang;
package de.uka.ilkd.key.informationflow.impl;

import java.util.Iterator;
import java.util.List;
Expand All @@ -21,6 +21,9 @@
import de.uka.ilkd.key.proof.init.ContractPO;
import de.uka.ilkd.key.proof.init.InitConfig;
import de.uka.ilkd.key.proof.init.ProofOblInput;
import de.uka.ilkd.key.speclang.Contract;
import de.uka.ilkd.key.speclang.ContractFactory;
import de.uka.ilkd.key.speclang.infflow.InformationFlowContract;
import de.uka.ilkd.key.util.InfFlowSpec;

import org.key_project.util.collection.ImmutableList;
Expand Down
Loading
Loading