From 87e30af82cabc9f320ba46b276290e6eb2f61678 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 29 Aug 2024 16:27:41 +0200 Subject: [PATCH 01/40] added new flag --only-svcomp-witness --- build.gradle.kts | 2 +- .../main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 2 +- .../java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 741094252d..e029ef4eda 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.5.1" + version = "6.5.2" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index d54865638a..9469c2eca3 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -316,7 +316,7 @@ private fun postVerificationLogging( } if (!config.outputConfig.witnessConfig.disable) { - if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex != null) { + if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex != null && !config.outputConfig.witnessConfig.svcomp) { val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, getSolver( diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt index ef50a1e108..a52a05c957 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt @@ -347,11 +347,12 @@ data class OutputConfig( ) : Config { override fun getObjects(): Set { - return super.getObjects() union cOutputConfig.getObjects() union xcfaOutputConfig.getObjects() union witnessConfig.getObjects() union argConfig.getObjects() + return super.getObjects() union cOutputConfig.getObjects() union xcfaOutputConfig.getObjects() union chcOutputConfig.getObjects() union witnessConfig.getObjects() union argConfig.getObjects() } override fun update(): Boolean = - listOf(cOutputConfig, xcfaOutputConfig, witnessConfig, argConfig).map { it.update() }.any { it } + listOf(cOutputConfig, xcfaOutputConfig, chcOutputConfig, witnessConfig, argConfig).map { it.update() } + .any { it } } data class XcfaOutputConfig( @@ -382,6 +383,9 @@ data class WitnessConfig( @Parameter(names = ["--disable-witness-generation"]) var disable: Boolean = false, + @Parameter(names = ["--only-svcomp-witness"]) + var svcomp: Boolean = false, + @Parameter(names = ["--cex-solver"], description = "Concretizer solver name") var concretizerSolver: String = "Z3", From dcb153908f86eb70750a1f5e0418f9af7b2b6ca1 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 3 Oct 2024 11:13:44 +0200 Subject: [PATCH 02/40] smallestCommonType now supports void --- .../frontend/transformation/model/types/complex/CVoid.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CVoid.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CVoid.java index 4d9d121d1e..353ca2cc9a 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CVoid.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CVoid.java @@ -29,6 +29,11 @@ public R accept(CComplexTypeVisitor visitor, T param) { return visitor.visit(this, param); } + @Override + public CComplexType getSmallestCommonType(CComplexType type) { + return type; + } + @Override public String getTypeName() { return "void"; From 244eb924efdddb48e89d6fc197dff4057ab24663 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 3 Oct 2024 12:01:15 +0200 Subject: [PATCH 03/40] Fixed struct and pointer dereferencing --- .../grammar/type/TypeVisitor.java | 31 ++++++------------- .../model/declaration/CDeclaration.java | 4 ++- .../model/types/simple/Struct.java | 21 ++++++++++--- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 4 ++- 4 files changed, 31 insertions(+), 29 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java index 83acdef4b6..5fbaf45690 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java @@ -28,32 +28,15 @@ import hu.bme.mit.theta.frontend.transformation.grammar.preprocess.TypedefVisitor; import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; -import hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleType; -import hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory; -import hu.bme.mit.theta.frontend.transformation.model.types.simple.DeclaredName; import hu.bme.mit.theta.frontend.transformation.model.types.simple.Enum; -import hu.bme.mit.theta.frontend.transformation.model.types.simple.NamedType; -import hu.bme.mit.theta.frontend.transformation.model.types.simple.Struct; +import hu.bme.mit.theta.frontend.transformation.model.types.simple.*; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.ParseTree; -import java.util.ArrayList; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Atomic; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.DeclaredName; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Enum; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Extern; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.NamedType; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Signed; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.ThreadLocal; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Typedef; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Unsigned; -import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.Volatile; +import static hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleTypeFactory.*; public class TypeVisitor extends CBaseVisitor { private final DeclarationVisitor declarationVisitor; @@ -245,13 +228,17 @@ public CSimpleType visitCompoundDefinition(CParser.CompoundDefinitionContext ctx CParser.SpecifierQualifierListContext specifierQualifierListContext = structDeclarationContext.specifierQualifierList(); CSimpleType cSimpleType = specifierQualifierListContext.accept(this); if (structDeclarationContext.structDeclaratorList() == null) { - struct.addField(cSimpleType.getAssociatedName(), cSimpleType); + final var decl = new CDeclaration(cSimpleType); + struct.addField(decl); } else { for (CParser.StructDeclaratorContext structDeclaratorContext : structDeclarationContext.structDeclaratorList() .structDeclarator()) { CDeclaration declaration = structDeclaratorContext.accept( declarationVisitor); - struct.addField(declaration.getName(), cSimpleType); + if (declaration.getType() == null) { + declaration.setType(cSimpleType); + } + struct.addField(declaration); } } } diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/declaration/CDeclaration.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/declaration/CDeclaration.java index 7c8ce9b585..7242590d40 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/declaration/CDeclaration.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/declaration/CDeclaration.java @@ -25,6 +25,8 @@ import java.util.ArrayList; import java.util.List; +import static com.google.common.base.Preconditions.checkNotNull; + public class CDeclaration { private CSimpleType type; @@ -37,7 +39,7 @@ public class CDeclaration { private CStatement initExpr; public CDeclaration(CSimpleType cSimpleType) { - this.name = null; + this.name = checkNotNull(cSimpleType).getAssociatedName(); this.type = cSimpleType; this.derefCounter = cSimpleType.getPointerLevel(); this.varDecls = new ArrayList<>(); diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/Struct.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/Struct.java index eb3d8ad12f..a7b55db04d 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/Struct.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/Struct.java @@ -20,7 +20,9 @@ import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; +import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CStruct; import java.util.ArrayList; @@ -28,9 +30,11 @@ import java.util.List; import java.util.Map; +import static com.google.common.base.Preconditions.checkNotNull; + public class Struct extends NamedType { - private final Map fields; + private final Map fields; private final String name; private final Logger uniqueWarningLogger; @@ -52,8 +56,8 @@ public static Struct getByName(String name) { currentlyBeingBuilt = false; } - public void addField(String name, CSimpleType type) { - fields.put(name, type); + public void addField(CDeclaration decl) { + fields.put(checkNotNull(decl.getName()), checkNotNull(decl)); } @Override @@ -64,9 +68,16 @@ public CComplexType getActualType() { } currentlyBeingBuilt = true; List> actualFields = new ArrayList<>(); - fields.forEach((s, cSimpleType) -> actualFields.add(Tuple2.of(s, cSimpleType.getActualType()))); + fields.forEach((s, cDeclaration) -> actualFields.add(Tuple2.of(s, cDeclaration.getActualType()))); currentlyBeingBuilt = false; - return new CStruct(this, actualFields, parseContext); + + CComplexType type = new CStruct(this, actualFields, parseContext); + + for (int i = 0; i < getPointerLevel(); i++) { + type = new CPointer(this, type, parseContext); + } + + return type; } @Override diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index 6dccaaa36c..7bd0113897 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -94,7 +94,9 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo continue } if (type is CStruct) { - error("Not handling init expression of struct array ${globalDeclaration.get1()}") + uniqueWarningLogger.write( + Logger.Level.INFO, "Not handling init expression of struct array ${globalDeclaration.get1()}" + ) } builder.addVar(XcfaGlobalVar(globalDeclaration.get2(), type.nullValue)) if (type is CArray) { From 6279916cf8796dd332490176a5a61ea4832c76ef Mon Sep 17 00:00:00 2001 From: Bajczi Levente Date: Wed, 16 Oct 2024 12:05:34 +0200 Subject: [PATCH 04/40] Added svg logo --- doc/theta-logo.svg | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 doc/theta-logo.svg diff --git a/doc/theta-logo.svg b/doc/theta-logo.svg new file mode 100644 index 0000000000..8705b0a3b4 --- /dev/null +++ b/doc/theta-logo.svg @@ -0,0 +1,50 @@ + + + + + + + + + + + From 991b764492bd3e65c9a379d9b141cde2525ed0d5 Mon Sep 17 00:00:00 2001 From: Bajczi Levente Date: Wed, 16 Oct 2024 12:08:44 +0200 Subject: [PATCH 05/40] Update README.md to point to svg instead of png --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80e602f755..7044ff4049 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ [![Check formatting](https://github.com/ftsrg/theta/actions/workflows/check-formatting.yml/badge.svg)](https://github.com/ftsrg/theta/actions/workflows/check-formatting.yml) [![Apache 2.0 License](https://img.shields.io/badge/license-Apache--2-brightgreen.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) -![Theta logo](https://raw.githubusercontent.com/ftsrg/theta/master/doc/theta-logo.png) +Theta logo ## About From c24de492baad29f0ad4b54fc38a2c79ccfe7e868 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 17 Oct 2024 11:21:59 +0200 Subject: [PATCH 06/40] Instead of FrontendFailure, throw UnsupportedElement --- .../UnsupportedFrontendElementException.java | 23 +++++++++ .../grammar/expression/ExpressionVisitor.java | 48 +++++-------------- .../expression/UnsupportedInitializer.java | 3 +- .../grammar/type/DeclarationVisitor.java | 9 ++-- .../grammar/type/TypeVisitor.java | 17 +++---- .../model/statements/CAssignment.java | 3 +- .../model/statements/CInitializerList.java | 3 +- .../model/statements/CStatement.java | 7 +-- .../model/types/complex/CComplexType.java | 22 +++------ .../model/types/complex/integer/Fitsall.java | 2 +- .../visitors/bitvector/CastVisitor.java | 5 +- .../model/types/simple/NamedType.java | 3 +- .../mit/theta/xcfa/cli/params/ExitCodes.kt | 5 ++ 13 files changed, 76 insertions(+), 74 deletions(-) create mode 100644 subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/UnsupportedFrontendElementException.java diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/UnsupportedFrontendElementException.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/UnsupportedFrontendElementException.java new file mode 100644 index 0000000000..e3bef460e0 --- /dev/null +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/UnsupportedFrontendElementException.java @@ -0,0 +1,23 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.frontend; + +public class UnsupportedFrontendElementException extends RuntimeException { + public UnsupportedFrontendElementException(String message) { + super(message); + } +} diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java index 60a7ff7609..d714b8693a 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java @@ -18,13 +18,7 @@ import hu.bme.mit.theta.c.frontend.dsl.gen.CBaseVisitor; import hu.bme.mit.theta.c.frontend.dsl.gen.CParser; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionAccessContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionBracesContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionBracketsContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionDecrementContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionIncrementContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionMemberAccessContext; -import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.PostfixExpressionPtrMemberAccessContext; +import hu.bme.mit.theta.c.frontend.dsl.gen.CParser.*; import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; @@ -35,33 +29,22 @@ import hu.bme.mit.theta.core.type.abstracttype.AbstractExprs; import hu.bme.mit.theta.core.type.abstracttype.DivExpr; import hu.bme.mit.theta.core.type.abstracttype.ModExpr; -import hu.bme.mit.theta.core.type.anytype.Dereference; -import hu.bme.mit.theta.core.type.anytype.Exprs; -import hu.bme.mit.theta.core.type.anytype.IteExpr; -import hu.bme.mit.theta.core.type.anytype.RefExpr; -import hu.bme.mit.theta.core.type.anytype.Reference; +import hu.bme.mit.theta.core.type.anytype.*; import hu.bme.mit.theta.core.type.booltype.BoolExprs; import hu.bme.mit.theta.core.type.booltype.BoolType; -import hu.bme.mit.theta.core.type.bvtype.BvAndExpr; -import hu.bme.mit.theta.core.type.bvtype.BvExprs; -import hu.bme.mit.theta.core.type.bvtype.BvOrExpr; -import hu.bme.mit.theta.core.type.bvtype.BvType; -import hu.bme.mit.theta.core.type.bvtype.BvXorExpr; +import hu.bme.mit.theta.core.type.bvtype.*; import hu.bme.mit.theta.core.type.fptype.FpLitExpr; import hu.bme.mit.theta.core.type.inttype.IntType; import hu.bme.mit.theta.core.utils.BvUtils; import hu.bme.mit.theta.core.utils.FpUtils; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.ArchitectureConfig; import hu.bme.mit.theta.frontend.transformation.grammar.function.FunctionVisitor; import hu.bme.mit.theta.frontend.transformation.grammar.preprocess.TypedefVisitor; import hu.bme.mit.theta.frontend.transformation.grammar.type.TypeVisitor; import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; -import hu.bme.mit.theta.frontend.transformation.model.statements.CAssignment; -import hu.bme.mit.theta.frontend.transformation.model.statements.CCall; -import hu.bme.mit.theta.frontend.transformation.model.statements.CCompound; -import hu.bme.mit.theta.frontend.transformation.model.statements.CExpr; -import hu.bme.mit.theta.frontend.transformation.model.statements.CStatement; +import hu.bme.mit.theta.frontend.transformation.model.statements.*; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CArray; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; @@ -70,23 +53,14 @@ import org.kframework.mpfr.BinaryMathContext; import java.math.BigInteger; -import java.util.ArrayList; -import java.util.Deque; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Add; import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Div; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Eq; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Geq; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Ite; import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Mod; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Neq; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Sub; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.*; import static hu.bme.mit.theta.core.type.anytype.Exprs.Reference; import static hu.bme.mit.theta.core.type.fptype.FpExprs.FpType; import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; @@ -310,7 +284,7 @@ public Expr visitRelationalExpression(CParser.RelationalExpressionContext ctx guard = AbstractExprs.Geq(leftExpr, rightExpr); break; default: - throw new IllegalStateException("Unexpected value: " + ctx.signs.get(i).getText()); + throw new UnsupportedFrontendElementException("Unexpected relational expression sign: " + ctx.signs.get(i).getText()); } // MaxEnumAnalyzer.instance.consume(guard); TODO: handle circular dependency CComplexType signedInt = CComplexType.getSignedInt(parseContext); @@ -415,7 +389,7 @@ public Expr visitMultiplicativeExpression(CParser.MultiplicativeExpressionCon } break; default: - throw new IllegalStateException("Unexpected value: " + ctx.signs.get(i).getText()); + throw new UnsupportedFrontendElementException("Unexpected multiplicative expression sign: " + ctx.signs.get(i).getText()); } parseContext.getMetadata().create(expr, "cType", smallestCommonType); expr = smallestCommonType.castTo(expr); @@ -665,9 +639,9 @@ public Expr visitPrimaryExpressionConstant(CParser.PrimaryExpressionConstantC BigFloat bigFloat; if (text.startsWith("0x")) { - throw new UnsupportedOperationException("Hexadecimal FP constants are not yet supported!"); + throw new UnsupportedFrontendElementException("Hexadecimal FP constants are not yet supported!"); } else if (text.startsWith("0b")) { - throw new UnsupportedOperationException("Binary FP constants are not yet supported!"); + throw new UnsupportedFrontendElementException("Binary FP constants are not yet supported!"); } else { bigFloat = new BigFloat(text, new BinaryMathContext(significand - 1, exponent)); } diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/UnsupportedInitializer.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/UnsupportedInitializer.java index 121f0a9bba..b11b230c07 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/UnsupportedInitializer.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/UnsupportedInitializer.java @@ -20,6 +20,7 @@ import hu.bme.mit.theta.core.type.LitExpr; import hu.bme.mit.theta.core.type.NullaryExpr; import hu.bme.mit.theta.core.type.inttype.IntType; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; @@ -32,7 +33,7 @@ public IntType getType() { @Override public LitExpr eval(Valuation val) { - throw new UnsupportedOperationException("UnsupportedInitializer expressions are not supported."); + throw new UnsupportedFrontendElementException("UnsupportedInitializer expressions are not supported."); } @Override diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/DeclarationVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/DeclarationVisitor.java index f752eb7ef8..84be79414d 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/DeclarationVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/DeclarationVisitor.java @@ -22,6 +22,7 @@ import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.grammar.expression.UnsupportedInitializer; import hu.bme.mit.theta.frontend.transformation.grammar.function.FunctionVisitor; import hu.bme.mit.theta.frontend.transformation.grammar.preprocess.TypedefVisitor; @@ -140,7 +141,7 @@ public CDeclaration visitStructDeclaratorSimple(CParser.StructDeclaratorSimpleCo @Override public CDeclaration visitStructDeclaratorConstant(CParser.StructDeclaratorConstantContext ctx) { - throw new UnsupportedOperationException("Not yet supported!"); + throw new UnsupportedFrontendElementException("Not yet supported!"); } @Override @@ -191,17 +192,17 @@ public CDeclaration visitDirectDeclaratorArray1(CParser.DirectDeclaratorArray1Co @Override public CDeclaration visitDirectDeclaratorArray2(CParser.DirectDeclaratorArray2Context ctx) { - throw new UnsupportedOperationException("Not yet implemented!"); + throw new UnsupportedFrontendElementException("Not yet implemented!"); } @Override public CDeclaration visitDirectDeclaratorArray3(CParser.DirectDeclaratorArray3Context ctx) { - throw new UnsupportedOperationException("Not yet implemented!"); + throw new UnsupportedFrontendElementException("Not yet implemented!"); } @Override public CDeclaration visitDirectDeclaratorArray4(CParser.DirectDeclaratorArray4Context ctx) { - throw new UnsupportedOperationException("Not yet implemented!"); + throw new UnsupportedFrontendElementException("Not yet implemented!"); } @Override diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java index 5fbaf45690..8fad36f961 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/type/TypeVisitor.java @@ -25,6 +25,7 @@ import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.grammar.preprocess.TypedefVisitor; import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; @@ -194,15 +195,15 @@ public CSimpleType visitStorageClassSpecifier(CParser.StorageClassSpecifierConte case "auto": case "register": case "_Thread_local": - throw new UnsupportedOperationException("Not yet implemented"); + throw new UnsupportedFrontendElementException("Not yet implemented (" + ctx.getText() + ")"); } - throw new UnsupportedOperationException( + throw new UnsupportedFrontendElementException( "Storage class specifier not expected: " + ctx.getText()); } @Override public CSimpleType visitTypeSpecifierAtomic(CParser.TypeSpecifierAtomicContext ctx) { - throw new UnsupportedOperationException("Not yet implemented"); + throw new UnsupportedFrontendElementException("Not yet implemented"); } @Override @@ -212,7 +213,7 @@ public CSimpleType visitTypeSpecifierCompound(CParser.TypeSpecifierCompoundConte @Override public CSimpleType visitTypeSpecifierFunctionPointer(CParser.TypeSpecifierFunctionPointerContext ctx) { - throw new UnsupportedOperationException("Function pointers not yet implemented"); + throw new UnsupportedFrontendElementException("Function pointers not yet implemented"); } @Override @@ -285,7 +286,7 @@ public CSimpleType visitEnumUsage(CParser.EnumUsageContext ctx) { @Override public CSimpleType visitTypeSpecifierExtension(CParser.TypeSpecifierExtensionContext ctx) { - throw new UnsupportedOperationException("Not yet implemented"); + throw new UnsupportedFrontendElementException("Not yet implemented typeSpecifierExtension"); } @Override @@ -348,7 +349,7 @@ public CSimpleType visitTypeSpecifierTypedefName(CParser.TypeSpecifierTypedefNam @Override public CSimpleType visitTypeSpecifierTypeof(CParser.TypeSpecifierTypeofContext ctx) { - throw new UnsupportedOperationException("Not yet implemented"); + throw new UnsupportedFrontendElementException("Not yet implemented typeSpecifierTypeof"); } @Override @@ -357,13 +358,13 @@ public CSimpleType visitTypeQualifier(CParser.TypeQualifierContext ctx) { case "const": return null; case "restrict": - throw new UnsupportedOperationException("Not yet implemented!"); + throw new UnsupportedFrontendElementException("Not yet implemented 'restrict'!"); case "volatile": return Volatile(); case "_Atomic": return Atomic(); } - throw new UnsupportedOperationException( + throw new UnsupportedFrontendElementException( "Type qualifier " + ctx.getText() + " not expected!"); } diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CAssignment.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CAssignment.java index 748b919252..8d285f2d04 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CAssignment.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CAssignment.java @@ -21,6 +21,7 @@ import hu.bme.mit.theta.core.type.bvtype.BvExprs; import hu.bme.mit.theta.core.type.bvtype.BvType; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import java.util.List; @@ -99,7 +100,7 @@ public Expr getrExpression() { ret = BvExprs.Or(List.of((Expr) type.castTo(lValue), (Expr) type.castTo(rExpression))); break; default: - throw new RuntimeException("Bad operator: " + operator); + throw new UnsupportedFrontendElementException("Unsupported operator: " + operator); } parseContext.getMetadata().create(ret, "cType", CComplexType.getType(lValue, parseContext)); ret = CComplexType.getType(lValue, parseContext).castTo(ret); diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CInitializerList.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CInitializerList.java index 4d7670b096..d12151fe4b 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CInitializerList.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CInitializerList.java @@ -19,6 +19,7 @@ import hu.bme.mit.theta.common.Tuple2; import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import java.util.ArrayList; @@ -38,7 +39,7 @@ public CInitializerList(CComplexType type, ParseContext parseContext) { @Override public Expr getExpression() { - throw new UnsupportedOperationException("Cannot create expression of initializer list."); + throw new UnsupportedFrontendElementException("Cannot create expression of initializer list."); } @Override diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java index 44f8087a79..93a2199239 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/statements/CStatement.java @@ -18,6 +18,7 @@ import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; /** * Every Program, Function and Statement is a subclass of this base class. @@ -60,7 +61,7 @@ public void setId(String id) { * @return The expression associated with the statement. */ public Expr getExpression() { - throw new RuntimeException("Cannot get expression!"); + throw new UnsupportedFrontendElementException("Cannot get expression!"); } public CStatement getPostStatements() { @@ -68,7 +69,7 @@ public CStatement getPostStatements() { } public void setPostStatements(CStatement postStatements) { - throw new UnsupportedOperationException("Only CCompounds shall currently have pre- and post statements!"); + throw new UnsupportedFrontendElementException("Only CCompounds shall currently have pre- and post statements!"); } public CStatement getPreStatements() { @@ -76,7 +77,7 @@ public CStatement getPreStatements() { } public void setPreStatements(CStatement preStatements) { - throw new UnsupportedOperationException("Only CCompounds shall currently have pre- and post statements!"); + throw new UnsupportedFrontendElementException("Only CCompounds shall currently have pre- and post statements!"); } public abstract R accept(CStatementVisitor visitor, P param); diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CComplexType.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CComplexType.java index 32b8c4b0e4..1f54441d28 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CComplexType.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/CComplexType.java @@ -26,11 +26,8 @@ import hu.bme.mit.theta.core.type.fptype.FpType; import hu.bme.mit.theta.core.type.inttype.IntType; import hu.bme.mit.theta.frontend.ParseContext; -import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CArray; -import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CCompound; -import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CFunction; -import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; -import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CStruct; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; +import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.*; import hu.bme.mit.theta.frontend.transformation.model.types.complex.integer.CInteger; import hu.bme.mit.theta.frontend.transformation.model.types.complex.integer.Fitsall; import hu.bme.mit.theta.frontend.transformation.model.types.complex.integer.c128.C128; @@ -62,12 +59,7 @@ import java.util.Map.Entry; import java.util.Optional; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getCastVisitor; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getLimitVisitor; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getNullValueVisitor; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getTypeVisitor; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getUnitValueVisitor; -import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.getValueVisitor; +import static hu.bme.mit.theta.frontend.transformation.ArchitectureConfig.*; public abstract class CComplexType { private final CSimpleType origin; @@ -208,7 +200,7 @@ private static CComplexType getType(Type type, ParseContext parseContext) { if (longDoubleType.equals(type)) { return new CFloat(null, parseContext); } - throw new RuntimeException("No suitable size found for type: " + type); + throw new UnsupportedFrontendElementException("No suitable size found for type: " + type); } else if (type instanceof BvType) { for (Entry entry : parseContext.getArchitecture().standardTypeSizes.entrySet()) { String s = entry.getKey(); @@ -230,9 +222,9 @@ private static CComplexType getType(Type type, ParseContext parseContext) { } } } - throw new RuntimeException("No suitable width found for type: " + type); + throw new UnsupportedFrontendElementException("No suitable width found for type: " + type); } else { - throw new RuntimeException("Not yet implemented for type: " + type); + throw new UnsupportedFrontendElementException("Not yet implemented for type: " + type); } } @@ -307,7 +299,7 @@ public R accept(CComplexTypeVisitor visitor, T param) { public static class CComplexTypeVisitor { public R visit(CComplexType type, T param) { - throw new UnsupportedOperationException("Not (yet) implemented (" + type.getClass().getSimpleName() + " in " + this.getClass().getName() + ")"); + throw new UnsupportedFrontendElementException("Not (yet) implemented (" + type.getClass().getSimpleName() + " in " + this.getClass().getName() + ")"); } public R visit(CVoid type, T param) { diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/integer/Fitsall.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/integer/Fitsall.java index 6550e48040..8cb56130a7 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/integer/Fitsall.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/integer/Fitsall.java @@ -41,7 +41,7 @@ public String getTypeName() { @Override public CInteger getSignedVersion() { - throw new RuntimeException("Bool does not have a signed version!"); + throw new RuntimeException("Fitsall does not have a signed version!"); } @Override diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/visitors/bitvector/CastVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/visitors/bitvector/CastVisitor.java index ab2fd3faa7..6187ff3391 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/visitors/bitvector/CastVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/complex/visitors/bitvector/CastVisitor.java @@ -25,6 +25,7 @@ import hu.bme.mit.theta.core.type.fptype.FpRoundingMode; import hu.bme.mit.theta.core.type.fptype.FpType; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CVoid; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; @@ -89,7 +90,7 @@ private Expr handleSignedConversion(CInteger type, Expr param } } } else { - throw new IllegalStateException("Compound types are not directly supported!"); + throw new UnsupportedFrontendElementException("Compound types are not directly supported!"); } } @@ -119,7 +120,7 @@ private Expr handleUnsignedConversion(CInteger type, Expr par } } } else { - throw new IllegalStateException("Compound types are not directly supported!"); + throw new UnsupportedFrontendElementException("Compound types are not directly supported!"); } } diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/NamedType.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/NamedType.java index 2cbc83220d..2ff2c5fdb0 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/NamedType.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/model/types/simple/NamedType.java @@ -19,6 +19,7 @@ import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.frontend.ParseContext; +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CVoid; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; @@ -169,7 +170,7 @@ protected void patch(CSimpleType cSimpleType) { break; default: if (!cSimpleType.isTypedef()) { - throw new RuntimeException( + throw new UnsupportedFrontendElementException( "namedType should be short or long or type specifier, instead it is " + namedType); } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ExitCodes.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ExitCodes.kt index 563a7abaa3..1ecf5e665a 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ExitCodes.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ExitCodes.kt @@ -18,6 +18,7 @@ package hu.bme.mit.theta.xcfa.cli.params import com.microsoft.z3.Z3Exception import hu.bme.mit.theta.common.exception.NotSolvableException +import hu.bme.mit.theta.frontend.UnsupportedFrontendElementException import hu.bme.mit.theta.solver.UnknownSolverStatusException import hu.bme.mit.theta.solver.javasmt.JavaSMTSolverException import hu.bme.mit.theta.solver.smtlib.solver.SmtLibSolverException @@ -32,6 +33,7 @@ enum class ExitCodes(val code: Int) { SERVER_ERROR(202), PORTFOLIO_ERROR(203), + UNSUPPORTED_ELEMENT(209), FRONTEND_FAILED(210), INVALID_PARAM(211), @@ -59,6 +61,9 @@ fun exitOnError(stacktrace: Boolean, throwDontExit: Boolean, body: () -> T): } catch (e: ErrorCodeException) { e.printStackTrace() exitProcess(throwDontExit, e, e.code) + } catch (e: UnsupportedFrontendElementException) { + e.printCauseAndTrace(stacktrace) + exitProcess(throwDontExit, e, ExitCodes.UNSUPPORTED_ELEMENT.code) } catch (e: SmtLibSolverException) { e.printCauseAndTrace(stacktrace) exitProcess(throwDontExit, e, ExitCodes.SOLVER_ERROR.code) From 6325e7839f5519b77787f5d0a53f978d0135e809 Mon Sep 17 00:00:00 2001 From: "ThetaBotMaintainer[bot]" <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> Date: Thu, 17 Oct 2024 09:29:59 +0000 Subject: [PATCH 07/40] Version bump --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index e029ef4eda..20a45bf13f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.5.2" + version = "6.6.0" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } From 1efc717114a0eefd09d5f73a8488e5c942f748ae Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 17 Oct 2024 12:08:35 +0200 Subject: [PATCH 08/40] Modified set file names --- .github/actions/benchexec-test/theta.xml | 88 ++++++++++++++---------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/.github/actions/benchexec-test/theta.xml b/.github/actions/benchexec-test/theta.xml index 2ce7d4bc50..5960b731de 100644 --- a/.github/actions/benchexec-test/theta.xml +++ b/.github/actions/benchexec-test/theta.xml @@ -1,4 +1,20 @@ + + @@ -11,90 +27,90 @@ - - ../sv-benchmarks/c/ReachSafety-Arrays.set + + ../sv-benchmarks/c/Arrays.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-BitVectors.set + + ../sv-benchmarks/c/BitVectors.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-ControlFlow.set + + ../sv-benchmarks/c/ControlFlow.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-ECA.set + + ../sv-benchmarks/c/ECA.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Floats.set + + ../sv-benchmarks/c/Floats.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Heap.set + + ../sv-benchmarks/c/Heap.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Loops.set + + ../sv-benchmarks/c/Loops.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-ProductLines.set + + ../sv-benchmarks/c/ProductLines.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Recursive.set + + ../sv-benchmarks/c/Recursive.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Sequentialized.set + + ../sv-benchmarks/c/Sequentialized.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-XCSP.set + + ../sv-benchmarks/c/XCSP.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Combinations.set + + ../sv-benchmarks/c/Combinations.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Hardware.set + + ../sv-benchmarks/c/Hardware.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Hardness.set + + ../sv-benchmarks/c/Hardness.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ReachSafety-Fuzzle.set + + ../sv-benchmarks/c/Fuzzle.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/ConcurrencySafety-Main.set + + ../sv-benchmarks/c/Concurrency.set ../sv-benchmarks/c/properties/unreach-call.prp - - ../sv-benchmarks/c/NoDataRace-Main.set + + ../sv-benchmarks/c/Concurrency.set ../sv-benchmarks/c/properties/no-data-race.prp - ../sv-benchmarks/c/ConcurrencySafety-NoOverflows.set + ../sv-benchmarks/c/Concurrency.set ../sv-benchmarks/c/properties/no-overflow.prp - ../sv-benchmarks/c/ConcurrencySafety-MemSafety.set + ../sv-benchmarks/c/ConcurrencySafety.set ../sv-benchmarks/c/properties/valid-memsafety.prp From 5f150a6ed2918250c1663d1865d58422cc995bf4 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 17 Oct 2024 14:43:49 +0200 Subject: [PATCH 09/40] Moved to timeout-based ending of bencjmarking --- .github/actions/benchexec-test/action.yml | 20 +++++++++---------- .github/workflows/linux-build-test-deploy.yml | 19 +++++++++++++++++- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/.github/actions/benchexec-test/action.yml b/.github/actions/benchexec-test/action.yml index d0f198ec4c..d71d1be253 100644 --- a/.github/actions/benchexec-test/action.yml +++ b/.github/actions/benchexec-test/action.yml @@ -49,20 +49,20 @@ runs: run: | unzip release/Theta.zip sed -i 's/ --input \$1/ --portfolio ${{ inputs.portfolio }} --input \$1/g' Theta/theta-start.sh - - name: Cut setfile if too long - id: setfile - shell: bash - run: | - cd sv-benchmarks/c - for i in $(sed 's/#.*$//g' ${{ inputs.task }}.set); do find . -wholename ./$i; done | while read line; do grep "${line#./}" $GITHUB_ACTION_PATH/unsupported.txt >/dev/null 2>/dev/null || test -z $(yq e '.properties.[] | select(.property_file == "../properties/unreach-call.prp")' $line) >/dev/null 2>/dev/null || echo $(echo $line | sha1sum | awk ' { print $1 } ') $line ; done | sort -k1 | awk ' { $1=""; print $0 } ' | awk '{$1=$1};1' > all-files.txt - head -n${{ inputs.test_number }} all-files.txt > ${{ inputs.task }}.set - echo "length=$(cat ${{ inputs.task }}.set | wc -l)" >> "$GITHUB_OUTPUT" - cat ${{ inputs.task }}.set +# - name: Cut setfile if too long +# id: setfile +# shell: bash +# run: | +# cd sv-benchmarks/c +# for i in $(sed 's/#.*$//g' ${{ inputs.task }}.set); do find . -wholename ./$i; done | while read line; do grep "${line#./}" $GITHUB_ACTION_PATH/unsupported.txt >/dev/null 2>/dev/null || test -z $(yq e '.properties.[] | select(.property_file == "../properties/unreach-call.prp")' $line) >/dev/null 2>/dev/null || echo $(echo $line | sha1sum | awk ' { print $1 } ') $line ; done | sort -k1 | awk ' { $1=""; print $0 } ' | awk '{$1=$1};1' > all-files.txt +# head -n${{ inputs.test_number }} all-files.txt > ${{ inputs.task }}.set +# echo "length=$(cat ${{ inputs.task }}.set | wc -l)" >> "$GITHUB_OUTPUT" +# cat ${{ inputs.task }}.set - name: Run benchexec shell: bash if: steps.setfile.outputs.length != '0' run: | - benchexec xml/theta.xml -n 2 --no-container --tool-directory Theta -t ${{ inputs.task }} + timeout 300 benchexec xml/theta.xml -n 2 --no-container --tool-directory Theta -t ${{ inputs.task }} - name: Upload results uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 if: steps.setfile.outputs.length != '0' diff --git a/.github/workflows/linux-build-test-deploy.yml b/.github/workflows/linux-build-test-deploy.yml index c670c7f497..80040fd800 100644 --- a/.github/workflows/linux-build-test-deploy.yml +++ b/.github/workflows/linux-build-test-deploy.yml @@ -49,7 +49,24 @@ jobs: test-benchexec: strategy: matrix: - task: [ReachSafety-Arrays, ReachSafety-BitVectors, ReachSafety-ControlFlow, ReachSafety-ECA, ReachSafety-Floats, ReachSafety-Heap, ReachSafety-Loops, ReachSafety-ProductLines, ReachSafety-Recursive, ReachSafety-Sequentialized, ReachSafety-XCSP, ReachSafety-Combinations, ReachSafety-Hardware, ConcurrencySafety-Main, NoDataRace-Main, ConcurrencySafety-NoOverflows, ConcurrencySafety-MemSafety] + task: + - Arrays + - BitVectors + - ControlFlow + - ECA + - Floats + - Heap + - Loops + - ProductLines + - Recursive + - Sequentialized + - XCSP + - Combinations + - Hardware + - Concurrency + - NoDataRace + - ConcurrencySafety-NoOverflows + - ConcurrencySafety-MemSafety portfolio: [CEGAR, BOUNDED, HORN] runs-on: ubuntu-latest needs: create-archives From 8b7f5d4e1a63d01f9d998da09103abbee75ac9ca Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 17 Oct 2024 15:06:15 +0200 Subject: [PATCH 10/40] Fix bug in action --- .github/actions/benchexec-test/action.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/actions/benchexec-test/action.yml b/.github/actions/benchexec-test/action.yml index d71d1be253..e56e7e8d09 100644 --- a/.github/actions/benchexec-test/action.yml +++ b/.github/actions/benchexec-test/action.yml @@ -60,12 +60,10 @@ runs: # cat ${{ inputs.task }}.set - name: Run benchexec shell: bash - if: steps.setfile.outputs.length != '0' run: | timeout 300 benchexec xml/theta.xml -n 2 --no-container --tool-directory Theta -t ${{ inputs.task }} - name: Upload results uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 - if: steps.setfile.outputs.length != '0' with: name: BenchexecResults-${{ inputs.task }}-${{ inputs.portfolio }} path: results From 295fee2fc9c58eb622ab7f53bf8b4170090f52cf Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Thu, 17 Oct 2024 18:04:57 +0200 Subject: [PATCH 11/40] Timeout produced nonzero exit code; fixed --- .github/actions/benchexec-test/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/benchexec-test/action.yml b/.github/actions/benchexec-test/action.yml index e56e7e8d09..8444c92201 100644 --- a/.github/actions/benchexec-test/action.yml +++ b/.github/actions/benchexec-test/action.yml @@ -61,7 +61,7 @@ runs: - name: Run benchexec shell: bash run: | - timeout 300 benchexec xml/theta.xml -n 2 --no-container --tool-directory Theta -t ${{ inputs.task }} + timeout 300 benchexec xml/theta.xml -n 2 --no-container --tool-directory Theta -t ${{ inputs.task }} || true - name: Upload results uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 with: From 7ff2cc6505060ce1643d8f4686ab04765bd71f84 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Fri, 18 Oct 2024 11:32:04 +0200 Subject: [PATCH 12/40] removed comment from xml --- .github/actions/benchexec-test/theta.xml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.github/actions/benchexec-test/theta.xml b/.github/actions/benchexec-test/theta.xml index 5960b731de..e2a7455cee 100644 --- a/.github/actions/benchexec-test/theta.xml +++ b/.github/actions/benchexec-test/theta.xml @@ -1,20 +1,4 @@ - - From b0ca2940f46d96938fbbfc7f141f244d47969b57 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Fri, 18 Oct 2024 15:23:24 +0200 Subject: [PATCH 13/40] Moved conditional expressions to function visitor --- .../frontends/c-frontend/src/main/antlr/C.g4 | 2 +- .../grammar/expression/ExpressionVisitor.java | 71 ++++----- .../grammar/function/FunctionVisitor.java | 136 +++++++++++++----- 3 files changed, 142 insertions(+), 67 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/antlr/C.g4 b/subprojects/frontends/c-frontend/src/main/antlr/C.g4 index af6b7ccd1c..386d294c42 100644 --- a/subprojects/frontends/c-frontend/src/main/antlr/C.g4 +++ b/subprojects/frontends/c-frontend/src/main/antlr/C.g4 @@ -173,7 +173,7 @@ logicalOrExpression ; conditionalExpression - : logicalOrExpression ('?' expression ':' conditionalExpression)? + : logicalOrExpression ('?' ifTrue=expression ':' ifFalse=expression)? ; assignmentExpression diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java index d714b8693a..18f2ee1123 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java @@ -44,7 +44,10 @@ import hu.bme.mit.theta.frontend.transformation.grammar.preprocess.TypedefVisitor; import hu.bme.mit.theta.frontend.transformation.grammar.type.TypeVisitor; import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; -import hu.bme.mit.theta.frontend.transformation.model.statements.*; +import hu.bme.mit.theta.frontend.transformation.model.statements.CAssignment; +import hu.bme.mit.theta.frontend.transformation.model.statements.CCall; +import hu.bme.mit.theta.frontend.transformation.model.statements.CExpr; +import hu.bme.mit.theta.frontend.transformation.model.statements.CStatement; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CArray; import hu.bme.mit.theta.frontend.transformation.model.types.complex.compound.CPointer; @@ -110,37 +113,41 @@ public List getPreStatements() { return preStatements; } - @Override - public Expr visitConditionalExpression(CParser.ConditionalExpressionContext ctx) { - if (ctx.expression() != null) { - CStatement ifTrue = ctx.expression().accept(functionVisitor); - addPreStatements(ifTrue); - if (ifTrue instanceof CAssignment) { - preStatements.add(ifTrue); - } - Expr expr = ctx.logicalOrExpression().accept(this); - Expr lhs = ifTrue.getExpression(); - Expr rhs = ctx.conditionalExpression().accept(this); - CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); - IteExpr ite = Ite( - AbstractExprs.Neq(CComplexType.getType(expr, parseContext).getNullValue(), expr), - smallestCommonType.castTo(lhs), - smallestCommonType.castTo(rhs) - ); - parseContext.getMetadata().create(ite, "cType", smallestCommonType); - return ite; - } else return ctx.logicalOrExpression().accept(this); - } - - private void addPreStatements(CStatement ifTrue) { - if (ifTrue instanceof CCompound) { - if (ifTrue.getPreStatements() != null) preStatements.add(ifTrue.getPreStatements()); - if (ifTrue.getPostStatements() != null) postStatements.add(ifTrue.getPostStatements()); - for (CStatement cStatement : ((CCompound) ifTrue).getcStatementList()) { - addPreStatements(cStatement); - } - } - } +// @Override +// public Expr visitConditionalExpression(CParser.ConditionalExpressionContext ctx) { +// if (ctx.expression() != null) { +// CStatement cond = ctx.logicalOrExpression().accept(functionVisitor); +// CStatement ifTrue = ctx.expression().accept(functionVisitor); +// CStatement ifFalse = ctx.conditionalExpression().accept(functionVisitor); +// +// Expr expr = ctx.logicalOrExpression().accept(this); +// Expr lhs = ifTrue.getExpression(); +// Expr rhs = ctx.conditionalExpression().accept(this); +// +// preStatements.add(new CIf(cond, ifTrue, ifFalse, parseContext)); +// +// CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); +// IteExpr ite = Ite( +// AbstractExprs.Neq(CComplexType.getType(expr, parseContext).getNullValue(), expr), +// smallestCommonType.castTo(lhs), +// smallestCommonType.castTo(rhs) +// ); +// parseContext.getMetadata().create(ite, "cType", smallestCommonType); +// return ite; +// } else return ctx.logicalOrExpression().accept(this); +// } + +// private void addPrePostStatementsForConditional(CStatement statement) { +// if (statement instanceof CCompound) { +// if (statement.getPreStatements() != null) preStatements.add(statement.getPreStatements()); +// if (statement.getPostStatements() != null) postStatements.add(statement.getPostStatements()); +// for (CStatement cStatement : ((CCompound) statement).getcStatementList()) { +// addPrePostStatementsForConditional(cStatement); +// } +// } else { +// preStatements.add(statement); +// } +// } @Override public Expr visitLogicalOrExpression(CParser.LogicalOrExpressionContext ctx) { diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index eb98d8d707..61906b9eb2 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -26,7 +26,9 @@ import hu.bme.mit.theta.core.stmt.AssumeStmt; import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.core.type.LitExpr; +import hu.bme.mit.theta.core.type.abstracttype.AbstractExprs; import hu.bme.mit.theta.core.type.anytype.Exprs; +import hu.bme.mit.theta.core.type.anytype.IteExpr; import hu.bme.mit.theta.core.type.arraytype.ArrayType; import hu.bme.mit.theta.core.type.booltype.BoolType; import hu.bme.mit.theta.frontend.ParseContext; @@ -40,26 +42,7 @@ import hu.bme.mit.theta.frontend.transformation.grammar.type.DeclarationVisitor; import hu.bme.mit.theta.frontend.transformation.grammar.type.TypeVisitor; import hu.bme.mit.theta.frontend.transformation.model.declaration.CDeclaration; -import hu.bme.mit.theta.frontend.transformation.model.statements.CAssignment; -import hu.bme.mit.theta.frontend.transformation.model.statements.CAssume; -import hu.bme.mit.theta.frontend.transformation.model.statements.CBreak; -import hu.bme.mit.theta.frontend.transformation.model.statements.CCase; -import hu.bme.mit.theta.frontend.transformation.model.statements.CCompound; -import hu.bme.mit.theta.frontend.transformation.model.statements.CContinue; -import hu.bme.mit.theta.frontend.transformation.model.statements.CDecls; -import hu.bme.mit.theta.frontend.transformation.model.statements.CDefault; -import hu.bme.mit.theta.frontend.transformation.model.statements.CDoWhile; -import hu.bme.mit.theta.frontend.transformation.model.statements.CExpr; -import hu.bme.mit.theta.frontend.transformation.model.statements.CFor; -import hu.bme.mit.theta.frontend.transformation.model.statements.CFunction; -import hu.bme.mit.theta.frontend.transformation.model.statements.CGoto; -import hu.bme.mit.theta.frontend.transformation.model.statements.CIf; -import hu.bme.mit.theta.frontend.transformation.model.statements.CInitializerList; -import hu.bme.mit.theta.frontend.transformation.model.statements.CProgram; -import hu.bme.mit.theta.frontend.transformation.model.statements.CRet; -import hu.bme.mit.theta.frontend.transformation.model.statements.CStatement; -import hu.bme.mit.theta.frontend.transformation.model.statements.CSwitch; -import hu.bme.mit.theta.frontend.transformation.model.statements.CWhile; +import hu.bme.mit.theta.frontend.transformation.model.statements.*; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CComplexType; import hu.bme.mit.theta.frontend.transformation.model.types.complex.CVoid; import hu.bme.mit.theta.frontend.transformation.model.types.simple.CSimpleType; @@ -67,20 +50,13 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.antlr.v4.runtime.Token; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.StringJoiner; +import java.util.*; +import java.util.stream.Stream; import static com.google.common.base.Preconditions.checkState; import static hu.bme.mit.theta.core.decl.Decls.Var; import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Add; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Ite; import static hu.bme.mit.theta.core.utils.TypeUtils.cast; import static hu.bme.mit.theta.grammar.UtilsKt.textWithWS; @@ -541,18 +517,110 @@ public CStatement visitAssignmentExpressionAssignmentExpression(CParser.Assignme @Override public CStatement visitAssignmentExpressionConditionalExpression(CParser.AssignmentExpressionConditionalExpressionContext ctx) { - ExpressionVisitor expressionVisitor = new ExpressionVisitor(parseContext, this, variables, functions, typedefVisitor, typeVisitor, uniqueWarningLogger); + return ctx.conditionalExpression().accept(this); + } + + /* + This collects the following: + - the current compound's pre-statement + - all pre-statements of the pre-statement (before the pre-statement) + - all the pre-statement of every cStatement + */ + private List collectPreStatements(CStatement cStatement) { + if (cStatement instanceof CCompound) { + return Stream.concat( + Stream.concat( + collectPreStatements(cStatement.getPreStatements()).stream(), + Stream.of(cStatement.getPreStatements())), + ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPreStatements(cStatement1).stream()) + ).toList(); + } else return List.of(); + } + + /* + This collects the following: + - all the post-statements of every cStatement + - the current compound's post-statement + - all post-statements of the post-statement (after the post-statement) + */ + private List collectPostStatements(CStatement cStatement) { + if (cStatement instanceof CCompound) { + return Stream.concat( + ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPostStatements(cStatement1).stream()), + Stream.concat( + Stream.of(cStatement.getPreStatements()), + collectPostStatements(cStatement.getPreStatements()).stream()) + ).toList(); + } else return List.of(); + } + + // This is in the function visitor, not in the expression visitor, because + // cond ? f1() : f2() + // will only call either f1 or f2 (it can be used for branching) + @Override + public CStatement visitConditionalExpression(CParser.ConditionalExpressionContext ctx) { CCompound compound = new CCompound(parseContext); CCompound preStatements = new CCompound(parseContext); CCompound postStatements = new CCompound(parseContext); - Expr ret = ctx.conditionalExpression().accept(expressionVisitor); - CExpr cexpr = new CExpr(ret, parseContext); + + ExpressionVisitor expressionVisitor = new ExpressionVisitor(parseContext, this, variables, functions, typedefVisitor, typeVisitor, uniqueWarningLogger); + + Expr iteExpr; + if (!ctx.expression().isEmpty()) { + CStatement ifTrue = ctx.ifTrue.accept(this); + CStatement ifFalse = ctx.ifFalse.accept(this); + + Expr expr = ctx.logicalOrExpression().accept(expressionVisitor); + Expr lhs = ifTrue.getExpression(); + Expr rhs = ifFalse.getExpression(); + + CCompound guardCompound = new CCompound(parseContext); + guardCompound.getcStatementList().add(new CExpr(expr, parseContext)); + guardCompound.setPostStatements(new CCompound(parseContext)); + guardCompound.setPreStatements(new CCompound(parseContext)); + + + CCompound ifTruePre = new CCompound(parseContext); + ifTruePre.getcStatementList().addAll(collectPreStatements(ifTrue)); + ifTruePre.setPostStatements(new CCompound(parseContext)); + ifTruePre.setPreStatements(new CCompound(parseContext)); + CCompound ifFalsePre = new CCompound(parseContext); + ifFalsePre.getcStatementList().addAll(collectPreStatements(ifFalse)); + ifFalsePre.setPostStatements(new CCompound(parseContext)); + ifFalsePre.setPreStatements(new CCompound(parseContext)); + + CCompound ifTruePost = new CCompound(parseContext); + ifTruePost.getcStatementList().addAll(collectPostStatements(ifTrue)); + ifTruePost.setPostStatements(new CCompound(parseContext)); + ifTruePost.setPreStatements(new CCompound(parseContext)); + CCompound ifFalsePost = new CCompound(parseContext); + ifFalsePost.getcStatementList().addAll(collectPostStatements(ifFalse)); + ifFalsePost.setPostStatements(new CCompound(parseContext)); + ifFalsePost.setPreStatements(new CCompound(parseContext)); + + + preStatements.getcStatementList().add(new CIf(guardCompound, ifTruePre, ifFalsePre, parseContext)); + postStatements.getcStatementList().add(new CIf(guardCompound, ifTruePost, ifFalsePost, parseContext)); + + CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); + IteExpr ite = Ite( + AbstractExprs.Neq(CComplexType.getType(expr, parseContext).getNullValue(), expr), + smallestCommonType.castTo(lhs), + smallestCommonType.castTo(rhs) + ); + parseContext.getMetadata().create(ite, "cType", smallestCommonType); + iteExpr = ite; + } else { + iteExpr = ctx.logicalOrExpression().accept(expressionVisitor); + } + + CExpr cexpr = new CExpr(iteExpr, parseContext); compound.getcStatementList().add(cexpr); preStatements.getcStatementList().addAll(expressionVisitor.getPreStatements()); compound.setPreStatements(preStatements); recordMetadata(ctx, compound); - postStatements.getcStatementList().addAll(expressionVisitor.getPostStatements()); compound.setPostStatements(postStatements); + postStatements.getcStatementList().addAll(expressionVisitor.getPostStatements()); recordMetadata(ctx, compound); return compound; } From e3e4e16cf84c89f1f1c88fb7398f7543879b6707 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Fri, 18 Oct 2024 16:30:03 +0200 Subject: [PATCH 14/40] Initializer lists now somewhat work --- .../grammar/function/FunctionVisitor.java | 15 ++++++++++----- .../bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index 61906b9eb2..427034fb2c 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -432,14 +432,19 @@ public CStatement visitBodyDeclaration(CParser.BodyDeclarationContext ctx) { createVars(declaration); if (declaration.getType() instanceof Struct) { checkState(declaration.getInitExpr() instanceof CInitializerList, "Struct can only be initialized via an initializer list!"); + final var initializerList = (CInitializerList) declaration.getInitExpr(); List> varDecls = declaration.getVarDecls(); - for (int i = 0; i < varDecls.size(); i++) { - VarDecl varDecl = varDecls.get(i); - Tuple2, CStatement> initializer = ((CInitializerList) declaration.getInitExpr()).getStatements().get(i); - - CAssignment cAssignment = new CAssignment(varDecl.getRef(), initializer.get2(), "=", parseContext); + VarDecl varDecl = varDecls.get(0); + final var ptrType = CComplexType.getUnsignedLong(parseContext); + LitExpr currentValue = ptrType.getNullValue(); + LitExpr unitValue = ptrType.getUnitValue(); + for (Tuple2, CStatement> statement : initializerList.getStatements()) { + final var expr = statement.get2().getExpression(); + final var deref = Exprs.Dereference(cast(varDecl.getRef(), currentValue.getType()), cast(currentValue, currentValue.getType()), expr.getType()); + CAssignment cAssignment = new CAssignment(deref, statement.get2(), "=", parseContext); recordMetadata(ctx, cAssignment); compound.getcStatementList().add(cAssignment); + currentValue = Add(currentValue, unitValue).eval(ImmutableValuation.empty()); } } else { checkState(declaration.getVarDecls().size() == 1, "non-struct declarations shall only have one variable!"); diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index 7bd0113897..d82a92fa4a 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -192,7 +192,7 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo for (flatVariable in flatVariables) { builder.addVar(flatVariable) val type = CComplexType.getType(flatVariable.ref, parseContext) - if (type is CArray && builder.getParams().none { it.first == flatVariable }) { + if ((type is CArray || type is CStruct) && builder.getParams().none { it.first == flatVariable }) { initStmtList.add(StmtLabel( Stmts.Assign(cast(flatVariable, flatVariable.type), cast(type.getValue("$ptrCnt"), flatVariable.type)) From 6591e8ba5d8304ce6cf13c4d4bd612023d950223 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Fri, 18 Oct 2024 19:36:13 +0200 Subject: [PATCH 15/40] Removed commented out code --- .../grammar/expression/ExpressionVisitor.java | 36 ------------------- 1 file changed, 36 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java index 18f2ee1123..609518ea3e 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/expression/ExpressionVisitor.java @@ -113,42 +113,6 @@ public List getPreStatements() { return preStatements; } -// @Override -// public Expr visitConditionalExpression(CParser.ConditionalExpressionContext ctx) { -// if (ctx.expression() != null) { -// CStatement cond = ctx.logicalOrExpression().accept(functionVisitor); -// CStatement ifTrue = ctx.expression().accept(functionVisitor); -// CStatement ifFalse = ctx.conditionalExpression().accept(functionVisitor); -// -// Expr expr = ctx.logicalOrExpression().accept(this); -// Expr lhs = ifTrue.getExpression(); -// Expr rhs = ctx.conditionalExpression().accept(this); -// -// preStatements.add(new CIf(cond, ifTrue, ifFalse, parseContext)); -// -// CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); -// IteExpr ite = Ite( -// AbstractExprs.Neq(CComplexType.getType(expr, parseContext).getNullValue(), expr), -// smallestCommonType.castTo(lhs), -// smallestCommonType.castTo(rhs) -// ); -// parseContext.getMetadata().create(ite, "cType", smallestCommonType); -// return ite; -// } else return ctx.logicalOrExpression().accept(this); -// } - -// private void addPrePostStatementsForConditional(CStatement statement) { -// if (statement instanceof CCompound) { -// if (statement.getPreStatements() != null) preStatements.add(statement.getPreStatements()); -// if (statement.getPostStatements() != null) postStatements.add(statement.getPostStatements()); -// for (CStatement cStatement : ((CCompound) statement).getcStatementList()) { -// addPrePostStatementsForConditional(cStatement); -// } -// } else { -// preStatements.add(statement); -// } -// } - @Override public Expr visitLogicalOrExpression(CParser.LogicalOrExpressionContext ctx) { if (ctx.logicalAndExpression().size() > 1) { From 185dc7ad29920254fc689ac68ff01952a1c65c5a Mon Sep 17 00:00:00 2001 From: "ThetaBotMaintainer[bot]" <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:12:37 +0000 Subject: [PATCH 16/40] Reformatted code --- buildSrc/build.gradle.kts | 3 +- .../src/main/kotlin/maven-artifact.gradle.kts | 9 +- scripts/complex.kts | 324 ++++++--- scripts/simple.kts | 6 +- .../theta/cfa/analysis/CfaToMonolithicExpr.kt | 12 +- .../bounded/BoundedCheckerBuilder.kt | 12 +- .../analysis/algorithm/chc/HornChecker.kt | 3 +- .../analysis/algorithm/mcm/MemoryEvent.kt | 12 +- .../algorithm/mcm/analysis/PartialSolver.kt | 3 +- .../mit/theta/analysis/ptr/ItpRefToPtrPrec.kt | 6 +- .../bme/mit/theta/analysis/ptr/PtrAction.kt | 23 +- .../bme/mit/theta/analysis/ptr/PtrAnalysis.kt | 15 +- .../hu/bme/mit/theta/analysis/ptr/PtrUtils.kt | 37 +- .../analysis/runtimemonitor/CexMonitor.kt | 9 +- .../runtimemonitor/MonitorCheckpoint.kt | 3 +- .../mit/theta/analysis/multi/MultiInitFunc.kt | 2 +- .../theta/analysis/multi/MultiPartialOrd.kt | 2 +- .../theta/analysis/multi/MultiTransFunc.kt | 2 +- .../multi/builder/MultiBuilderResult.kt | 2 +- .../multi/builder/MultiControlInitFunc.kt | 2 +- .../theta/analysis/algorithm/BoundedTest.kt | 9 +- .../mit/theta/analysis/ptr/PtrAnalysisTest.kt | 37 +- .../java/hu/bme/mit/theta/core/ChcUtils.kt | 6 +- .../hu/bme/mit/theta/grammar/dsl/Utils.kt | 6 +- .../mit/theta/grammar/dsl/expr/ExprParser.kt | 210 ++++-- .../mit/theta/grammar/dsl/stmt/StmtParser.kt | 3 +- .../bme/mit/theta/grammar/gson/ArgAdapter.kt | 6 +- .../theta/grammar/gson/ArgAdapterHelper.kt | 9 +- .../theta/grammar/gson/SafetyResultAdapter.kt | 12 +- .../mit/theta/grammar/gson/StateAdapters.kt | 3 +- .../mit/theta/grammar/gson/TraceAdapter.kt | 18 +- .../mit/theta/grammar/gson/VarDeclAdapter.kt | 6 +- .../hu/bme/mit/theta/grammar/dsl/ExprTest.kt | 283 +++++--- .../hu/bme/mit/theta/grammar/dsl/StmtTest.kt | 18 +- .../hu/bme/mit/theta/grammar/dsl/TypeTest.kt | 6 +- .../hu/bme/mit/theta/grammar/gson/TestGson.kt | 36 +- .../MultiNondetDiningPhilosophersTest.kt | 30 +- .../hu/bme/mit/theta/frontend/CStatistics.kt | 6 +- subprojects/frontends/llvm/build.gradle.kts | 30 +- .../compilers/DefaultGraphPatternCompiler.kt | 6 +- .../compilers/GraphPatternCompiler.kt | 6 +- .../pattern2expr/Pattern2ExprCompiler.kt | 24 +- .../mit/theta/graphsolver/GraphSolverTest.kt | 162 +++-- .../smtlib/GenericSmtLibHornSolverTest.kt | 7 +- .../mit/theta/solver/z3/Z3HornSolverTest.kt | 7 +- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 488 +++++++++----- .../java/hu/bme/mit/theta/c2xcfa/Utils.kt | 6 +- .../hu/bme/mit/theta/cat/dsl/CatVisitor.kt | 3 +- subprojects/xcfa/llvm2xcfa/build.gradle.kts | 6 +- .../hu/bme/mit/theta/xcfa/analysis/Utils.kt | 3 +- .../mit/theta/xcfa/analysis/XcfaAbstractor.kt | 7 +- .../bme/mit/theta/xcfa/analysis/XcfaAction.kt | 12 +- .../mit/theta/xcfa/analysis/XcfaAnalysis.kt | 148 +++-- .../theta/xcfa/analysis/XcfaPrecRefiner.kt | 15 +- .../analysis/XcfaSingeExprTraceRefiner.kt | 13 +- .../bme/mit/theta/xcfa/analysis/XcfaState.kt | 125 ++-- .../theta/xcfa/analysis/XcfaStateAdapter.kt | 6 +- .../xcfa/analysis/XcfaToMonolithicExpr.kt | 36 +- .../xcfa/analysis/coi/XcfaCoiMultiThread.kt | 6 +- .../theta/xcfa/analysis/oc/XcfaOcChecker.kt | 6 +- .../xcfa/analysis/oc/XcfaOcTraceExtractor.kt | 24 +- .../theta/xcfa/analysis/por/XcfaDporLts.kt | 7 +- .../xcfa/analysis/XcfaExplAnalysisTest.kt | 97 ++- .../xcfa/analysis/XcfaPredAnalysisTest.kt | 100 ++- .../theta/xcfa/analysis/XcfaStateLtsTest.kt | 3 +- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 23 +- .../cli/checkers/ConfigToBoundedChecker.kt | 24 +- .../xcfa/cli/checkers/ConfigToCegarChecker.kt | 45 +- .../xcfa/cli/checkers/ConfigToChecker.kt | 6 +- .../xcfa/cli/checkers/ConfigToOcChecker.kt | 12 +- .../xcfa/cli/checkers/ConfigToPortfolio.kt | 71 +- .../xcfa/cli/checkers/InProcessChecker.kt | 31 +- .../mit/theta/xcfa/cli/params/ParamValues.kt | 45 +- .../mit/theta/xcfa/cli/params/XcfaConfig.kt | 108 ++- .../mit/theta/xcfa/cli/portfolio/bounded.kt | 98 ++- .../mit/theta/xcfa/cli/portfolio/complex23.kt | 507 +++++++++----- .../mit/theta/xcfa/cli/portfolio/complex24.kt | 616 ++++++++++++------ .../bme/mit/theta/xcfa/cli/portfolio/horn.kt | 44 +- .../bme/mit/theta/xcfa/cli/portfolio/stm.kt | 29 +- .../bme/mit/theta/xcfa/cli/utils/GsonUtils.kt | 45 +- .../mit/theta/xcfa/cli/utils/PropertyUtils.kt | 6 +- .../mit/theta/xcfa/cli/utils/XcfaParser.kt | 79 ++- .../theta/xcfa/cli/utils/XcfaWitnessWriter.kt | 93 ++- .../xcfa/cli/witnesses/TraceToWitness.kt | 39 +- .../mit/theta/xcfa/cli/witnesses/Witness.kt | 17 +- .../mit/theta/xcfa/cli/XcfaCliParseTest.kt | 136 ++-- .../theta/xcfa/cli/XcfaCliPortfolioTest.kt | 22 +- .../mit/theta/xcfa/cli/XcfaCliVerifyTest.kt | 24 +- .../mit/theta/xcfa/cli/XcfaCliWitnessTest.kt | 40 +- .../hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt | 15 +- .../hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt | 12 +- .../xcfa-cli/src/test/resources/simple.kts | 16 +- .../main/java/hu/bme/mit/theta/xcfa/Utils.kt | 36 +- .../java/hu/bme/mit/theta/xcfa/XcfaToC.kt | 6 +- .../hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt | 9 +- .../mit/theta/xcfa/gson/XcfaLabelAdapter.kt | 9 +- .../java/hu/bme/mit/theta/xcfa/model/Dsl.kt | 49 +- .../hu/bme/mit/theta/xcfa/model/Visualizer.kt | 3 +- .../hu/bme/mit/theta/xcfa/model/XcfaLabel.kt | 33 +- .../xcfa/passes/AssumeFalseRemovalPass.kt | 3 +- .../xcfa/passes/AtomicReadsOneWritePass.kt | 9 +- .../xcfa/passes/CLibraryFunctionsPass.kt | 16 +- .../theta/xcfa/passes/ErrorLocationPass.kt | 7 +- .../xcfa/passes/FetchExecuteWriteback.kt | 44 +- .../theta/xcfa/passes/FinalLocationPass.kt | 18 +- .../xcfa/passes/FpFunctionsToExprsPass.kt | 286 +++++--- .../xcfa/passes/HavocPromotionAndRange.kt | 15 +- .../theta/xcfa/passes/InlineProceduresPass.kt | 40 +- .../hu/bme/mit/theta/xcfa/passes/LbePass.kt | 18 +- .../theta/xcfa/passes/MallocFunctionPass.kt | 42 +- .../mit/theta/xcfa/passes/NoSideEffectPass.kt | 4 +- .../theta/xcfa/passes/NondetFunctionPass.kt | 16 +- .../mit/theta/xcfa/passes/NormalizePass.kt | 4 +- .../theta/xcfa/passes/ProcedurePassManager.kt | 44 +- .../theta/xcfa/passes/ReferenceElimination.kt | 104 ++- .../theta/xcfa/passes/SvCompIntrinsicsPass.kt | 19 +- .../mit/theta/xcfa/passes/UnusedVarPass.kt | 3 +- .../hu/bme/mit/theta/xcfa/passes/Utils.kt | 66 +- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 18 +- .../hu/bme/mit/theta/xcfa/passes/PassTests.kt | 31 +- .../hu/bme/mit/theta/xcfa/passes/UtilsTest.kt | 36 +- .../hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt | 112 ++-- .../theta/xsts/analysis/XstsToRelations.kt | 3 +- .../theta/xsts/analysis/util/RandomXsts.kt | 54 +- .../xsts/analysis/util/XstsSerializer.kt | 3 +- .../mit/theta/xsts/utils/XSTSVarChanger.kt | 6 +- 126 files changed, 3926 insertions(+), 1987 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 093b423f12..5b1c79903a 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -44,7 +44,8 @@ dependencies { // https://github.com/gradle/kotlin-dsl/issues/1207 configurations.all { val isKotlinCompiler = name == "embeddedKotlin" || name.startsWith("kotlin") || name.startsWith( - "kapt") + "kapt" + ) if (!isKotlinCompiler) { resolutionStrategy.eachDependency { if (requested.group == "org.jetbrains.kotlin" && requested.module.name == "kotlin-compiler-embeddable") { diff --git a/buildSrc/src/main/kotlin/maven-artifact.gradle.kts b/buildSrc/src/main/kotlin/maven-artifact.gradle.kts index 95ddb2d588..acb489be5d 100644 --- a/buildSrc/src/main/kotlin/maven-artifact.gradle.kts +++ b/buildSrc/src/main/kotlin/maven-artifact.gradle.kts @@ -107,11 +107,14 @@ tasks { repositories { maven { val releasesRepoUrl = uri( - "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") + "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" + ) val snapshotsRepoUrl = uri( - "https://s01.oss.sonatype.org/content/repositories/snapshots/") + "https://s01.oss.sonatype.org/content/repositories/snapshots/" + ) url = if (version.toString() - .endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl + .endsWith("SNAPSHOT") + ) snapshotsRepoUrl else releasesRepoUrl credentials { username = System.getenv("OSSRH_USERNAME") password = System.getenv("OSSRH_PASSWORD") diff --git a/scripts/complex.kts b/scripts/complex.kts index b90d3907cc..98e5e6d073 100644 --- a/scripts/complex.kts +++ b/scripts/complex.kts @@ -89,38 +89,60 @@ val predConfig = baseConfig.copy(domain = Domain.PRED_CART, refinement = Refinem fun integerStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_z3_4.10.1_$inProcess", - quickExplConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_1 = ConfigNode("EmptyExpl_z3_4.10.1_$inProcess", - emptyExplConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_3_1 = ConfigNode("PredCart_z3_4.10.1_$inProcess", - predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess) + val config_1_1 = ConfigNode( + "QuickFullExpl_z3_4.10.1_$inProcess", + quickExplConfig.copy( + abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_2_1 = ConfigNode( + "EmptyExpl_z3_4.10.1_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_3_1 = ConfigNode( + "PredCart_z3_4.10.1_$inProcess", + predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess + ) val config_1_2 = ConfigNode("QuickFullExpl_Z3_$inProcess", quickExplConfig.copy(), checker, inProcess) val config_2_2 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(), checker, inProcess) val config_3_2 = ConfigNode("PredCart_Z3_$inProcess", predConfig.copy(), checker, inProcess) - val config_1_3 = ConfigNode("QuickFullExpl_princess_2022_07_01_$inProcess", + val config_1_3 = ConfigNode( + "QuickFullExpl_princess_2022_07_01_$inProcess", quickExplConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess) - val config_2_3 = ConfigNode("EmptyExpl_princess_2022_07_01_$inProcess", + checker, inProcess + ) + val config_2_3 = ConfigNode( + "EmptyExpl_princess_2022_07_01_$inProcess", emptyExplConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess) - val config_3_3 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + checker, inProcess + ) + val config_3_3 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess) + inProcess + ) - val config_1_4 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + val config_1_4 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess) - val config_2_4 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + inProcess + ) + val config_2_4 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess) - val config_3_4 = ConfigNode("PredCart_princess_2022_07_01_$inProcess", + inProcess + ) + val config_3_4 = ConfigNode( + "PredCart_princess_2022_07_01_$inProcess", predConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess) + checker, inProcess + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -136,9 +158,13 @@ fun integerStm(): STM { Edge(config_2_4, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -166,32 +192,60 @@ fun integerStm(): STM { fun bitwiseStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_Z3_$inProcess", - quickExplConfig.copy(refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_1 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(refinement = Refinement.NWT_IT_WP), - checker, inProcess) - val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + val config_1_1 = ConfigNode( + "QuickFullExpl_Z3_$inProcess", + quickExplConfig.copy(refinement = Refinement.NWT_IT_WP), checker, inProcess + ) + val config_2_1 = ConfigNode( + "EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(refinement = Refinement.NWT_IT_WP), + checker, inProcess + ) + val config_3_1 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess) - - val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", - emptyExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_3_2 = ConfigNode("PredCart_z3_4.10.1_$inProcess", - predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess) - - val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.SEQ_ITP), checker, inProcess) - val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", - predConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) + inProcess + ) + + val config_1_2 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_2_2 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_3_2 = ConfigNode( + "PredCart_z3_4.10.1_$inProcess", + predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess + ) + + val config_1_3 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.copy( + abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_2_3 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + refinement = Refinement.SEQ_ITP + ), checker, inProcess + ) + val config_3_3 = ConfigNode( + "PredCart_cvc5_1.0.2_$inProcess", + predConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -204,9 +258,13 @@ fun bitwiseStm(): STM { Edge(config_2_3, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -231,57 +289,113 @@ fun bitwiseStm(): STM { fun floatsStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_1 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + val config_1_1 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_2_1 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_3_1 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess) - - val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_seq_$inProcess", - quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP), checker, inProcess) - val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_seq_$inProcess", - emptyExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP), checker, inProcess) - val config_3_2 = ConfigNode("PredCart_bitwuzla_latest_$inProcess", - predConfig.copy(abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - - val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), - checker, inProcess) - val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), - checker, inProcess) - val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", - predConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker, inProcess) - - val config_1_4 = ConfigNode("QuickFullExpl_mathsat_fp_$inProcess", - quickExplConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) - val config_2_4 = ConfigNode("EmptyExpl_mathsat_fp_$inProcess", - emptyExplConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) - val config_3_4 = ConfigNode("PredCart_mathsat_fp_$inProcess", - predConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) - - val config_1_5 = ConfigNode("QuickFullExpl_Z3_$inProcess", - quickExplConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_2_5 = ConfigNode("EmptyExpl_Z3_$inProcess", - emptyExplConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker, inProcess) - val config_3_5 = ConfigNode("PredCart_Z3_$inProcess", + inProcess + ) + + val config_1_2 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_seq_$inProcess", + quickExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP + ), checker, inProcess + ) + val config_2_2 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_seq_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP + ), checker, inProcess + ) + val config_3_2 = ConfigNode( + "PredCart_bitwuzla_latest_$inProcess", + predConfig.copy( + abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + + val config_1_3 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.copy( + abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), + checker, inProcess + ) + val config_2_3 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), + checker, inProcess + ) + val config_3_3 = ConfigNode( + "PredCart_cvc5_1.0.2_$inProcess", + predConfig.copy( + abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + + val config_1_4 = ConfigNode( + "QuickFullExpl_mathsat_fp_$inProcess", + quickExplConfig.copy( + abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker, inProcess + ) + val config_2_4 = ConfigNode( + "EmptyExpl_mathsat_fp_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker, inProcess + ) + val config_3_4 = ConfigNode( + "PredCart_mathsat_fp_$inProcess", + predConfig.copy( + abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker, inProcess + ) + + val config_1_5 = ConfigNode( + "QuickFullExpl_Z3_$inProcess", + quickExplConfig.copy( + abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_2_5 = ConfigNode( + "EmptyExpl_Z3_$inProcess", + emptyExplConfig.copy( + abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), checker, inProcess + ) + val config_3_5 = ConfigNode( + "PredCart_Z3_$inProcess", predConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP), - checker, inProcess) + checker, inProcess + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -300,9 +414,13 @@ fun floatsStm(): STM { Edge(config_2_5, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), diff --git a/scripts/simple.kts b/scripts/simple.kts index 78c2678a13..da95633e75 100644 --- a/scripts/simple.kts +++ b/scripts/simple.kts @@ -47,8 +47,10 @@ var baseConfig = XcfaCegarConfig( ) if (traitsTyped.multithreaded) { - baseConfig = baseConfig.copy(search = Search.BFS, porLevel = POR.AAPOR, - pruneStrategy = PruneStrategy.LAZY) + baseConfig = baseConfig.copy( + search = Search.BFS, porLevel = POR.AAPOR, + pruneStrategy = PruneStrategy.LAZY + ) if (propertyTyped == ErrorDetection.DATA_RACE) { baseConfig = baseConfig.copy(porLevel = POR.BASIC) diff --git a/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt b/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt index ca6c125314..1164bb66af 100644 --- a/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt +++ b/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt @@ -41,11 +41,13 @@ fun CFA.toMonolithicExpr(): MonolithicExpr { } val locVar = Decls.Var("__loc__", Int()) val tranList = this.edges.map { e -> - SequenceStmt.of(listOf( - AssumeStmt.of(Eq(locVar.ref, Int(map[e.source]!!))), - e.stmt, - AssignStmt.of(locVar, Int(map[e.target]!!)) - )) + SequenceStmt.of( + listOf( + AssumeStmt.of(Eq(locVar.ref, Int(map[e.source]!!))), + e.stmt, + AssignStmt.of(locVar, Int(map[e.target]!!)) + ) + ) }.toList() val trans = NonDetStmt.of(tranList); val transUnfold = StmtUtils.toExpr(trans, VarIndexingFactory.indexing(0)); diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt index bfd1aeadf9..b54dc029aa 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt @@ -35,7 +35,8 @@ fun buildBMC( lfPathOnly: () -> Boolean = { true }, ): BoundedChecker { return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, null, - { false }, valToState, biValToAction, logger) + { false }, valToState, biValToAction, logger + ) } @JvmOverloads @@ -51,8 +52,10 @@ fun buildKIND( lfPathOnly: () -> Boolean = { true }, kindEnabled: (Int) -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, indSolver, - kindEnabled, valToState, biValToAction, logger) + return BoundedChecker( + monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, indSolver, + kindEnabled, valToState, biValToAction, logger + ) } @JvmOverloads @@ -69,5 +72,6 @@ fun buildIMC( imcEnabled: (Int) -> Boolean = { true }, ): BoundedChecker { return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, itpSolver, imcEnabled, null, - { false }, valToState, biValToAction, logger) + { false }, valToState, biValToAction, logger + ) } \ No newline at end of file diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt index 0c083b7cd0..8630eed180 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt @@ -68,7 +68,8 @@ class HornChecker( logger.write(Logger.Level.MAINSTEP, "Proof (model) found\n") val model = solver.model.toMap() SafetyResult.safe( - Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() })) + Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() }) + ) } SolverStatus.UNSAT -> { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt index d10f26e4d1..eeb9b794a4 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt @@ -52,8 +52,10 @@ open class MemoryEvent(protected val type: MemoryEventType, protected val tag: S throw UnsupportedOperationException("Not memory IO!") } - abstract class MemoryIO(id: Int, private val `var`: VarDecl<*>, private val localVar: VarDecl<*>, - type: MemoryEventType, tag: String) : + abstract class MemoryIO( + id: Int, private val `var`: VarDecl<*>, private val localVar: VarDecl<*>, + type: MemoryEventType, tag: String + ) : MemoryEvent(type, tag, id) { override fun asMemoryIO(): MemoryIO { @@ -86,8 +88,10 @@ open class MemoryEvent(protected val type: MemoryEventType, protected val tag: S } } - class Write(id: Int, `var`: VarDecl<*>, localVar: VarDecl<*>, private val dependencies: Set>, - tag: String) : + class Write( + id: Int, `var`: VarDecl<*>, localVar: VarDecl<*>, private val dependencies: Set>, + tag: String + ) : MemoryIO(id, `var`, localVar, MemoryEventType.WRITE, tag) { override fun asWrite(): Write { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt index a0257bb216..24b877d848 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt @@ -54,5 +54,6 @@ class PartialSolver( data class CandidateExecutionGraph( val nodes: List, - val knownEvents: Map, ThreeVL>) { + val knownEvents: Map, ThreeVL> +) { } \ No newline at end of file diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt index c3ec804041..6b17827bf2 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt @@ -30,8 +30,10 @@ class ItpRefToPtrPrec

(private val innerRefToPrec: RefutationToPrec { val newDerefs = refutation[index].dereferences val innerPrec = innerRefToPrec.toPrec(refutation, index).repatch() - return PtrPrec(innerPrec, newDerefs.flatMap { it.ops }.toSet(), - if (newDerefs.isEmpty()) 0 else refutation.size() - index) + return PtrPrec( + innerPrec, newDerefs.flatMap { it.ops }.toSet(), + if (newDerefs.isEmpty()) 0 else refutation.size() - index + ) } override fun join(prec1: PtrPrec

, prec2: PtrPrec

): PtrPrec

{ diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt index 015084a889..4dee747bb0 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt @@ -61,19 +61,30 @@ abstract class PtrAction(writeTriples: WriteTriples = emptyMap(), val inCnt: Int val postList = ArrayList() for ((deref, type) in stmt.dereferencesWithAccessTypes) { - Preconditions.checkState(deref.uniquenessIdx.isPresent, - "Incomplete dereferences (missing uniquenessIdx) are not handled properly.") + Preconditions.checkState( + deref.uniquenessIdx.isPresent, + "Incomplete dereferences (missing uniquenessIdx) are not handled properly." + ) val expr = deref.getIte(nextWriteTriples) if (type == AccessType.WRITE) { val writeExpr = ExprUtils.simplify(IntExprs.Add(expr, IntExprs.Int(1))) nextWriteTriples.getOrPut(deref.type) { ArrayList() } .add(Triple(lookup[deref]!!.first, lookup[deref]!!.second, deref.uniquenessIdx.get())) - postList.add(Stmts.Assume(ExprUtils.simplify(BoolExprs.And(listOf( - AbstractExprs.Eq(writeExpr, deref.uniquenessIdx.get()), - ))))) + postList.add( + Stmts.Assume( + ExprUtils.simplify( + BoolExprs.And( + listOf( + AbstractExprs.Eq(writeExpr, deref.uniquenessIdx.get()), + ) + ) + ) + ) + ) } else { preList.add( - Stmts.Assume(ExprUtils.simplify(AbstractExprs.Eq(expr, deref.uniquenessIdx.get())))) + Stmts.Assume(ExprUtils.simplify(AbstractExprs.Eq(expr, deref.uniquenessIdx.get()))) + ) } // postList.add(Stmts.Assume(Eq(vargen("value", deref.type).ref, deref))) // debug mode } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt index 4eb29ec625..881fecb5bb 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt @@ -35,16 +35,20 @@ import hu.bme.mit.theta.core.stmt.Stmt * */ -class PtrAnalysis(private val innerAnalysis: Analysis, - private val isHavoc: Boolean = false) : +class PtrAnalysis( + private val innerAnalysis: Analysis, + private val isHavoc: Boolean = false +) : Analysis, PtrAction, PtrPrec

> { override fun getPartialOrd(): PartialOrd> = innerAnalysis.partialOrd.getPtrPartialOrd() override fun getInitFunc(): InitFunc, PtrPrec

> = innerAnalysis.initFunc.getPtrInitFunc() - override fun getTransFunc(): TransFunc, PtrAction, PtrPrec

> = innerAnalysis.transFunc.getPtrTransFunc( - isHavoc) + override fun getTransFunc(): TransFunc, PtrAction, PtrPrec

> = + innerAnalysis.transFunc.getPtrTransFunc( + isHavoc + ) } fun PartialOrd.getPtrPartialOrd(): PartialOrd> = PartialOrd { state1, state2 -> @@ -56,7 +60,8 @@ fun InitFunc.getPtrInitFunc(): InitFunc TransFunc.getPtrTransFunc( - isHavoc: Boolean = false): TransFunc, PtrAction, PtrPrec

> = TransFunc { state, action, prec -> + isHavoc: Boolean = false +): TransFunc, PtrAction, PtrPrec

> = TransFunc { state, action, prec -> val writeTriples = action.nextWriteTriples() val patchedPrec = prec.innerPrec.patch(writeTriples) val exprAction: ExprAction = if (isHavoc) { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt index 3cc08a0cf1..d1748f2526 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt @@ -53,7 +53,8 @@ enum class AccessType { val Stmt.dereferencesWithAccessTypes: List, AccessType>> get() = when (this) { is MemoryAssignStmt<*, *, *> -> expr.dereferences.map { Pair(it, AccessType.READ) } + listOf( - Pair(deref, AccessType.WRITE)) + deref.ops.flatMap { it.dereferences }.map { Pair(it, AccessType.READ) } + Pair(deref, AccessType.WRITE) + ) + deref.ops.flatMap { it.dereferences }.map { Pair(it, AccessType.READ) } is AssignStmt<*> -> expr.dereferences.map { Pair(it, AccessType.READ) } is AssumeStmt -> cond.dereferences.map { Pair(it, AccessType.READ) } @@ -83,19 +84,23 @@ fun SequenceStmt.collapse(): Stmt = this } -fun Stmt.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, - lookup: MutableMap, Pair, Expr<*>>>): Stmt { +fun Stmt.uniqueDereferences( + vargen: (String, Type) -> VarDecl<*>, + lookup: MutableMap, Pair, Expr<*>>> +): Stmt { val ret = ArrayList() val newStmt = when (this) { is MemoryAssignStmt<*, *, *> -> { MemoryAssignStmt.create( deref.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second as Dereference<*, *, *>, - expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) + expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second + ) } is AssignStmt<*> -> AssignStmt.of( TypeUtils.cast(varDecl, varDecl.type), - TypeUtils.cast(expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second, varDecl.type)) + TypeUtils.cast(expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second, varDecl.type) + ) is AssumeStmt -> AssumeStmt.of(cond.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) is SequenceStmt -> Stmts.SequenceStmt(stmts.map { it.uniqueDereferences(vargen, lookup) }) @@ -109,13 +114,16 @@ fun Stmt.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, return SequenceStmt.of(ret + newStmt).collapse() } -fun Expr.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, - lookup: MutableMap, Pair, Expr<*>>>): Pair, Expr> = +fun Expr.uniqueDereferences( + vargen: (String, Type) -> VarDecl<*>, + lookup: MutableMap, Pair, Expr<*>>> +): Pair, Expr> = if (this is Dereference<*, *, T>) { val ret = ArrayList() Preconditions.checkState(this.uniquenessIdx.isEmpty, "Only non-pretransformed dereferences should be here") val arrayExpr = ExprUtils.simplify( - array.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) + array.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second + ) val arrayLaterRef = if (arrayExpr !is LitExpr<*>) { val arrayConst = vargen("a", array.type).ref ret.add(Assume(Eq(arrayConst, arrayExpr))) @@ -124,7 +132,8 @@ fun Expr.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, arrayExpr } val offsetExpr = ExprUtils.simplify( - offset.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) + offset.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second + ) val offsetLaterRef = if (offsetExpr !is LitExpr<*>) { val offsetConst = vargen("o", offset.type).ref ret.add(Assume(Eq(offsetConst, offsetExpr))) @@ -141,7 +150,8 @@ fun Expr.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, } else { val ret = ArrayList() Pair(ret, - this.withOps(this.ops.map { it.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second })) + this.withOps(this.ops.map { it.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second }) + ) } object TopCollection : Set> { @@ -168,8 +178,11 @@ enum class PtrTracking { fun Dereference.getIte(writeTriples: WriteTriples): Expr { val list = writeTriples[type] ?: emptyList() return list.fold(Int(0) as Expr) { elze, (arr, off, value) -> - IteExpr.of(BoolExprs.And( - listOf(Eq(arr, array), Eq(off, offset))), value, elze) + IteExpr.of( + BoolExprs.And( + listOf(Eq(arr, array), Eq(off, offset)) + ), value, elze + ) } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt index 32c78c9b0e..95069ed1c1 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt @@ -39,8 +39,10 @@ class CexMonitor constructor( fun checkIfNewCexFound(): Boolean { return if (arg.cexs.anyMatch { cex -> !cexHashStorage.contains(cex) }) { - logger.write(Logger.Level.VERBOSE, - "Counterexample hash check: new cex found successfully\n") + logger.write( + Logger.Level.VERBOSE, + "Counterexample hash check: new cex found successfully\n" + ) true } else { logger.write(Logger.Level.INFO, "Counterexample hash check: NO new cex found\n") @@ -65,7 +67,8 @@ class CexMonitor constructor( when (checkpointName) { "CegarChecker.unsafeARG" -> if (checkIfNewCexFound()) addNewCounterexample() else throwNotSolvable() else -> throw RuntimeException( - "Unknown checkpoint name in CexMonitor execution: $checkpointName") + "Unknown checkpoint name in CexMonitor execution: $checkpointName" + ) } } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt index 0e1faccd73..7ddfe7adec 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt @@ -52,7 +52,8 @@ class MonitorCheckpoint internal constructor(private val name: String) { assert(registeredCheckpoints.contains(checkpointName)) { "Checkpoint name $checkpointName was not registered (add it in MonitorCheckpoint.kt)" } // see checkpointNames above registeredCheckpoints[checkpointName]?.registerMonitor(m) ?: error( - "Checkpoint with name $checkpointName not found.") + "Checkpoint with name $checkpointName not found." + ) } fun execute(name: String) { diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt index 4d7e740082..f3c1ab15ec 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt @@ -22,7 +22,7 @@ import hu.bme.mit.theta.analysis.State class MultiInitFunc> -( + ( private val createInitialState: (LControl, RControl, DataState) -> MState, private val dataInitFunc: InitFunc, private val extractLeftControlPrec: (LPrec) -> LControlPrec, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt index 68b3c77b27..b48b564c28 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt @@ -20,7 +20,7 @@ import hu.bme.mit.theta.analysis.State class MultiPartialOrd> -( + ( private val leftPartOrd: PartialOrd, private val leftCombineStates: (LControl, DataState) -> LState, private val rightPartOrd: PartialOrd, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt index ffe72c9757..02021807d9 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt @@ -24,7 +24,7 @@ class MultiTransFunc, MAction : MultiAction> -( + ( private val defineNextSide: (MState) -> MultiSide, private val createState: (LControl, RControl, DataState, MultiSide) -> MState, private val leftTransFunc: TransFunc, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt index eea37fb1ce..d090ac8cb4 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt @@ -33,7 +33,7 @@ import hu.bme.mit.theta.analysis.unit.UnitState * the whole IDE. For this reason, a POJO has to be used instead */ private data class MultiBuilderResult, MControlState : MultiState, MAction : MultiAction, MLts : MultiLts> -( + ( val side: MultiAnalysisSide, MultiPrec>, val lts: MLts ) diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt index d094692eac..6aa4f6614a 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt @@ -28,7 +28,7 @@ import hu.bme.mit.theta.analysis.unit.UnitState * Serves as a control initial function for a multi analysis if the product is nested and this analysis is going to be a part of a larger product. */ internal class MultiControlInitFunc, MPrec : MultiPrec> -( + ( private val leftControlInitFunc: InitFunc, private val rightControlInitFunc: InitFunc, private val createState: (lState: LControl, rState: RControl) -> MState diff --git a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt index c1a49e333e..5156908c26 100644 --- a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt +++ b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt @@ -43,7 +43,8 @@ class BoundedTest { } private val biValToAction = { valuation: Valuation?, valuation2: Valuation? -> ExprActionStub( - emptyList()) + emptyList() + ) } init { @@ -76,7 +77,8 @@ class BoundedTest { indSolver = indSolver, valToState = valToState, biValToAction = biValToAction, - logger = ConsoleLogger(Logger.Level.VERBOSE)) + logger = ConsoleLogger(Logger.Level.VERBOSE) + ) val safetyResult: SafetyResult<*, *> = checker.check() Assert.assertTrue(safetyResult.isUnsafe()) } @@ -93,7 +95,8 @@ class BoundedTest { indSolver = indSolver, valToState = valToState, biValToAction = biValToAction, - logger = ConsoleLogger(Logger.Level.VERBOSE)) + logger = ConsoleLogger(Logger.Level.VERBOSE) + ) val safetyResult: SafetyResult<*, *> = checker.check() Assert.assertTrue(safetyResult.isSafe()) } diff --git a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt index 9379846676..6c2a0a179c 100644 --- a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt +++ b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt @@ -43,31 +43,44 @@ class PtrAnalysisTest { private val explTop1 = PtrState(ExplState.top(), nextCnt = 1) private val emptyAction = PtrActionStub(listOf(), emptyMap()) - private val readLiteralOnly = PtrActionStub(listOf(Assume(Eq(Dereference(Int(0), Int(1), Int()), Int(0)))), - emptyMap()) - private val writeLiteralOnly = PtrActionStub(listOf(MemoryAssign(Dereference(Int(0), Int(1), Int()), Int(0))), - emptyMap()) + private val readLiteralOnly = PtrActionStub( + listOf(Assume(Eq(Dereference(Int(0), Int(1), Int()), Int(0)))), + emptyMap() + ) + private val writeLiteralOnly = PtrActionStub( + listOf(MemoryAssign(Dereference(Int(0), Int(1), Int()), Int(0))), + emptyMap() + ) private val emptyPrec = PtrPrec(ExplPrec.empty(), emptySet()) @JvmStatic fun testInputs(): Collection { return listOf( - Arguments.of(explTop0, emptyAction, emptyPrec, - listOf(explTop0)), - Arguments.of(explTop0, readLiteralOnly, emptyPrec, - listOf(explTop1)), - Arguments.of(explTop0, writeLiteralOnly, emptyPrec, + Arguments.of( + explTop0, emptyAction, emptyPrec, + listOf(explTop0) + ), + Arguments.of( + explTop0, readLiteralOnly, emptyPrec, + listOf(explTop1) + ), + Arguments.of( + explTop0, writeLiteralOnly, emptyPrec, listOf( - PtrState(ExplState.top(), 1))), + PtrState(ExplState.top(), 1) + ) + ), ) } } @ParameterizedTest @MethodSource("testInputs") - fun transFuncTest(state: PtrState, action: PtrAction, prec: PtrPrec, - expectedResult: Collection>) { + fun transFuncTest( + state: PtrState, action: PtrAction, prec: PtrPrec, + expectedResult: Collection> + ) { val analysis = PtrAnalysis(ExplAnalysis.create(Z3LegacySolverFactory.getInstance().createSolver(), True())) val result = analysis.transFunc.getSuccStates(state, action, prec) diff --git a/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt b/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt index 5b7789b350..1f3d2ee7c5 100644 --- a/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt +++ b/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt @@ -61,8 +61,10 @@ open class Relation(val name: String, vararg paramTypes: Type) { open operator fun invoke(vararg params: Expr<*>) = RelationApp(this, params.toList()) } -data class RelationApp(val relation: Relation, val params: List>, - val constraints: List> = emptyList()) { +data class RelationApp( + val relation: Relation, val params: List>, + val constraints: List> = emptyList() +) { init { checkArgument(params.size == relation.arity) diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt index 488fe3330b..665121a5cd 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt @@ -33,8 +33,10 @@ fun ParserRuleContext.textWithWS(): String { object ThrowingErrorListener : BaseErrorListener() { @Throws(ParseCancellationException::class) - override fun syntaxError(recognizer: Recognizer<*, *>?, offendingSymbol: Any?, line: Int, - charPositionInLine: Int, msg: String, e: RecognitionException?) { + override fun syntaxError( + recognizer: Recognizer<*, *>?, offendingSymbol: Any?, line: Int, + charPositionInLine: Int, msg: String, e: RecognitionException? + ) { throw ParseCancellationException("line $line:$charPositionInLine $msg") } } \ No newline at end of file diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt index f896e6265a..adfdcc3f80 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt @@ -118,8 +118,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } private fun pop() { - Preconditions.checkState(currentScope.enclosingScope().isPresent, - "Enclosing scope is not present.") + Preconditions.checkState( + currentScope.enclosingScope().isPresent, + "Enclosing scope is not present." + ) currentScope = currentScope.enclosingScope().get() env.pop() } @@ -127,8 +129,10 @@ class ExpressionWrapper(scope: Scope, content: String) { //// override fun visitFuncLitExpr(ctx: FuncLitExprContext): Expr { return if (ctx.result != null) { - val param = Decls.Param(ctx.param.name.text, - TypeWrapper(ctx.param.type().textWithWS()).instantiate()) + val param = Decls.Param( + ctx.param.name.text, + TypeWrapper(ctx.param.type().textWithWS()).instantiate() + ) push(listOf(param)) val result = ctx.result.accept>(this) as Expr pop() @@ -144,8 +148,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } else { ctx.decls.stream() .map { d: DeclContext -> - Decls.Param(d.name.getText(), - TypeWrapper(d.ttype.textWithWS()).instantiate()) + Decls.Param( + d.name.getText(), + TypeWrapper(d.ttype.textWithWS()).instantiate() + ) }.collect(Collectors.toList()) } } @@ -153,8 +159,10 @@ class ExpressionWrapper(scope: Scope, content: String) { //// override fun visitIteExpr(ctx: IteExprContext): Expr { return if (ctx.cond != null) { - val cond: Expr = TypeUtils.cast(ctx.cond.accept>(this), - BoolExprs.Bool()) + val cond: Expr = TypeUtils.cast( + ctx.cond.accept>(this), + BoolExprs.Bool() + ) val then: Expr<*> = ctx.then.accept>(this) val elze: Expr<*> = ctx.elze.accept>(this) AbstractExprs.Ite(cond, then, elze) @@ -165,10 +173,14 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitIffExpr(ctx: IffExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), - BoolExprs.Bool()) - val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), - BoolExprs.Bool()) + val leftOp: Expr = TypeUtils.cast( + ctx.leftOp.accept>(this), + BoolExprs.Bool() + ) + val rightOp: Expr = TypeUtils.cast( + ctx.rightOp.accept>(this), + BoolExprs.Bool() + ) BoolExprs.Iff(leftOp, rightOp) } else { visitChildren(ctx) @@ -177,10 +189,14 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitImplyExpr(ctx: ImplyExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), - BoolExprs.Bool()) - val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), - BoolExprs.Bool()) + val leftOp: Expr = TypeUtils.cast( + ctx.leftOp.accept>(this), + BoolExprs.Bool() + ) + val rightOp: Expr = TypeUtils.cast( + ctx.rightOp.accept>(this), + BoolExprs.Bool() + ) BoolExprs.Imply(leftOp, rightOp) } else { visitChildren(ctx) @@ -191,8 +207,10 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.paramDecls != null) { val paramDecls = createParamList(ctx.paramDecls) push(paramDecls) - val op: Expr = TypeUtils.cast(ctx.op.accept>(this), - BoolExprs.Bool()) + val op: Expr = TypeUtils.cast( + ctx.op.accept>(this), + BoolExprs.Bool() + ) pop() BoolExprs.Forall(paramDecls, op) } else { @@ -204,8 +222,10 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.paramDecls != null) { val paramDecls = createParamList(ctx.paramDecls) push(paramDecls) - val op: Expr = TypeUtils.cast(ctx.op.accept>(this), - BoolExprs.Bool()) + val op: Expr = TypeUtils.cast( + ctx.op.accept>(this), + BoolExprs.Bool() + ) pop() BoolExprs.Exists(paramDecls, op) } else { @@ -228,10 +248,14 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitXorExpr(ctx: XorExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), - BoolExprs.Bool()) - val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), - BoolExprs.Bool()) + val leftOp: Expr = TypeUtils.cast( + ctx.leftOp.accept>(this), + BoolExprs.Bool() + ) + val rightOp: Expr = TypeUtils.cast( + ctx.rightOp.accept>(this), + BoolExprs.Bool() + ) BoolExprs.Xor(leftOp, rightOp) } else { visitChildren(ctx) @@ -253,8 +277,10 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitNotExpr(ctx: NotExprContext): Expr { return if (ctx.op != null) { - val op: Expr = TypeUtils.cast(ctx.op.accept>(this), - BoolExprs.Bool()) + val op: Expr = TypeUtils.cast( + ctx.op.accept>(this), + BoolExprs.Bool() + ) BoolExprs.Not(op) } else { visitChildren(ctx) @@ -386,8 +412,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createAdditiveExpr(opsHead: Expr<*>, opsTail: List>, - oper: Token, ctx: AdditiveExprContext): Expr { + private fun createAdditiveExpr( + opsHead: Expr<*>, opsTail: List>, + oper: Token, ctx: AdditiveExprContext + ): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -398,18 +426,24 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createAdditiveSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, - ctx: AdditiveExprContext): Expr { + private fun createAdditiveSubExpr( + leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, + ctx: AdditiveExprContext + ): Expr { return when (oper.type) { PLUS -> createAddExpr(leftOp, rightOp) MINUS -> createSubExpr(leftOp, rightOp) BV_ADD -> createBvAddExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) BV_SUB -> createBvSubExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) - FPADD -> FpExprs.Add(getRoundingMode(ctx.oper.text), - java.util.List.of(TypeUtils.castFp(leftOp), TypeUtils.castFp(rightOp))) + FPADD -> FpExprs.Add( + getRoundingMode(ctx.oper.text), + java.util.List.of(TypeUtils.castFp(leftOp), TypeUtils.castFp(rightOp)) + ) - FPSUB -> FpExprs.Sub(getRoundingMode(ctx.oper.text), TypeUtils.castFp(leftOp), - TypeUtils.castFp(rightOp)) + FPSUB -> FpExprs.Sub( + getRoundingMode(ctx.oper.text), TypeUtils.castFp(leftOp), + TypeUtils.castFp(rightOp) + ) else -> throw ParseException(ctx, "Unknown operator '" + oper.text + "'") } @@ -459,8 +493,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createMutliplicativeExpr(opsHead: Expr<*>, opsTail: List>, - oper: Token, ctx: MultiplicativeExprContext): Expr { + private fun createMutliplicativeExpr( + opsHead: Expr<*>, opsTail: List>, + oper: Token, ctx: MultiplicativeExprContext + ): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -471,8 +507,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createMultiplicativeSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, - ctx: MultiplicativeExprContext): Expr { + private fun createMultiplicativeSubExpr( + leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, + ctx: MultiplicativeExprContext + ): Expr { return when (oper.type) { MUL -> createMulExpr(leftOp, rightOp) BV_MUL -> createBvMulExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) @@ -485,11 +523,15 @@ class ExpressionWrapper(scope: Scope, content: String) { BV_UREM -> createBvURemExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) BV_SREM -> createBvSRemExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) FPREM -> FpExprs.Rem(leftOp as Expr, rightOp as Expr) - FPMUL -> FpExprs.Mul(getRoundingMode(ctx.oper.text), - java.util.List.of(leftOp as Expr, rightOp as Expr)) + FPMUL -> FpExprs.Mul( + getRoundingMode(ctx.oper.text), + java.util.List.of(leftOp as Expr, rightOp as Expr) + ) - FPDIV -> FpExprs.Div(getRoundingMode(ctx.oper.text), leftOp as Expr, - rightOp as Expr) + FPDIV -> FpExprs.Div( + getRoundingMode(ctx.oper.text), leftOp as Expr, + rightOp as Expr + ) else -> throw ParseException(ctx, "Unknown operator '" + oper.text + "'") } @@ -563,8 +605,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createConcatExpr(opsHead: Expr<*>, opsTail: List>, - oper: Token): Expr { + private fun createConcatExpr( + opsHead: Expr<*>, opsTail: List>, + oper: Token + ): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -575,8 +619,10 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createConcatSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, - oper: Token): Expr { + private fun createConcatSubExpr( + leftOp: Expr<*>, rightOp: Expr<*>, + oper: Token + ): Expr { return when (oper.type) { BV_CONCAT -> createBvConcatExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) else -> throw AssertionError() @@ -599,10 +645,12 @@ class ExpressionWrapper(scope: Scope, content: String) { val extendType = BvExprs.BvType(ctx.rightOp.size.getText().toInt()) when (ctx.oper.getType()) { BV_ZERO_EXTEND -> BvExprs.ZExt( - TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType) + TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType + ) BV_SIGN_EXTEND -> BvExprs.SExt( - TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType) + TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType + ) else -> throw AssertionError() } @@ -621,20 +669,28 @@ class ExpressionWrapper(scope: Scope, content: String) { FP_ABS -> FpExprs.Abs(op as Expr) FP_IS_INF -> FpExprs.IsInfinite(op as Expr) FP_IS_NAN -> FpExprs.IsNan(op as Expr) - FPROUNDTOINT -> FpExprs.RoundToIntegral(getRoundingMode(ctx.oper.text), - op as Expr) + FPROUNDTOINT -> FpExprs.RoundToIntegral( + getRoundingMode(ctx.oper.text), + op as Expr + ) FPSQRT -> FpExprs.Sqrt(getRoundingMode(ctx.oper.text), op as Expr) - FPTOFP -> FpExprs.ToFp(getRoundingMode(ctx.oper.text), op as Expr, - getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText())) - - FPTOBV -> FpExprs.ToBv(getRoundingMode(ctx.oper.text), op as Expr, - getBvSize(ctx.oper.getText()), isSignedBv(ctx.oper.getText())) - - FP_FROM_BV -> FpExprs.FromBv(getRoundingMode(ctx.oper.text), + FPTOFP -> FpExprs.ToFp( + getRoundingMode(ctx.oper.text), op as Expr, + getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText()) + ) + + FPTOBV -> FpExprs.ToBv( + getRoundingMode(ctx.oper.text), op as Expr, + getBvSize(ctx.oper.getText()), isSignedBv(ctx.oper.getText()) + ) + + FP_FROM_BV -> FpExprs.FromBv( + getRoundingMode(ctx.oper.text), op as Expr, FpType.of(getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText())), - isSignedFp(ctx.oper.getText())) + isSignedFp(ctx.oper.getText()) + ) FPNEG -> FpExprs.Neg(op as Expr) FPPOS -> FpExprs.Pos(op as Expr) @@ -717,7 +773,8 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.array != null) { ArrayReadExpr.create( ctx.array.accept(this), - ctx.index.accept(this)) + ctx.index.accept(this) + ) } else { visitChildren(ctx) } @@ -728,7 +785,8 @@ class ExpressionWrapper(scope: Scope, content: String) { ArrayWriteExpr.create( ctx.array.accept(this), ctx.index.accept(this), - ctx.elem.accept(this)) + ctx.elem.accept(this) + ) } else { visitChildren(ctx) } @@ -746,8 +804,10 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.op != null) { val op = ctx.op.accept(this) val bitvec = TypeUtils.castBv(op) - return BvExprs.Extract(bitvec, Int(ctx.from.getText()), - IntExprs.Int(ctx.until.getText())) + return BvExprs.Extract( + bitvec, Int(ctx.from.getText()), + IntExprs.Int(ctx.until.getText()) + ) } else { visitChildren(ctx) } @@ -804,14 +864,19 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitArrLitExpr(ctx: ArrLitExprContext): Expr { Preconditions.checkNotNull(ctx.elseExpr) val indexType = if (ctx.indexExpr.size > 0) ctx.indexExpr[0].accept( - this).type else Int() + this + ).type else Int() val elseElem = ctx.elseExpr.accept(this) val valueType = elseElem.type val elems = ctx.indexExpr.mapIndexed { idx, it -> Tuple2.of(it.accept(this), ctx.valueExpr[idx].accept(this)) } - return ExprUtils.simplify(ArrayInitExpr.create(elems, elseElem, - ArrayType.of(indexType, valueType))) + return ExprUtils.simplify( + ArrayInitExpr.create( + elems, elseElem, + ArrayType.of(indexType, valueType) + ) + ) } override fun visitBvLitExpr(ctx: BvLitExprContext): Expr { @@ -822,7 +887,8 @@ class ExpressionWrapper(scope: Scope, content: String) { decodeBinaryBvContent(content.substring(1)) } else if (content.startsWith("d")) { check( - sizeAndContent.size == 2) { "Decimal value is only parseable if size is given." } + sizeAndContent.size == 2 + ) { "Decimal value is only parseable if size is given." } decodeDecimalBvContent(content.substring(1), sizeAndContent[0].toInt()) } else if (content.startsWith("x")) { decodeHexadecimalBvContent(content.substring(1)) @@ -843,7 +909,8 @@ class ExpressionWrapper(scope: Scope, content: String) { '0' -> value[i] = false '1' -> value[i] = true else -> throw IllegalArgumentException( - "Binary literal can contain only 0 and 1") + "Binary literal can contain only 0 and 1" + ) } } return value @@ -853,7 +920,8 @@ class ExpressionWrapper(scope: Scope, content: String) { var value = BigInteger(lit) Preconditions.checkArgument( value.compareTo( - BigInteger.TWO.pow(size - 1).multiply(BigInteger.valueOf(-1))) >= 0 && + BigInteger.TWO.pow(size - 1).multiply(BigInteger.valueOf(-1)) + ) >= 0 && value.compareTo(BigInteger.TWO.pow(size)) < 0, "Decimal literal is not in range" ) @@ -892,8 +960,10 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitIdExpr(ctx: IdExprContext): RefExpr<*> { val optSymbol = currentScope.resolve(ctx.id.getText()) if (optSymbol.isEmpty) { - throw ParseException(ctx, - "Identifier '" + ctx.id.getText() + "' cannot be resolved") + throw ParseException( + ctx, + "Identifier '" + ctx.id.getText() + "' cannot be resolved" + ) } val symbol = optSymbol.get() val decl = env.eval(symbol) as Decl<*> diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt index 09ea6e8f9d..d11ca4187c 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt @@ -108,7 +108,8 @@ class StatementWrapper(val content: String, scope: Scope) { override fun visitMemAssignStmt(ctx: MemAssignStmtContext): Stmt { val derefExpr: Dereference<*, *, *> = ExpressionWrapper(scope, ctx.derefExpr().textWithWS()).instantiate( - env) as Dereference<*, *, *> + env + ) as Dereference<*, *, *> val value = ExpressionWrapper(scope, ctx.value.textWithWS()) val valueE: Expr<*> = value.instantiate(env) return if (derefExpr.type == valueE.type) { diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt index a05598f87e..eaad49e3e0 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt @@ -26,9 +26,11 @@ import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.algorithm.arg.ARG import java.lang.reflect.Type -class ArgAdapter(val gsonSupplier: () -> Gson, +class ArgAdapter( + val gsonSupplier: () -> Gson, private val partialOrdSupplier: () -> PartialOrd, - private val argTypeSupplier: () -> Type) : TypeAdapter>() { + private val argTypeSupplier: () -> Type +) : TypeAdapter>() { private lateinit var gson: Gson private lateinit var partialOrd: PartialOrd diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt index f00ff2ac89..05e193a195 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt @@ -54,11 +54,14 @@ data class ArgAdapterHelper( while (waitSet.isNotEmpty()) { val entry = waitSet.firstOrNull { lut.keys.contains(checkNotNull(edges[it]).source) } check( - entry != null) { "Unreachable node(s) present: $waitSet\nedges: $edges\nlut: $lut" } + entry != null + ) { "Unreachable node(s) present: $waitSet\nedges: $edges\nlut: $lut" } waitSet.remove(entry) val edge = checkNotNull(edges[entry]) - lut[entry] = arg.createSuccNode(lut[edge.source], edge.action, checkNotNull(nodes[entry]).state, - checkNotNull(nodes[entry]).target) + lut[entry] = arg.createSuccNode( + lut[edge.source], edge.action, checkNotNull(nodes[entry]).state, + checkNotNull(nodes[entry]).target + ) .also { n -> if (checkNotNull(nodes[entry]).expanded) n.expanded = true } } coveringEdges.forEach { checkNotNull(lut[it.key]).cover(lut[it.value]) } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt index 6829d577c0..271417ea04 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt @@ -40,8 +40,10 @@ class SafetyResultAdapter( private lateinit var argType: Type private lateinit var traceType: Type - override fun write(writer: JsonWriter, - value: SafetyResult, Trace>) { + override fun write( + writer: JsonWriter, + value: SafetyResult, Trace> + ) { initGson() writer.beginObject() writer.name("arg") @@ -80,8 +82,10 @@ class SafetyResultAdapter( return if (stats.isEmpty) if (safe == true) SafetyResult.safe(arg) else SafetyResult.unsafe(trace, arg) else - if (safe == false) SafetyResult.safe(arg, stats.get()) else SafetyResult.unsafe(trace, - arg, stats.get()) + if (safe == false) SafetyResult.safe(arg, stats.get()) else SafetyResult.unsafe( + trace, + arg, stats.get() + ) } private fun initGson() { diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt index a75f2133cb..1675ec639a 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt @@ -90,7 +90,8 @@ class PredStateAdapter(val gsonSupplier: () -> Gson, val scope: Scope, val env: if (reader.nextBoolean()) ret = PredState.bottom() check(reader.nextName() == "preds") val preds = gson.fromJson>>(reader, - object : TypeToken>>() {}.type) + object : TypeToken>>() {}.type + ) if (ret == null) ret = PredState.of(preds) reader.endObject() return ret!! diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt index 0571800b23..649ec9d72c 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt @@ -26,8 +26,10 @@ import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.Trace import java.lang.reflect.Type -class TraceAdapter(val gsonSupplier: () -> Gson, private val stateTypeSupplier: () -> Type, - private val actionType: Type) : TypeAdapter>() { +class TraceAdapter( + val gsonSupplier: () -> Gson, private val stateTypeSupplier: () -> Type, + private val actionType: Type +) : TypeAdapter>() { private lateinit var gson: Gson private lateinit var stateType: Type @@ -47,11 +49,15 @@ class TraceAdapter(val gsonSupplier: () -> Gson, private val stateTypeSupplier: if (!this::stateType.isInitialized) stateType = stateTypeSupplier() reader.beginObject() check(reader.nextName() == "states") - val stateList: List = gson.fromJson(reader, - TypeToken.getParameterized(TypeToken.get(List::class.java).type, stateType).type) + val stateList: List = gson.fromJson( + reader, + TypeToken.getParameterized(TypeToken.get(List::class.java).type, stateType).type + ) check(reader.nextName() == "actions") - val actionList: List = gson.fromJson(reader, - TypeToken.getParameterized(TypeToken.get(List::class.java).type, actionType).type) + val actionList: List = gson.fromJson( + reader, + TypeToken.getParameterized(TypeToken.get(List::class.java).type, actionType).type + ) reader.endObject() return Trace.of(stateList, actionList) } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt index 8e0ea55885..2dc571788f 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt @@ -29,8 +29,10 @@ import hu.bme.mit.theta.core.decl.Decls.Var import hu.bme.mit.theta.core.decl.VarDecl import hu.bme.mit.theta.core.type.Type -class VarDeclAdapter(val gsonSupplier: () -> Gson, val scope: MutableScope, val env: Env, - val throwIfNotInScope: Boolean = false) : TypeAdapter>() { +class VarDeclAdapter( + val gsonSupplier: () -> Gson, val scope: MutableScope, val env: Env, + val throwIfNotInScope: Boolean = false +) : TypeAdapter>() { private lateinit var gson: Gson diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt index ff72c48eb5..b647fb75c2 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt @@ -91,36 +91,57 @@ class ExprTest { arrayOf(fpLit1, "(#b1 #b1010 #b101010)", emptyMap>()), arrayOf(fpLit2, "(#b0 #b1010 #b101010)", emptyMap>()), - arrayOf(ArrayLitExpr.of(listOf(), Int(2), ArrayType.of(Int(), Int())), - "(array (default 2))", emptyMap>()), - arrayOf(ArrayLitExpr.of(listOf(Tuple2.of(Int(0), Int(1))), Int(2), - ArrayType.of(Int(), Int())), "(array (0 1) (default 2))", - emptyMap>()), arrayOf( - ArrayLitExpr.of(listOf(Tuple2.of(Int(0), Int(1)), Tuple2.of(Int(1), Int(2))), - Int(3), ArrayType.of(Int(), Int())), "(array (0 1) (1 2) (default 3))", - emptyMap>()), + ArrayLitExpr.of(listOf(), Int(2), ArrayType.of(Int(), Int())), + "(array (default 2))", emptyMap>() + ), + arrayOf( + ArrayLitExpr.of( + listOf(Tuple2.of(Int(0), Int(1))), Int(2), + ArrayType.of(Int(), Int()) + ), "(array (0 1) (default 2))", + emptyMap>() + ), + arrayOf( + ArrayLitExpr.of( + listOf(Tuple2.of(Int(0), Int(1)), Tuple2.of(Int(1), Int(2))), + Int(3), ArrayType.of(Int(), Int()) + ), "(array (0 1) (1 2) (default 3))", + emptyMap>() + ), arrayOf(RefExpr.of(x), "x", mapOf(Pair(NamedSymbol("x"), x))), - arrayOf(Ite(True(), Int(1), Int(2)), "(ite true 1 2)", - emptyMap>()), + arrayOf( + Ite(True(), Int(1), Int(2)), "(ite true 1 2)", + emptyMap>() + ), arrayOf(Iff(True(), False()), "(iff true false)", emptyMap>()), arrayOf(Imply(True(), False()), "(=> true false)", emptyMap>()), - arrayOf(Forall(listOf(p), True()), "(forall ((p Int)) true)", - mapOf(Pair(NamedSymbol("p"), p))), - arrayOf(Exists(listOf(p), True()), "(exists ((p Int)) true)", - mapOf(Pair(NamedSymbol("p"), p))), + arrayOf( + Forall(listOf(p), True()), "(forall ((p Int)) true)", + mapOf(Pair(NamedSymbol("p"), p)) + ), + arrayOf( + Exists(listOf(p), True()), "(exists ((p Int)) true)", + mapOf(Pair(NamedSymbol("p"), p)) + ), - arrayOf(Max(fpLit1, fpLit2), "(fpmax (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), - arrayOf(Min(fpLit1, fpLit2), "(fpmin (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), + arrayOf( + Max(fpLit1, fpLit2), "(fpmax (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>() + ), + arrayOf( + Min(fpLit1, fpLit2), "(fpmin (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>() + ), arrayOf(Or(True(), False()), "(or true false)", emptyMap>()), arrayOf(Xor(True(), False()), "(xor true false)", emptyMap>()), - arrayOf(And(True(), False(), False()), "(and true false false)", - emptyMap>()), + arrayOf( + And(True(), False(), False()), "(and true false false)", + emptyMap>() + ), arrayOf(Not(True()), "(not true)", emptyMap>()), arrayOf(Eq(Int(1), Int(2)), "(= 1 2)", emptyMap>()), @@ -129,80 +150,142 @@ class ExprTest { arrayOf(Gt(Int(1), Int(2)), "(> 1 2)", emptyMap>()), arrayOf(Geq(Int(1), Int(2)), "(>= 1 2)", emptyMap>()), - arrayOf(BvExprs.ULt(bvLit1, bvLit1), "(bvult #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.ULeq(bvLit1, bvLit1), "(bvule #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.UGt(bvLit1, bvLit1), "(bvugt #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.UGeq(bvLit1, bvLit1), "(bvuge #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.SLt(bvLit1, bvLit1), "(bvslt #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.SLeq(bvLit1, bvLit1), "(bvsle #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.SGt(bvLit1, bvLit1), "(bvsgt #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.SGeq(bvLit1, bvLit1), "(bvsge #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.Or(listOf(bvLit1, bvLit1)), "(bvor #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.Xor(listOf(bvLit1, bvLit1)), "(bvxor #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.And(listOf(bvLit1, bvLit1)), "(bvand #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.ShiftLeft(bvLit1, bvLit1), "(bvshl #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.ArithShiftRight(bvLit1, bvLit1), "(bvashr #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.LogicShiftRight(bvLit1, bvLit1), "(bvlshr #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.RotateLeft(bvLit1, bvLit1), "(bvrol #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.RotateRight(bvLit1, bvLit1), "(bvror #b1010 #b1010)", - emptyMap>()), - - arrayOf(Add(listOf(Int(1), Int(2), Int(3))), "(+ 1 2 3)", - emptyMap>()), + arrayOf( + BvExprs.ULt(bvLit1, bvLit1), "(bvult #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.ULeq(bvLit1, bvLit1), "(bvule #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.UGt(bvLit1, bvLit1), "(bvugt #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.UGeq(bvLit1, bvLit1), "(bvuge #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.SLt(bvLit1, bvLit1), "(bvslt #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.SLeq(bvLit1, bvLit1), "(bvsle #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.SGt(bvLit1, bvLit1), "(bvsgt #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.SGeq(bvLit1, bvLit1), "(bvsge #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.Or(listOf(bvLit1, bvLit1)), "(bvor #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.Xor(listOf(bvLit1, bvLit1)), "(bvxor #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.And(listOf(bvLit1, bvLit1)), "(bvand #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.ShiftLeft(bvLit1, bvLit1), "(bvshl #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.ArithShiftRight(bvLit1, bvLit1), "(bvashr #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.LogicShiftRight(bvLit1, bvLit1), "(bvlshr #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.RotateLeft(bvLit1, bvLit1), "(bvrol #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.RotateRight(bvLit1, bvLit1), "(bvror #b1010 #b1010)", + emptyMap>() + ), + + arrayOf( + Add(listOf(Int(1), Int(2), Int(3))), "(+ 1 2 3)", + emptyMap>() + ), arrayOf(Sub(Int(1), Int(2)), "(- 1 2)", emptyMap>()), arrayOf(Add(bvLit1, bvLit1), "(bvadd #b1010 #b1010)", emptyMap>()), arrayOf(Sub(bvLit1, bvLit1), "(bvsub #b1010 #b1010)", emptyMap>()), - arrayOf(Add(fpLit1, fpLit2), "(fpadd (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), - arrayOf(Sub(fpLit1, fpLit2), "(fpsub (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), + arrayOf( + Add(fpLit1, fpLit2), "(fpadd (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>() + ), + arrayOf( + Sub(fpLit1, fpLit2), "(fpsub (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>() + ), - arrayOf(Mul(listOf(Int(1), Int(2), Int(3))), "(* 1 2 3)", - emptyMap>()), + arrayOf( + Mul(listOf(Int(1), Int(2), Int(3))), "(* 1 2 3)", + emptyMap>() + ), arrayOf(Div(Int(1), Int(2)), "(div 1 2)", emptyMap>()), arrayOf(Mod(Int(1), Int(2)), "(mod 1 2)", emptyMap>()), arrayOf(Rem(Int(1), Int(2)), "(rem 1 2)", emptyMap>()), arrayOf(Mul(bvLit1, bvLit1), "(bvmul #b1010 #b1010)", emptyMap>()), - arrayOf(UDiv(bvLit1, bvLit1), "(bvudiv #b1010 #b1010)", - emptyMap>()), - arrayOf(BvExprs.SDiv(bvLit1, bvLit2), "(bvsdiv #b1010 #b0101)", - emptyMap>()), - arrayOf(BvExprs.SMod(bvLit1, bvLit2), "(bvsmod #b1010 #b0101)", - emptyMap>()), - arrayOf(BvExprs.URem(bvLit1, bvLit2), "(bvurem #b1010 #b0101)", - emptyMap>()), - arrayOf(BvExprs.SRem(bvLit1, bvLit2), "(bvsrem #b1010 #b0101)", - emptyMap>()), - arrayOf(Mul(fpLit1, fpLit2), "(fpmul (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), - arrayOf(FpExprs.Div(FpRoundingMode.RNE, fpLit1, fpLit2), + arrayOf( + UDiv(bvLit1, bvLit1), "(bvudiv #b1010 #b1010)", + emptyMap>() + ), + arrayOf( + BvExprs.SDiv(bvLit1, bvLit2), "(bvsdiv #b1010 #b0101)", + emptyMap>() + ), + arrayOf( + BvExprs.SMod(bvLit1, bvLit2), "(bvsmod #b1010 #b0101)", + emptyMap>() + ), + arrayOf( + BvExprs.URem(bvLit1, bvLit2), "(bvurem #b1010 #b0101)", + emptyMap>() + ), + arrayOf( + BvExprs.SRem(bvLit1, bvLit2), "(bvsrem #b1010 #b0101)", + emptyMap>() + ), + arrayOf( + Mul(fpLit1, fpLit2), "(fpmul (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>() + ), + arrayOf( + FpExprs.Div(FpRoundingMode.RNE, fpLit1, fpLit2), "(fpdiv[rne] (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), - arrayOf(FpExprs.Rem(fpLit1, fpLit2), + emptyMap>() + ), + arrayOf( + FpExprs.Rem(fpLit1, fpLit2), "(fprem (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>()), + emptyMap>() + ), - arrayOf(Concat(listOf(bvLit1, bvLit2)), "(++ #b1010 #b0101)", - emptyMap>()), - arrayOf(ZExt(bvLit1, BvType(5)), "(bv_zero_extend #b1010 (Bv 5))", - emptyMap>()), - arrayOf(SExt(bvLit1, BvType(5)), "(bv_sign_extend #b1010 (Bv 5))", - emptyMap>()), + arrayOf( + Concat(listOf(bvLit1, bvLit2)), "(++ #b1010 #b0101)", + emptyMap>() + ), + arrayOf( + ZExt(bvLit1, BvType(5)), "(bv_zero_extend #b1010 (Bv 5))", + emptyMap>() + ), + arrayOf( + SExt(bvLit1, BvType(5)), "(bv_sign_extend #b1010 (Bv 5))", + emptyMap>() + ), arrayOf(Pos(Int(1)), "(+ 1)", emptyMap>()), arrayOf(Neg(Int(1)), "(- 1)", emptyMap>()), @@ -210,17 +293,27 @@ class ExprTest { arrayOf(Neg(bvLit1), "(bvneg #b1010)", emptyMap>()), arrayOf(Not(bvLit1), "(bvnot #b1010)", emptyMap>()), - arrayOf(ArrayReadExpr.create( - ArrayLitExpr.of(emptyList(), Int(2), ArrayType.of(Int(), Int())), Int(5)), - "(read (array (default 2)) 5)", emptyMap>()), - arrayOf(ArrayWriteExpr.create( - ArrayLitExpr.of(emptyList(), Int(2), - ArrayType.of(Int(), Int())), Int(5), Int(6)), - "(write (array (default 2)) 5 6)", emptyMap>()), + arrayOf( + ArrayReadExpr.create( + ArrayLitExpr.of(emptyList(), Int(2), ArrayType.of(Int(), Int())), Int(5) + ), + "(read (array (default 2)) 5)", emptyMap>() + ), + arrayOf( + ArrayWriteExpr.create( + ArrayLitExpr.of( + emptyList(), Int(2), + ArrayType.of(Int(), Int()) + ), Int(5), Int(6) + ), + "(write (array (default 2)) 5 6)", emptyMap>() + ), arrayOf(Prime(Int(1)), "(prime 1)", emptyMap>()), - arrayOf(Extract(bvLit1, Int(1), Int(4)), "(extract #b1010 1 4)", - emptyMap>()), + arrayOf( + Extract(bvLit1, Int(1), Int(4)), "(extract #b1010 1 4)", + emptyMap>() + ), arrayOf(Dereference(Int(0), Int(1), Int()), "(deref 0 1 Int)", emptyMap>()), ) @@ -240,7 +333,8 @@ class ExprTest { val env = Env() decls.forEach { env.define(it.key, it.value) } val expr = simplify( - ExpressionWrapper(SimpleScope(symbolTable), serialized).instantiate(env)) + ExpressionWrapper(SimpleScope(symbolTable), serialized).instantiate(env) + ) Assert.assertEquals(simplify(memory), expr) } @@ -252,7 +346,8 @@ class ExprTest { val env = Env() decls.forEach { env.define(it.key, it.value) } val expr = simplify( - ExpressionWrapper(SimpleScope(symbolTable), memory.toString()).instantiate(env)) + ExpressionWrapper(SimpleScope(symbolTable), memory.toString()).instantiate(env) + ) Assert.assertEquals(simplify(memory), expr) } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt index 372e1f796e..2dc532876e 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt @@ -53,13 +53,19 @@ class StmtTest { val addr = x.hashCode() return listOf( - arrayOf(Assign(x, Int(1)), "(assign x 1)", - mapOf(Pair(ExprTest.NamedSymbol("x"), x))), - arrayOf(MemoryAssign(Dereference(Int(addr), Int(0), Int()), Int(1)), + arrayOf( + Assign(x, Int(1)), "(assign x 1)", + mapOf(Pair(ExprTest.NamedSymbol("x"), x)) + ), + arrayOf( + MemoryAssign(Dereference(Int(addr), Int(0), Int()), Int(1)), "(memassign (deref $addr 0 Int) 1)", - mapOf(Pair(ExprTest.NamedSymbol("x"), x))), - arrayOf(Assume(Eq(x.ref, Int(1))), "(assume (= x 1))", - mapOf(Pair(ExprTest.NamedSymbol("x"), x))), + mapOf(Pair(ExprTest.NamedSymbol("x"), x)) + ), + arrayOf( + Assume(Eq(x.ref, Int(1))), "(assume (= x 1))", + mapOf(Pair(ExprTest.NamedSymbol("x"), x)) + ), arrayOf(Havoc(x), "(havoc x)", mapOf(Pair(ExprTest.NamedSymbol("x"), x))), ) } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt index a94dfbf86d..8745fef7c3 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt @@ -52,8 +52,10 @@ class TypeTest { arrayOf(BvType(32), "(Bv 32)"), arrayOf(FpType(12, 45), "(Fp 12 45)"), - arrayOf(Func(Int(), ArrayExprs.Array(Int(), Rat())), - "(Func Int (Array ([Int] -> Rat)))"), + arrayOf( + Func(Int(), ArrayExprs.Array(Int(), Rat())), + "(Func Int (Array ([Int] -> Rat)))" + ), ) } } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt index cb6ca93071..026a4626ee 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt @@ -102,11 +102,14 @@ class TestGson { val gsonBuilder = GsonBuilder() gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, - ArgAdapter(gsonSuppl, { ExplOrd.getInstance() }, { explArgAdapterHelper() })) + ArgAdapter(gsonSuppl, { ExplOrd.getInstance() }, { explArgAdapterHelper() }) + ) gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, - TraceAdapter(gsonSuppl, { ExplState::class.java }, SimpleStmtAction::class.java)) + TraceAdapter(gsonSuppl, { ExplState::class.java }, SimpleStmtAction::class.java) + ) gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, - SafetyResultAdapter(gsonSuppl, { explArgHelper() }, { explTraceHelper() })) + SafetyResultAdapter(gsonSuppl, { explArgHelper() }, { explTraceHelper() }) + ) return gsonBuilder } @@ -115,11 +118,14 @@ class TestGson { val gsonBuilder = GsonBuilder() gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, - ArgAdapter(gsonSuppl, { PartialOrd { a, b -> true } }, { predArgAdapterHelper() })) + ArgAdapter(gsonSuppl, { PartialOrd { a, b -> true } }, { predArgAdapterHelper() }) + ) gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, - TraceAdapter(gsonSuppl, { PredState::class.java }, SimpleStmtAction::class.java)) + TraceAdapter(gsonSuppl, { PredState::class.java }, SimpleStmtAction::class.java) + ) gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, - SafetyResultAdapter(gsonSuppl, { predArgHelper() }, { predTraceHelper() })) + SafetyResultAdapter(gsonSuppl, { predArgHelper() }, { predTraceHelper() }) + ) return gsonBuilder } @@ -133,8 +139,10 @@ class TestGson { val env = Env() env.define(symbol, x) - gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, - VarDeclAdapter(gsonSuppl, scope, env, false)) + gsonBuilder.registerTypeHierarchyAdapter( + VarDecl::class.java, + VarDeclAdapter(gsonSuppl, scope, env, false) + ) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -144,8 +152,10 @@ class TestGson { gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) - gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, - PredStateAdapter(gsonSuppl, scope, env)) + gsonBuilder.registerTypeHierarchyAdapter( + PredState::class.java, + PredStateAdapter(gsonSuppl, scope, env) + ) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter(gsonSuppl)) gsonBuilder.registerTypeHierarchyAdapter(Triple::class.java, TripleAdapter(gsonSuppl)) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter(gsonSuppl)) @@ -194,8 +204,10 @@ class TestGson { gson = getGson(getExplBuilder { gson }) { gson } val trace = Trace.of( - listOf(ExplState.of(ImmutableValuation.builder().put(x, Int(1)).build()), - ExplState.of(ImmutableValuation.builder().put(x, Int(2)).build())), + listOf( + ExplState.of(ImmutableValuation.builder().put(x, Int(1)).build()), + ExplState.of(ImmutableValuation.builder().put(x, Int(2)).build()) + ), listOf(SimpleStmtAction(SkipStmt.getInstance())) ) diff --git a/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt b/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt index ce30555dea..408190e912 100644 --- a/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt +++ b/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt @@ -73,20 +73,28 @@ class MultiNondetDiningPhilosophersTest { val phil3cfa = phil3rawCfa.copyWithReplacingVars(variables.associateBy { it.name }) val phil4cfa = phil4rawCfa.copyWithReplacingVars(variables.associateBy { it.name }) - val cfa1ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance()) + val cfa1ConfigBuilder = CfaConfigBuilder( + CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance() + ) cfa1ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa1ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil1cfa) - val cfa2ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance()) + val cfa2ConfigBuilder = CfaConfigBuilder( + CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance() + ) cfa2ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa2ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil2cfa) - val cfa3ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance()) + val cfa3ConfigBuilder = CfaConfigBuilder( + CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance() + ) cfa3ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa3ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil3cfa) - val cfa4ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance()) + val cfa4ConfigBuilder = CfaConfigBuilder( + CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance() + ) cfa4ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa4ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil4cfa) @@ -110,13 +118,15 @@ class MultiNondetDiningPhilosophersTest { var prop: Expr = True() variables.forEach { prop = And(prop, Eq(it.ref, True())) } val dataPredicate = ExplStatePredicate(prop, solver) - val multiConfigBuilder = StmtMultiConfigBuilder.ItpStmtMultiConfigBuilder(totalProduct, prop, + val multiConfigBuilder = StmtMultiConfigBuilder.ItpStmtMultiConfigBuilder( + totalProduct, prop, MultiStatePredicate(dataPredicate), RefToMultiPrec(cfaRefToPrec, cfaRefToPrec, ItpRefToExplPrec()), RefToMultiPrec(cfaRefToPrec, cfaRefToPrec, ItpRefToExplPrec()), ItpRefToExplPrec(), MultiPrec(cfaInitPrec, cfaInitPrec, dataInitPrec), MultiPrec(cfaInitPrec, cfaInitPrec, dataInitPrec), dataInitPrec, Z3LegacySolverFactory.getInstance(), - logger) + logger + ) val result = multiConfigBuilder.build().check() Assertions.assertTrue(result.isUnsafe) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt index 6be63aab98..1f8d894b79 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt @@ -50,8 +50,10 @@ fun CProgram.getStatistics(): CStatistics { fun CFunction.collectStatistics(): Triple { val statisticsCollectorVisitor = StatisticsCollectorVisitor() this.compound?.accept(statisticsCollectorVisitor, Unit) - return Triple(statisticsCollectorVisitor.loopNumber, statisticsCollectorVisitor.deepestLoop, - statisticsCollectorVisitor.linear) + return Triple( + statisticsCollectorVisitor.loopNumber, statisticsCollectorVisitor.deepestLoop, + statisticsCollectorVisitor.linear + ) } fun Expr<*>.isNonLinear(): Boolean { diff --git a/subprojects/frontends/llvm/build.gradle.kts b/subprojects/frontends/llvm/build.gradle.kts index 2d93c23af0..812b35248b 100644 --- a/subprojects/frontends/llvm/build.gradle.kts +++ b/subprojects/frontends/llvm/build.gradle.kts @@ -104,8 +104,10 @@ fun llvmConfigFlags(vararg args: String): Array { fun jniConfigFlags(): Array { if (!taskEnabled) return arrayOf() - val jdkHomeArr = runCommandForOutput("bash", "-c", - "dirname \$(cd \$(dirname \$(readlink -f \$(which javac) || which javac)); pwd -P)") + val jdkHomeArr = runCommandForOutput( + "bash", "-c", + "dirname \$(cd \$(dirname \$(readlink -f \$(which javac) || which javac)); pwd -P)" + ) check(jdkHomeArr.size == 1) val jdkHome = File(jdkHomeArr[0]) check(jdkHome.exists()) @@ -120,11 +122,14 @@ fun jniConfigFlags(): Array { library { targetMachines.add(machines.linux.x86_64) tasks.withType(CppCompile::class) { - compilerArgs.addAll(listOf( - "-Wall", - "-fpic", - *jniConfigFlags(), - *llvmConfigFlags("--cxxflags"))) + compilerArgs.addAll( + listOf( + "-Wall", + "-fpic", + *jniConfigFlags(), + *llvmConfigFlags("--cxxflags") + ) + ) if (!taskEnabled) { println("CppCompile is enabled: $taskEnabled") enabled = false @@ -132,10 +137,13 @@ library { } tasks.withType(LinkSharedLibrary::class) { - linkerArgs.addAll(listOf( - "-rdynamic", - *llvmConfigFlags("--cxxflags", "--ldflags", "--libs", "core", "bitreader"), - "-ldl")) + linkerArgs.addAll( + listOf( + "-rdynamic", + *llvmConfigFlags("--cxxflags", "--ldflags", "--libs", "core", "bitreader"), + "-ldl" + ) + ) if (!taskEnabled) { println("LinkSharedLibrary is enabled: $taskEnabled") enabled = false diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt index facf177953..1869904e1e 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt @@ -110,8 +110,10 @@ abstract class DefaultGraphPatternCompiler : GraphPatternCompiler { override fun compile(pattern: BasicEventSet): T? = null override fun compile(pattern: BasicRelation): T? = null - override fun getCompleteGraph(mcm: Set, - model: Valuation): Pair, Map, ThreeVL>> { + override fun getCompleteGraph( + mcm: Set, + model: Valuation + ): Pair, Map, ThreeVL>> { error("Not implemented") } } \ No newline at end of file diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt index 0490c9f006..fa24ce82cc 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt @@ -59,6 +59,8 @@ interface GraphPatternCompiler { fun compile(pattern: UnionNode): T2 fun compile(pattern: BasicEventSet): T2 fun compile(pattern: BasicRelation): T2 - fun getCompleteGraph(namedPatterns: Set, - model: Valuation): Pair, Map, ThreeVL>> + fun getCompleteGraph( + namedPatterns: Set, + model: Valuation + ): Pair, Map, ThreeVL>> } \ No newline at end of file diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt index 4102e138ff..d6355f1d95 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt @@ -48,8 +48,10 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map, - model: Valuation): Pair, Map, ThreeVL>> { + override fun getCompleteGraph( + namedPatterns: Set, + model: Valuation + ): Pair, Map, ThreeVL>> { val ret = LinkedHashMap, ThreeVL>() ret.putAll(facts) ret.putAll(namedLookup.map { n -> @@ -200,7 +202,8 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map val const = if (pattern.patternName != null) { val const = namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] ?: Const( - "RTC_" + uuid + "_" + a + "_" + b, Bool()) + "RTC_" + uuid + "_" + a + "_" + b, Bool() + ) namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] = const const } else { @@ -263,7 +266,8 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map val const = if (pattern.patternName != null) { val const = namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] ?: Const( - "TC_" + uuid + "_" + a + "_" + b, Bool()) + "TC_" + uuid + "_" + a + "_" + b, Bool() + ) namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] = const const } else { @@ -314,7 +318,8 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map> { return events.associate { a -> - Pair(Tuple1.of(a), + Pair( + Tuple1.of(a), when (facts[Pair(pattern.name, Tuple1.of(a))]) { ThreeVL.FALSE -> False() ThreeVL.TRUE -> True() @@ -323,14 +328,16 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map> { return events.map { a -> events.map { b -> - Pair(Tuple2.of(a, b), + Pair( + Tuple2.of(a, b), when (facts[Pair(pattern.name, Tuple2.of(a, b))]) { ThreeVL.FALSE -> False() ThreeVL.TRUE -> True() @@ -339,7 +346,8 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map { companion object { - private val smallLine: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), - )) + private val smallLine: Pair, Map, ThreeVL>> = Pair( + listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), + ) + ) - private val smallCycle: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), - )) + private val smallCycle: Pair, Map, ThreeVL>> = Pair( + listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), + ) + ) - private val smallFull: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.TRUE), - Pair(Pair("W", Tuple1.of(1)), ThreeVL.TRUE), - Pair(Pair("R", Tuple1.of(2)), ThreeVL.TRUE), - Pair(Pair("F", Tuple1.of(3)), ThreeVL.TRUE), - )) + private val smallFull: Pair, Map, ThreeVL>> = Pair( + listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.TRUE), + Pair(Pair("W", Tuple1.of(1)), ThreeVL.TRUE), + Pair(Pair("R", Tuple1.of(2)), ThreeVL.TRUE), + Pair(Pair("F", Tuple1.of(3)), ThreeVL.TRUE), + ) + ) @Parameterized.Parameters @JvmStatic @@ -102,7 +108,8 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -111,7 +118,8 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -120,7 +128,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -129,7 +138,8 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -138,7 +148,8 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -147,7 +158,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -156,7 +168,8 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -165,7 +178,8 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -174,7 +188,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -183,7 +198,8 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -192,7 +208,8 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -201,7 +218,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -210,7 +228,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -219,7 +238,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), arrayOf( @@ -228,7 +248,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -237,7 +258,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -246,7 +268,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -255,7 +278,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -264,7 +288,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -273,7 +298,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -282,7 +308,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -291,7 +318,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -300,7 +328,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -309,7 +338,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -318,7 +348,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -327,7 +358,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -336,7 +368,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), true ), arrayOf( @@ -345,7 +378,8 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver()), + Z3LegacySolverFactory.getInstance().createSolver() + ), false ), ) diff --git a/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt b/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt index 9383d479b8..e1c2533a6d 100644 --- a/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt +++ b/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt @@ -126,8 +126,11 @@ class GenericSmtLibHornSolverTest { App( App( model.get(init.constDecl) as FuncLitExpr>, - p0.ref), - p1.ref)) + p0.ref + ), + p1.ref + ) + ) checkerSolver.add(Lt(p1.ref, Int(0))) Assertions.assertTrue(checkerSolver.check().isUnsat) diff --git a/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt b/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt index 859165d9cf..eafd44ec12 100644 --- a/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt +++ b/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt @@ -85,8 +85,11 @@ class Z3HornSolverTest { App( App( model.get(init.constDecl) as FuncLitExpr>, - p0.ref), - p1.ref)) + p0.ref + ), + p1.ref + ) + ) checkerSolver.add(Lt(p1.ref, Int(0))) Assertions.assertTrue(checkerSolver.check().isUnsat) diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index d82a92fa4a..a015c6ce1d 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -54,16 +54,20 @@ import org.abego.treelayout.internal.util.Contract.checkState import java.math.BigInteger import java.util.stream.Collectors -class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boolean = false, - val uniqueWarningLogger: Logger) : +class FrontendXcfaBuilder( + val parseContext: ParseContext, val checkOverflow: Boolean = false, + val uniqueWarningLogger: Logger +) : CStatementVisitorBase() { private val locationLut: MutableMap = LinkedHashMap() private var ptrCnt = 1 // counts up, uses 3k+1 get() = field.also { field += 3 } - private fun getLoc(builder: XcfaProcedureBuilder, name: String?, - metadata: MetaData): XcfaLocation { + private fun getLoc( + builder: XcfaProcedureBuilder, name: String?, + metadata: MetaData + ): XcfaLocation { if (name == null) return getAnonymousLoc(builder, metadata = metadata) locationLut.putIfAbsent(name, XcfaLocation(name, metadata = metadata)) val location = locationLut[name] @@ -100,40 +104,64 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo } builder.addVar(XcfaGlobalVar(globalDeclaration.get2(), type.nullValue)) if (type is CArray) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type)) - )) + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type) + ) + ) + ) } else { if (globalDeclaration.get1().initExpr != null && globalDeclaration.get1().initExpr.expression !is UnsupportedInitializer) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.castTo(globalDeclaration.get1().initExpr.expression), - globalDeclaration.get2().type)) - )) + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast( + type.castTo(globalDeclaration.get1().initExpr.expression), + globalDeclaration.get2().type + ) + ) + ) + ) } else { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.nullValue, globalDeclaration.get2().type)) - )) + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.nullValue, globalDeclaration.get2().type) + ) + ) + ) } } if (globalDeclaration.get1().arrayDimensions.size == 1) { - val bounds = ExprUtils.simplify(CComplexType.getUnsignedLong(parseContext) - .castTo(globalDeclaration.get1().arrayDimensions[0].expression)) - checkState(bounds is IntLitExpr || bounds is BvLitExpr, - "Only IntLit and BvLit expression expected here.") - val literalValue = if (bounds is IntLitExpr) bounds.value.toLong() else BvUtils.neutralBvLitExprToBigInteger( - bounds as BvLitExpr).toLong() + val bounds = ExprUtils.simplify( + CComplexType.getUnsignedLong(parseContext) + .castTo(globalDeclaration.get1().arrayDimensions[0].expression) + ) + checkState( + bounds is IntLitExpr || bounds is BvLitExpr, + "Only IntLit and BvLit expression expected here." + ) + val literalValue = + if (bounds is IntLitExpr) bounds.value.toLong() else BvUtils.neutralBvLitExprToBigInteger( + bounds as BvLitExpr + ).toLong() val literalToExpr = { x: Long -> if (bounds is IntLitExpr) IntLitExpr.of( - BigInteger.valueOf(x)) else BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.valueOf(x), - (bounds as BvLitExpr).type.size) + BigInteger.valueOf(x) + ) else BvUtils.bigIntegerToNeutralBvLitExpr( + BigInteger.valueOf(x), + (bounds as BvLitExpr).type.size + ) } - val initExprs: Map> = (globalDeclaration.get1()?.initExpr as? CInitializerList)?.statements?.mapIndexed { i, it -> - Pair(i, it.get2().expression) - }?.toMap() ?: emptyMap() + val initExprs: Map> = + (globalDeclaration.get1()?.initExpr as? CInitializerList)?.statements?.mapIndexed { i, it -> + Pair(i, it.get2().expression) + }?.toMap() ?: emptyMap() for (i in 0 until literalValue) { checkState(globalDeclaration.get1().actualType is CArray, "Only arrays are expected here") val embeddedType = (globalDeclaration.get1().actualType as CArray).embeddedType @@ -155,8 +183,10 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo return builder } - private fun handleFunction(function: CFunction, param: List, - xcfaBuilder: XcfaBuilder): XcfaProcedureBuilder { + private fun handleFunction( + function: CFunction, param: List, + xcfaBuilder: XcfaBuilder + ): XcfaProcedureBuilder { locationLut.clear() val flatVariables = function.flatVariables val funcDecl = function.funcDecl @@ -183,7 +213,8 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo for (functionParam in funcDecl.functionParams) { Preconditions.checkState( functionParam.actualType is CVoid || functionParam.varDecls.size > 0, - "Function param should have an associated variable!") + "Function param should have an associated variable!" + ) for (varDecl in functionParam.varDecls) { if (varDecl != null) builder.addParam(varDecl, ParamDirection.IN) } @@ -193,10 +224,14 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addVar(flatVariable) val type = CComplexType.getType(flatVariable.ref, parseContext) if ((type is CArray || type is CStruct) && builder.getParams().none { it.first == flatVariable }) { - initStmtList.add(StmtLabel( - Stmts.Assign(cast(flatVariable, flatVariable.type), - cast(type.getValue("$ptrCnt"), flatVariable.type)) - )) + initStmtList.add( + StmtLabel( + Stmts.Assign( + cast(flatVariable, flatVariable.type), + cast(type.getValue("$ptrCnt"), flatVariable.type) + ) + ) + ) } } builder.createInitLoc(getMetadata(function)) @@ -212,8 +247,10 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo val endinit = getAnonymousLoc(builder, getMetadata(function)) builder.addLoc(endinit) - val initEdge = XcfaEdge(init, endinit, SequenceLabel(initStmtList), - metadata = getMetadata(function)) + val initEdge = XcfaEdge( + init, endinit, SequenceLabel(initStmtList), + metadata = getMetadata(function) + ) builder.addEdge(initEdge) init = endinit builder.createFinalLoc(getMetadata(function)) @@ -257,10 +294,13 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo } is RefExpr<*> -> { - StmtLabel(Stmts.Assign( - cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), - cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type)), - metadata = getMetadata(statement)) + StmtLabel( + Stmts.Assign( + cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), + cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type) + ), + metadata = getMetadata(statement) + ) } else -> { @@ -281,17 +321,23 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo xcfaEdge = XcfaEdge(initLoc, middleLoc1, label, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(middleLoc1, location, + xcfaEdge = XcfaEdge( + middleLoc1, location, StmtLabel(type.limit(lhs.ref), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) + metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(middleLoc1, middleLoc2, + xcfaEdge = XcfaEdge( + middleLoc1, middleLoc2, StmtLabel(Assume(Not(type.limit(lhs.ref).cond)), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) + metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge(middleLoc2, location, + xcfaEdge = XcfaEdge( + middleLoc2, location, InvokeLabel("overflow", listOf(), metadata = getMetadata(statement)), - metadata = getMetadata(statement)) + metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) } return location @@ -309,11 +355,13 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addEdge(xcfaEdge) val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(location) - xcfaEdge = XcfaEdge(initLoc, location, StmtLabel( - statement.assumeStmt, - choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(statement) - ), metadata = getMetadata(statement)) + xcfaEdge = XcfaEdge( + initLoc, location, StmtLabel( + statement.assumeStmt, + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(statement) + ), metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) return location } @@ -330,8 +378,10 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addEdge(edge) check(breakLoc != null) edge = XcfaEdge(initLoc, breakLoc, metadata = getMetadata(statement)) - val unreachableLoc = XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), - metadata = getMetadata(statement)) + val unreachableLoc = XcfaLocation( + "Unreachable" + XcfaLocation.uniqueCounter(), + metadata = getMetadata(statement) + ) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -355,8 +405,10 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addVar(ret) params.add(ret.ref) for (cStatement in myParams) { - initLoc = cStatement.accept(this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) + initLoc = cStatement.accept( + this, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) + ) } params.addAll(myParams.stream().map { obj: CStatement -> obj.expression } .collect(Collectors.toList())) @@ -388,14 +440,20 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (preStatements != null) lastLoc = preStatements.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) for (cStatement in statement.getcStatementList()) { - if (cStatement != null) lastLoc = cStatement.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (cStatement != null) lastLoc = cStatement.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) } - if (postStatements != null) lastLoc = postStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (postStatements != null) lastLoc = postStatements.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) return lastLoc } @@ -412,7 +470,8 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo check(continueLoc != null) edge = XcfaEdge(initLoc, continueLoc, metadata = getMetadata(statement)) val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) + "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement) + ) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -447,26 +506,40 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(initLoc) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastBody = body.accept(this, - ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc)) + val lastBody = body.accept( + this, + ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc) + ) xcfaEdge = XcfaEdge(lastBody, innerEndLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastPre = buildWithoutPostStatement(guard, - ParamPack(builder, innerEndLoc, null, null, returnLoc)) - val assume = StmtLabel(Stmts.Assume( - AbstractExprs.Neq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard)) + val lastPre = buildWithoutPostStatement( + guard, + ParamPack(builder, innerEndLoc, null, null, returnLoc) + ) + val assume = StmtLabel( + Stmts.Assume( + AbstractExprs.Neq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue) + ), + choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) + ) xcfaEdge = XcfaEdge(lastPre, innerInnerGuard, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val assume1 = StmtLabel(Stmts.Assume( - AbstractExprs.Eq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), - choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard)) + val assume1 = StmtLabel( + Stmts.Assume( + AbstractExprs.Eq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue) + ), + choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard) + ) xcfaEdge = XcfaEdge(lastPre, outerInnerGuard, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val outerLastGuard = buildPostStatement(guard, - ParamPack(builder, outerInnerGuard, null, null, null)) - val innerLastGuard = buildPostStatement(guard, - ParamPack(builder, innerInnerGuard, null, null, null)) + val outerLastGuard = buildPostStatement( + guard, + ParamPack(builder, outerInnerGuard, null, null, null) + ) + val innerLastGuard = buildPostStatement( + guard, + ParamPack(builder, innerInnerGuard, null, null, null) + ) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) xcfaEdge = XcfaEdge(innerLastGuard, initLoc, metadata = getMetadata(statement)) @@ -505,13 +578,21 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(startIncrement) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastInit = if (init == null) initLoc else init.accept(this, - ParamPack(builder, initLoc, null, null, returnLoc)) - val lastTest = if (guard == null) lastInit else buildWithoutPostStatement(guard, - ParamPack(builder, lastInit!!, null, null, returnLoc)) + val lastInit = if (init == null) initLoc else init.accept( + this, + ParamPack(builder, initLoc, null, null, returnLoc) + ) + val lastTest = if (guard == null) lastInit else buildWithoutPostStatement( + guard, + ParamPack(builder, lastInit!!, null, null, returnLoc) + ) val assume = StmtLabel( - Stmts.Assume(if (guard == null) True() else AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + if (guard == null) True() else AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.MAIN_PATH, metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) ) @@ -519,30 +600,42 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo xcfaEdge = XcfaEdge(lastTest, endInit, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume(if (guard == null) False() else AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + if (guard == null) False() else AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) ) xcfaEdge = XcfaEdge(lastTest, outerLastTest, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val innerLastGuard = if (guard == null) endInit else buildPostStatement(guard, - ParamPack(builder, endInit, endLoc, startIncrement, returnLoc)) - val lastBody = if (body == null) innerLastGuard else body.accept(this, - ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc)) + val innerLastGuard = if (guard == null) endInit else buildPostStatement( + guard, + ParamPack(builder, endInit, endLoc, startIncrement, returnLoc) + ) + val lastBody = if (body == null) innerLastGuard else body.accept( + this, + ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc) + ) xcfaEdge = XcfaEdge(lastBody, startIncrement, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) if (increment != null) { - val lastIncrement = increment.accept(this, - ParamPack(builder, startIncrement, null, null, returnLoc)) + val lastIncrement = increment.accept( + this, + ParamPack(builder, startIncrement, null, null, returnLoc) + ) xcfaEdge = XcfaEdge(lastIncrement, lastInit, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else { xcfaEdge = XcfaEdge(startIncrement, lastInit, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - val outerLastGuard = if (guard == null) outerLastTest else buildPostStatement(guard, - ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc)) + val outerLastGuard = if (guard == null) outerLastTest else buildPostStatement( + guard, + ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc) + ) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) return endLoc @@ -558,11 +651,14 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(initLoc) var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) - edge = XcfaEdge(initLoc, - getLoc(builder, statement.label, metadata = getMetadata(statement))) + edge = XcfaEdge( + initLoc, + getLoc(builder, statement.label, metadata = getMetadata(statement)) + ) builder.addLoc(getLoc(builder, statement.label, metadata = getMetadata(statement))) val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) + "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement) + ) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -587,33 +683,51 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(initLoc) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val endGuard = buildWithoutPostStatement(guard, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) + val endGuard = buildWithoutPostStatement( + guard, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) + ) val assume = StmtLabel( - Stmts.Assume(AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(endGuard, mainBranch, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume(AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(endGuard, elseBranch, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val mainAfterGuard = buildPostStatement(guard, - ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc)) - val mainEnd = body.accept(this, - ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc)) + val mainAfterGuard = buildPostStatement( + guard, + ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc) + ) + val mainEnd = body.accept( + this, + ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc) + ) if (elseStatement != null) { - val elseAfterGuard = buildPostStatement(guard, - ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc)) - val elseEnd = elseStatement.accept(this, - ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc)) + val elseAfterGuard = buildPostStatement( + guard, + ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc) + ) + val elseEnd = elseStatement.accept( + this, + ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc) + ) xcfaEdge = XcfaEdge(elseEnd, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else { @@ -649,16 +763,24 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(initLoc) val xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val endExpr = expr?.accept(this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) ?: initLoc + val endExpr = expr?.accept( + this, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) + ) ?: initLoc val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(endLoc) val key: VarDecl<*> = builder.getParams()[0].first check(returnLoc != null) val type = CComplexType.getType(key.ref, parseContext) - val edge = XcfaEdge(endExpr, returnLoc, StmtLabel(Stmts.Assign(cast(key, key.type), - cast(type.castTo(expr?.expression ?: type.nullValue), key.type)), - metadata = getMetadata(statement)), metadata = getMetadata(statement)) + val edge = XcfaEdge( + endExpr, returnLoc, StmtLabel( + Stmts.Assign( + cast(key, key.type), + cast(type.castTo(expr?.expression ?: type.nullValue), key.type) + ), + metadata = getMetadata(statement) + ), metadata = getMetadata(statement) + ) builder.addEdge(edge) return endLoc } @@ -677,14 +799,18 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addLoc(endLoc) val edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) - val endInit = buildWithoutPostStatement(testValue, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) + val endInit = buildWithoutPostStatement( + testValue, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) + ) Preconditions.checkState(body is CCompound, "Switch body has to be a CompoundStatement!") var defaultExpr: Expr? = True() for (cStatement in (body as CCompound).getcStatementList()) { if (cStatement is CCase) { - defaultExpr = BoolExprs.And(defaultExpr, - AbstractExprs.Neq(testValue.expression, cStatement.expr.expression)) + defaultExpr = BoolExprs.And( + defaultExpr, + AbstractExprs.Neq(testValue.expression, cStatement.expr.expression) + ) } } var lastLocation: XcfaLocation? = null @@ -697,19 +823,24 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo builder.addEdge(xcfaEdge) } if (cStatement is CCase) { - val afterGuard = buildPostStatement(testValue, - ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc)) + val afterGuard = buildPostStatement( + testValue, + ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc) + ) val assume = StmtLabel( Stmts.Assume( - AbstractExprs.Eq(testValue.expression, cStatement.expr.expression)), + AbstractExprs.Eq(testValue.expression, cStatement.expr.expression) + ), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(testValue) ) xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else if (cStatement is CDefault) { - val afterGuard = buildPostStatement(testValue, - ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc)) + val afterGuard = buildPostStatement( + testValue, + ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc) + ) val assume = StmtLabel( Stmts.Assume(defaultExpr), choiceType = ChoiceType.MAIN_PATH, // TODO: is this what validators expect? @@ -718,12 +849,16 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - lastLocation = cStatement.accept(this, - ParamPack(builder, location, endLoc, continueLoc, returnLoc)) + lastLocation = cStatement.accept( + this, + ParamPack(builder, location, endLoc, continueLoc, returnLoc) + ) } if (lastLocation != null) { - val xcfaEdge: XcfaEdge = XcfaEdge(lastLocation, endLoc, - metadata = getMetadata(statement)) + val xcfaEdge: XcfaEdge = XcfaEdge( + lastLocation, endLoc, + metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) } return endLoc @@ -749,46 +884,66 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo for (i in 0 until if (UNROLL_COUNT == 0) 1 else UNROLL_COUNT) { val innerLoop = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(innerLoop) - val testEndLoc = buildWithoutPostStatement(guard, - ParamPack(builder, initLoc, null, null, returnLoc)) + val testEndLoc = buildWithoutPostStatement( + guard, + ParamPack(builder, initLoc, null, null, returnLoc) + ) if (UNROLL_COUNT > 0) { initLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(initLoc) } val assume = StmtLabel( - Stmts.Assume(AbstractExprs.Neq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + AbstractExprs.Neq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(testEndLoc, innerLoop, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume(AbstractExprs.Eq(guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue)), + Stmts.Assume( + AbstractExprs.Eq( + guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue + ) + ), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(statement) ) - xcfaEdge = XcfaEdge(testEndLoc, outerBeforeGuard, assume1, - metadata = getMetadata(statement)) + xcfaEdge = XcfaEdge( + testEndLoc, outerBeforeGuard, assume1, + metadata = getMetadata(statement) + ) builder.addEdge(xcfaEdge) - val lastGuard = buildPostStatement(guard, - ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc)) - val lastBody = body.accept(this, - ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc)) + val lastGuard = buildPostStatement( + guard, + ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc) + ) + val lastBody = body.accept( + this, + ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc) + ) xcfaEdge = XcfaEdge(lastBody, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - val outerLastGuard = buildPostStatement(guard, - ParamPack(builder, outerBeforeGuard, null, null, null)) + val outerLastGuard = buildPostStatement( + guard, + ParamPack(builder, outerBeforeGuard, null, null, null) + ) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) return endLoc } private fun buildWithoutPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState(cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!") + Preconditions.checkState( + cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!" + ) val statement = cStatement as CCompound val builder: XcfaProcedureBuilder = param.builder var lastLoc = param.lastLoc @@ -803,28 +958,38 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (preStatements != null) lastLoc = preStatements.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) for (i in 0 until cStatementList.size - 1) { val stmt = cStatementList[i] - if (stmt != null) lastLoc = stmt.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + if (stmt != null) lastLoc = stmt.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) } if (cStatementList.size == 0) return lastLoc val lastStatement = cStatementList[cStatementList.size - 1] lastLoc = if (postStatements == null) { - buildWithoutPostStatement(lastStatement, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + buildWithoutPostStatement( + lastStatement, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) } else { - lastStatement.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + lastStatement.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) } return lastLoc } private fun buildPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState(cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!") + Preconditions.checkState( + cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!" + ) val statement = cStatement as CCompound val builder: XcfaProcedureBuilder = param.builder var lastLoc = param.lastLoc @@ -834,15 +999,20 @@ class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boo val preStatements = statement.preStatements val postStatements = statement.postStatements val cStatementList = statement.getcStatementList() - lastLoc = if (postStatements != null) postStatements.accept(this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) else buildPostStatement( + lastLoc = if (postStatements != null) postStatements.accept( + this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) else buildPostStatement( cStatementList[cStatementList.size - 1], - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) + ) return lastLoc } - class ParamPack(builder: XcfaProcedureBuilder, lastLoc: XcfaLocation, breakLoc: XcfaLocation?, - continueLoc: XcfaLocation?, returnLoc: XcfaLocation?) { + class ParamPack( + builder: XcfaProcedureBuilder, lastLoc: XcfaLocation, breakLoc: XcfaLocation?, + continueLoc: XcfaLocation?, returnLoc: XcfaLocation? + ) { val builder: XcfaProcedureBuilder val lastLoc: XcfaLocation diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt index 40d06bd9c1..d1faac52da 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt @@ -30,8 +30,10 @@ import org.antlr.v4.runtime.CharStreams import org.antlr.v4.runtime.CommonTokenStream import java.io.InputStream -fun getXcfaFromC(stream: InputStream, parseContext: ParseContext, collectStatistics: Boolean, - checkOverflow: Boolean, warningLogger: Logger): Triple?> { +fun getXcfaFromC( + stream: InputStream, parseContext: ParseContext, collectStatistics: Boolean, + checkOverflow: Boolean, warningLogger: Logger +): Triple?> { val input = CharStreams.fromStream(stream) val lexer = CLexer(input) val tokens = CommonTokenStream(lexer) diff --git a/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt b/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt index 6fc85e623d..861ba376b5 100644 --- a/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt +++ b/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt @@ -238,7 +238,8 @@ class CatVisitor(file: File) : CatBaseVisitor() { override fun visitExprComplement(ctx: ExprComplementContext): GraphPattern { val rel = ctx.e.accept(this) return if (rel is EdgePattern) Complement(rel) else if (rel is NodePattern) ComplementNode(rel) else error( - "Mismatched types") + "Mismatched types" + ) } override fun visitExprInverse(ctx: ExprInverseContext): GraphPattern { diff --git a/subprojects/xcfa/llvm2xcfa/build.gradle.kts b/subprojects/xcfa/llvm2xcfa/build.gradle.kts index 1888b50a11..874d563124 100644 --- a/subprojects/xcfa/llvm2xcfa/build.gradle.kts +++ b/subprojects/xcfa/llvm2xcfa/build.gradle.kts @@ -36,7 +36,9 @@ tasks.test { } val linkTask = task.first() dependsOn(linkTask) - systemProperty("java.library.path", - linkTask.linkedFile.get().asFile.parent + ":/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib") + systemProperty( + "java.library.path", + linkTask.linkedFile.get().asFile.parent + ":/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib" + ) } } diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt index cf5d298dab..4f9bbd7bee 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt @@ -52,7 +52,8 @@ private fun S.getState(varLookup: Map, VarDecl<*>>): is PredState -> PredState.of(preds.map { p -> p.changeVars(varLookup) }) is PtrState<*> -> PtrState(innerState.getState(varLookup)) else -> throw NotImplementedError( - "Generalizing variable instances is not implemented for data states that are not explicit or predicate.") + "Generalizing variable instances is not implemented for data states that are not explicit or predicate." + ) } as S class LazyDelegate(val getProperty: T.() -> P) { diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt index d17f15fda1..0e2d35e29c 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt @@ -122,13 +122,14 @@ class XcfaAbstractor( companion object { fun builder( - argBuilder: ArgBuilder): BasicAbstractor.Builder { + argBuilder: ArgBuilder + ): BasicAbstractor.Builder { return Builder(argBuilder) } } - class Builder(argBuilder: ArgBuilder) - : BasicAbstractor.Builder(argBuilder) { + class Builder(argBuilder: ArgBuilder) : + BasicAbstractor.Builder(argBuilder) { override fun build(): BasicAbstractor { return XcfaAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt index 82a8e65178..798886422e 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt @@ -24,8 +24,10 @@ import hu.bme.mit.theta.xcfa.passes.flatten data class XcfaAction @JvmOverloads -constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTriples = emptyMap(), - private val nextCnt: Int = 0) : +constructor( + val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTriples = emptyMap(), + private val nextCnt: Int = 0 +) : PtrAction(lastWrites, nextCnt) { val source: XcfaLocation = edge.source @@ -33,12 +35,14 @@ constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTripl val label: XcfaLabel = edge.label private val stmts: List = label.toStmt().flatten() - constructor(pid: Int, + constructor( + pid: Int, source: XcfaLocation, target: XcfaLocation, label: XcfaLabel = NopLabel, lastWrites: WriteTriples = emptyMap(), - nextCnt: Int = 0) : + nextCnt: Int = 0 + ) : this(pid, XcfaEdge(source, target, label), lastWrites, nextCnt) override val stmtList: List diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt index 64bd2e3d62..d630b6ac06 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt @@ -60,7 +60,8 @@ open class XcfaAnalysis( ) : Analysis>, XcfaAction, XcfaPrec

> { init { - ConeOfInfluence.coreTransFunc = transFunc as TransFunc>, XcfaAction, XcfaPrec> + ConeOfInfluence.coreTransFunc = + transFunc as TransFunc>, XcfaAction, XcfaPrec> coreTransFunc = ConeOfInfluence.transFunc as TransFunc>, XcfaAction, XcfaPrec

> } @@ -74,14 +75,28 @@ private var tempCnt: Int = 0 fun getCoreXcfaLts() = LTS>, XcfaAction> { s -> s.processes.map { proc -> if (proc.value.locs.peek().final) { - listOf(XcfaAction(proc.key, - XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), SequenceLabel(listOf( - proc.value.paramStmts.peek().second, - ReturnLabel(proc.value.returnStmts.peek()), - ))), nextCnt = s.sGlobal.nextCnt)) + listOf( + XcfaAction( + proc.key, + XcfaEdge( + proc.value.locs.peek(), proc.value.locs.peek(), SequenceLabel( + listOf( + proc.value.paramStmts.peek().second, + ReturnLabel(proc.value.returnStmts.peek()), + ) + ) + ), nextCnt = s.sGlobal.nextCnt + ) + ) } else if (!proc.value.paramsInitialized) { - listOf(XcfaAction(proc.key, XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), - proc.value.paramStmts.peek().first), nextCnt = s.sGlobal.nextCnt)) + listOf( + XcfaAction( + proc.key, XcfaEdge( + proc.value.locs.peek(), proc.value.locs.peek(), + proc.value.paramStmts.peek().first + ), nextCnt = s.sGlobal.nextCnt + ) + ) } else { proc.value.locs.peek().outgoingEdges.map { edge -> val newLabel = edge.label.changeVars(proc.value.varLookup.peek()) @@ -95,15 +110,21 @@ fun getCoreXcfaLts() = LTS>, XcfaAction> { SequenceLabel(listOf(procedure.params.withIndex() .filter { it.value.second != ParamDirection.OUT }.map { iVal -> val originalVar = iVal.value.first - val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, - originalVar.type) + val tempVar = Var( + "tmp${tempCnt++}_" + originalVar.name, + originalVar.type + ) lookup[originalVar] = tempVar StmtLabel( Stmts.Assign( TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type)), - metadata = label.metadata) - }, listOf(label.copy(tempLookup = lookup))).flatten()) + TypeUtils.cast(label.params[iVal.index], tempVar.type) + ), + metadata = label.metadata + ) + }, listOf(label.copy(tempLookup = lookup)) + ).flatten() + ) } else if (label is StartLabel) { val procedure = s.xcfa?.procedures?.find { proc -> proc.name == label.name } ?: error("No such method ${label.name}.") @@ -111,22 +132,28 @@ fun getCoreXcfaLts() = LTS>, XcfaAction> { SequenceLabel(listOf(procedure.params.withIndex() .filter { it.value.second != ParamDirection.OUT }.mapNotNull { iVal -> val originalVar = iVal.value.first - val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, - originalVar.type) + val tempVar = Var( + "tmp${tempCnt++}_" + originalVar.name, + originalVar.type + ) lookup[originalVar] = tempVar val trial = Try.attempt { StmtLabel( Stmts.Assign( TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type)), - metadata = label.metadata) + TypeUtils.cast(label.params[iVal.index], tempVar.type) + ), + metadata = label.metadata + ) } if (trial.isSuccess) { trial.asSuccess().value } else { null } - }, listOf(label.copy(tempLookup = lookup))).flatten()) + }, listOf(label.copy(tempLookup = lookup)) + ).flatten() + ) } else label }) XcfaAction(proc.key, edge.withLabel(newNewLabel), nextCnt = s.sGlobal.nextCnt) @@ -152,7 +179,8 @@ enum class ErrorDetection { } fun getXcfaErrorPredicate( - errorDetection: ErrorDetection): Predicate>> = when (errorDetection) { + errorDetection: ErrorDetection +): Predicate>> = when (errorDetection) { ErrorDetection.ERROR_LOCATION -> Predicate>> { s -> s.processes.any { it.value.locs.peek().error } } @@ -185,11 +213,14 @@ fun getXcfaErrorPredicate( fun getPartialOrder(partialOrd: PartialOrd>) = PartialOrd>> { s1, s2 -> s1.processes == s2.processes && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes && partialOrd.isLeq( - s1.sGlobal, s2.sGlobal) + s1.sGlobal, s2.sGlobal + ) } -private fun stackIsLeq(s1: XcfaState>, - s2: XcfaState>) = s2.processes.keys.all { pid -> +private fun stackIsLeq( + s1: XcfaState>, + s2: XcfaState> +) = s2.processes.keys.all { pid -> s1.processes[pid]?.let { ps1 -> val ps2 = s2.processes.getValue(pid) ps1.locs.peek() == ps2.locs.peek() && ps1.paramsInitialized && ps2.paramsInitialized @@ -198,15 +229,18 @@ private fun stackIsLeq(s1: XcfaState>, fun getStackPartialOrder(partialOrd: PartialOrd>) = PartialOrd>> { s1, s2 -> - s1.processes.size == s2.processes.size && stackIsLeq(s1, - s2) && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes + s1.processes.size == s2.processes.size && stackIsLeq( + s1, + s2 + ) && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes && partialOrd.isLeq(s1.withGeneralizedVars(), s2.withGeneralizedVars()) } private fun >, P : XcfaPrec> getXcfaArgBuilder( analysis: Analysis, lts: LTS>, XcfaAction>, - errorDetection: ErrorDetection) + errorDetection: ErrorDetection +) : ArgBuilder = ArgBuilder.create( lts, @@ -233,13 +267,19 @@ fun >, P : XcfaPrec> getXcfa /// EXPL -private fun getExplXcfaInitFunc(xcfa: XCFA, - solver: Solver): (XcfaPrec>) -> List>> { +private fun getExplXcfaInitFunc( + xcfa: XCFA, + solver: Solver +): (XcfaPrec>) -> List>> { val processInitState = xcfa.initProcedures.mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) + Pair( + i, XcfaProcessState( + initLocStack, prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))) + ) + ) }.toMap() return { p -> ExplInitFunc.create(solver, True()).getPtrInitFunc().getInitStates(p.p) @@ -248,19 +288,28 @@ private fun getExplXcfaInitFunc(xcfa: XCFA, } private fun getExplXcfaTransFunc(solver: Solver, maxEnum: Int, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { - val explTransFunc = (ExplStmtTransFunc.create(solver, - maxEnum) as TransFunc).getPtrTransFunc(isHavoc) + (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { + val explTransFunc = (ExplStmtTransFunc.create( + solver, + maxEnum + ) as TransFunc).getPtrTransFunc(isHavoc) return { s, a, p -> val (newSt, newAct) = s.apply(a) - explTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( - listOf(s.processes.map { it.value.varLookup }.flatten(), - listOf(getTempLookup(a.label))).flatten())).map { newSt.withState(it) } + explTransFunc.getSuccStates( + newSt.sGlobal, newAct, p.p.addVars( + listOf( + s.processes.map { it.value.varLookup }.flatten(), + listOf(getTempLookup(a.label)) + ).flatten() + ) + ).map { newSt.withState(it) } } } -class ExplXcfaAnalysis(xcfa: XCFA, solver: Solver, maxEnum: Int, - partialOrd: PartialOrd>>, isHavoc: Boolean) : +class ExplXcfaAnalysis( + xcfa: XCFA, solver: Solver, maxEnum: Int, + partialOrd: PartialOrd>>, isHavoc: Boolean +) : XcfaAnalysis>( corePartialOrd = partialOrd, coreInitFunc = getExplXcfaInitFunc(xcfa, solver), @@ -269,13 +318,19 @@ class ExplXcfaAnalysis(xcfa: XCFA, solver: Solver, maxEnum: Int, /// PRED -private fun getPredXcfaInitFunc(xcfa: XCFA, - predAbstractor: PredAbstractor): (XcfaPrec>) -> List>> { +private fun getPredXcfaInitFunc( + xcfa: XCFA, + predAbstractor: PredAbstractor +): (XcfaPrec>) -> List>> { val processInitState = xcfa.initProcedures.mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) + Pair( + i, XcfaProcessState( + initLocStack, prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))) + ) + ) }.toMap() return { p -> PredInitFunc.create(predAbstractor, True()).getPtrInitFunc().getInitStates(p.p) @@ -284,9 +339,10 @@ private fun getPredXcfaInitFunc(xcfa: XCFA, } private fun getPredXcfaTransFunc(predAbstractor: PredAbstractors.PredAbstractor, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { + (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { val predTransFunc = (PredTransFunc.create( - predAbstractor) as TransFunc).getPtrTransFunc(isHavoc) + predAbstractor + ) as TransFunc).getPtrTransFunc(isHavoc) return { s, a, p -> val (newSt, newAct) = s.apply(a) predTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( @@ -295,8 +351,10 @@ private fun getPredXcfaTransFunc(predAbstractor: PredAbstractors.PredAbstractor, } } -class PredXcfaAnalysis(xcfa: XCFA, solver: Solver, predAbstractor: PredAbstractor, - partialOrd: PartialOrd>>, isHavoc: Boolean) : +class PredXcfaAnalysis( + xcfa: XCFA, solver: Solver, predAbstractor: PredAbstractor, + partialOrd: PartialOrd>>, isHavoc: Boolean +) : XcfaAnalysis>( corePartialOrd = partialOrd, coreInitFunc = getPredXcfaInitFunc(xcfa, predAbstractor), diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt index 64e8984d4d..40cea2bc74 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt @@ -37,8 +37,10 @@ class XcfaPrecRefiner(refToPrec: Refuta private val refToPrec: RefutationToPrec, R> = Preconditions.checkNotNull(refToPrec) - override fun refine(prec: XcfaPrec>, trace: Trace, XcfaAction>, - refutation: R): XcfaPrec> { + override fun refine( + prec: XcfaPrec>, trace: Trace, XcfaAction>, + refutation: R + ): XcfaPrec> { Preconditions.checkNotNull(trace) Preconditions.checkNotNull(prec) Preconditions.checkNotNull(refutation) @@ -48,7 +50,8 @@ class XcfaPrecRefiner(refToPrec: Refuta it.foldVarLookup().map { Pair(it.value, it.key) } }.flatten().toMap() val reverseTempLookup = if (i > 0) getTempLookup( - trace.actions[i - 1].edge.label).entries.associateBy( + trace.actions[i - 1].edge.label + ).entries.associateBy( { it.value }) { it.key } else emptyMap() val precFromRef = refToPrec.toPrec(refutation, i).changeVars(reverseVarLookup + reverseTempLookup) runningPrec = refToPrec.join(runningPrec, precFromRef) @@ -83,10 +86,12 @@ fun

P.addVars(lookups: Collection, VarDecl<*>>>): P = else when (this) { is ExplPrec -> ExplPrec.of( - vars.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten()) as P + vars.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten() + ) as P is PredPrec -> PredPrec.of( - preds.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten()) as P + preds.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten() + ) as P is PtrPrec<*> -> PtrPrec(innerPrec.addVars(lookups)) as P diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt index ad0a385e5d..878e2a3964 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt @@ -72,15 +72,20 @@ class XcfaSingleExprTraceRefiner, states: List, actions: List): Triple, List, List>, a: A -> + Triple( + Pair(emptyMap(), 0), listOf(rawTrace.getState(0)), + listOf() + ) + ) { i: Int, (wTripleCnt: Pair, states: List, actions: List): Triple, List, List>, a: A -> val (wTriple, cnt) = wTripleCnt val newA = (a as XcfaAction).withLastWrites(wTriple, cnt) val newState = (rawTrace.getState(i + 1) as XcfaState>).let { it.withState(PtrState(it.sGlobal.innerState.patch(newA.nextWriteTriples()))) } - Triple(Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), states + (newState as S), - actions + (newA as A)) + Triple( + Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), states + (newState as S), + actions + (newA as A) + ) } val traceToConcretize = Trace.of(states, actions) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt index 0054be37f2..c75bcefd8e 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt @@ -52,8 +52,10 @@ data class XcfaState @JvmOverloads constructor( fun apply(a: XcfaAction): Pair, XcfaAction> { val changes: MutableList<(XcfaState) -> XcfaState> = ArrayList() - if (mutexes[""] != null && mutexes[""] != a.pid) return Pair(copy(bottom = true), - a.withLabel(SequenceLabel(listOf(NopLabel)))) + if (mutexes[""] != null && mutexes[""] != a.pid) return Pair( + copy(bottom = true), + a.withLabel(SequenceLabel(listOf(NopLabel))) + ) val processState = processes[a.pid] checkNotNull(processState) @@ -101,12 +103,19 @@ data class XcfaState @JvmOverloads constructor( is InvokeLabel -> { val proc = xcfa?.procedures?.find { proc -> proc.name == it.name } ?: error( - "No such method ${it.name}.") + "No such method ${it.name}." + ) val returnStmt = SequenceLabel( proc.params.withIndex().filter { it.value.second != ParamDirection.IN }.map { iVal -> - StmtLabel(Assign(cast((it.params[iVal.index] as RefExpr<*>).decl as VarDecl<*>, - iVal.value.first.type), cast(iVal.value.first.ref, iVal.value.first.type)), - metadata = it.metadata) + StmtLabel( + Assign( + cast( + (it.params[iVal.index] as RefExpr<*>).decl as VarDecl<*>, + iVal.value.first.type + ), cast(iVal.value.first.ref, iVal.value.first.type) + ), + metadata = it.metadata + ) }) changes.add { state -> state.invokeFunction(a.pid, proc, returnStmt, proc.params.toMap(), it.tempLookup) @@ -161,20 +170,34 @@ data class XcfaState @JvmOverloads constructor( val pid = pidCnt++ val lookup = XcfaProcessState.createLookup(procedure, "T$pid", "") newThreadLookup[startLabel.pidVar] = pid - newProcesses[pid] = XcfaProcessState(LinkedList(listOf(procedure.initLoc)), prefix = "T$pid", + newProcesses[pid] = XcfaProcessState( + LinkedList(listOf(procedure.initLoc)), prefix = "T$pid", varLookup = LinkedList(listOf(lookup)), returnStmts = LinkedList(listOf(returnStmt)), - paramStmts = LinkedList(listOf(Pair( - /* init */ - SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { - StmtLabel(Assign(cast(it.key.changeVars(lookup), it.key.type), - cast(it.key.changeVars(tempLookup).ref, it.key.type))) - }), - /* deinit */ - SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { - StmtLabel(Assign(cast(it.key.changeVars(tempLookup), it.key.type), - cast(it.key.changeVars(lookup).ref, it.key.type))) - }), - )))) + paramStmts = LinkedList( + listOf( + Pair( + /* init */ + SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { + StmtLabel( + Assign( + cast(it.key.changeVars(lookup), it.key.type), + cast(it.key.changeVars(tempLookup).ref, it.key.type) + ) + ) + }), + /* deinit */ + SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { + StmtLabel( + Assign( + cast(it.key.changeVars(tempLookup), it.key.type), + cast(it.key.changeVars(lookup).ref, it.key.type) + ) + ) + }), + ) + ) + ) + ) val newMutexes = LinkedHashMap(mutexes) newMutexes["$pid"] = pid @@ -189,8 +212,10 @@ data class XcfaState @JvmOverloads constructor( return copy(processes = newProcesses, mutexes = newMutexes) } - private fun invokeFunction(pid: Int, proc: XcfaProcedure, returnStmt: XcfaLabel, - paramList: Map, ParamDirection>, tempLookup: Map, VarDecl<*>>): XcfaState { + private fun invokeFunction( + pid: Int, proc: XcfaProcedure, returnStmt: XcfaLabel, + paramList: Map, ParamDirection>, tempLookup: Map, VarDecl<*>> + ): XcfaState { val newProcesses: MutableMap = LinkedHashMap(processes) newProcesses[pid] = checkNotNull(processes[pid]?.enterFunction(proc, returnStmt, paramList, tempLookup)) return copy(processes = newProcesses) @@ -230,10 +255,12 @@ data class XcfaState @JvmOverloads constructor( } } -data class XcfaProcessState(val locs: LinkedList, val varLookup: LinkedList, VarDecl<*>>>, +data class XcfaProcessState( + val locs: LinkedList, val varLookup: LinkedList, VarDecl<*>>>, val returnStmts: LinkedList = LinkedList(listOf(NopLabel)), val paramStmts: LinkedList> = LinkedList(listOf(Pair(NopLabel, NopLabel))), - val paramsInitialized: Boolean = false, val prefix: String = "") { + val paramsInitialized: Boolean = false, val prefix: String = "" +) { internal var popped: XcfaLocation? = null // stores if the stack was popped due to abstract stack covering @@ -250,8 +277,10 @@ data class XcfaProcessState(val locs: LinkedList, val varLookup: L else -> "${locs.peek()!!} [${locs.size}], initilized=$paramsInitialized" } - fun enterFunction(xcfaProcedure: XcfaProcedure, returnStmt: XcfaLabel, paramList: Map, ParamDirection>, - tempLookup: Map, VarDecl<*>>): XcfaProcessState { + fun enterFunction( + xcfaProcedure: XcfaProcedure, returnStmt: XcfaLabel, paramList: Map, ParamDirection>, + tempLookup: Map, VarDecl<*>> + ): XcfaProcessState { val deque: LinkedList = LinkedList(locs) val varLookup: LinkedList, VarDecl<*>>> = LinkedList(varLookup) val returnStmts: LinkedList = LinkedList(returnStmts) @@ -260,20 +289,32 @@ data class XcfaProcessState(val locs: LinkedList, val varLookup: L val lookup = createLookup(xcfaProcedure, prefix, "P${procCnt++}") varLookup.push(lookup) returnStmts.push(returnStmt) - paramStmts.push(Pair( - /* init */ - SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { - StmtLabel(Assign(cast(it.key.changeVars(lookup), it.key.type), - cast(it.key.changeVars(tempLookup).ref, it.key.type))) - }), - /* deinit */ - SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { - StmtLabel(Assign(cast(it.key.changeVars(tempLookup), it.key.type), - cast(it.key.changeVars(lookup).ref, it.key.type))) - }), - )) - return copy(locs = deque, varLookup = varLookup, returnStmts = returnStmts, paramStmts = paramStmts, - paramsInitialized = false) + paramStmts.push( + Pair( + /* init */ + SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { + StmtLabel( + Assign( + cast(it.key.changeVars(lookup), it.key.type), + cast(it.key.changeVars(tempLookup).ref, it.key.type) + ) + ) + }), + /* deinit */ + SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { + StmtLabel( + Assign( + cast(it.key.changeVars(tempLookup), it.key.type), + cast(it.key.changeVars(lookup).ref, it.key.type) + ) + ) + }), + ) + ) + return copy( + locs = deque, varLookup = varLookup, returnStmts = returnStmts, paramStmts = paramStmts, + paramsInitialized = false + ) } fun exitFunction(): XcfaProcessState { @@ -308,8 +349,10 @@ data class XcfaProcessState(val locs: LinkedList, val varLookup: L companion object { - fun createLookup(proc: XcfaProcedure, threadPrefix: String, - procPrefix: String): Map, VarDecl<*>> = listOf(proc.params.map { it.first }, proc.vars).flatten() + fun createLookup( + proc: XcfaProcedure, threadPrefix: String, + procPrefix: String + ): Map, VarDecl<*>> = listOf(proc.params.map { it.first }, proc.vars).flatten() .associateWith { val sj = StringJoiner("::") if (threadPrefix != "") sj.add(threadPrefix) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt index 30d7147c72..7b22edcdea 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt @@ -61,12 +61,14 @@ class XcfaStateAdapter(val gsonSupplier: () -> Gson, val stateTypeSupplier: () - val bottom: Boolean = gson.fromJson(reader, Boolean::class.java) reader.endObject() - return XcfaState(xcfa = null, + return XcfaState( + xcfa = null, processes = processes, sGlobal = sGlobal, mutexes = mutexes, threadLookup = threadLookup, - bottom = bottom) + bottom = bottom + ) } private fun initGson() { diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt index d91174ed82..882ecae465 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt @@ -52,12 +52,16 @@ fun XCFA.toMonolithicExpr(): MonolithicExpr { } val locVar = Decls.Var("__loc_", IntExprs.Int()) val tranList = proc.edges.map { (source, target, label): XcfaEdge -> - SequenceStmt.of(listOf( - AssumeStmt.of(Eq(locVar.ref, IntExprs.Int(map[source]!!))), - label.toStmt(), - AssignStmt.of(locVar, - IntExprs.Int(map[target]!!)) - )) + SequenceStmt.of( + listOf( + AssumeStmt.of(Eq(locVar.ref, IntExprs.Int(map[source]!!))), + label.toStmt(), + AssignStmt.of( + locVar, + IntExprs.Int(map[target]!!) + ) + ) + ) }.toList() val trans = NonDetStmt.of(tranList) val transUnfold = StmtUtils.toExpr(trans, VarIndexingFactory.indexing(0)) @@ -95,16 +99,24 @@ fun XCFA.valToState(val1: Valuation): XcfaState> { } return XcfaState( xcfa = this, - processes = mapOf(Pair(0, XcfaProcessState( - locs = LinkedList( - listOf(map[(valMap[valMap.keys.first { it.name == "__loc_" }] as IntLitExpr).value.toInt()])), - varLookup = LinkedList(), - ))), + processes = mapOf( + Pair( + 0, XcfaProcessState( + locs = LinkedList( + listOf(map[(valMap[valMap.keys.first { it.name == "__loc_" }] as IntLitExpr).value.toInt()]) + ), + varLookup = LinkedList(), + ) + ) + ), PtrState(ExplState.of( ImmutableValuation.from( val1.toMap() .filter { it.key.name != "__loc_" && !it.key.name.startsWith("__temp_") } - .map { Pair(Decls.Var("_" + "_" + it.key.name, it.key.type), it.value) }.toMap()))), + .map { Pair(Decls.Var("_" + "_" + it.key.name, it.key.type), it.value) }.toMap() + ) + ) + ), mutexes = emptyMap(), threadLookup = emptyMap(), bottom = false diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt index 0500b5d88b..6560d5ea82 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt @@ -90,8 +90,10 @@ class XcfaCoiMultiThread(xcfa: XCFA) : XcfaCoi(xcfa) { } } - private fun isObserved(action: A, procedures: MutableList, - multipleProcedures: Set): Boolean { + private fun isObserved( + action: A, procedures: MutableList, + multipleProcedures: Set + ): Boolean { val toVisit = edgeToProcedure.keys.filter { it.source == action.edge.source && it.target == action.edge.target }.toMutableList() diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt index 6ffa9bc1fb..69c695ca39 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt @@ -74,14 +74,16 @@ class XcfaOcChecker(xcfa: XCFA, decisionProcedure: OcDecisionProcedureType, priv private val rfs = mutableMapOf, MutableSet>() override fun check( - prec: XcfaPrec?): SafetyResult>, XcfaAction>> = let { + prec: XcfaPrec? + ): SafetyResult>, XcfaAction>> = let { if (xcfa.initProcedures.size > 1) error("Multiple entry points are not supported by OC checker.") logger.write(Logger.Level.MAINSTEP, "Adding constraints...\n") xcfa.initProcedures.forEach { processThread(Thread(it.first)) } addCrossThreadRelations() if (!addToSolver()) return@let SafetyResult.safe>, XcfaAction>>( - EmptyWitness.getInstance()) // no violations in the model + EmptyWitness.getInstance() + ) // no violations in the model logger.write(Logger.Level.MAINSTEP, "Start checking...\n") val status = ocChecker.check(events, pos, rfs) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt index 05ff67fc9e..ad96ab9606 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt @@ -75,8 +75,10 @@ internal class XcfaOcTraceExtractor( val nextEdge = eventTrace.getOrNull(index + 1)?.edge if (nextEdge != lastEdge) { - extend(stateList.last(), event.pid, lastEdge.source, - explState.innerState)?.let { (midActions, midStates) -> + extend( + stateList.last(), event.pid, lastEdge.source, + explState.innerState + )?.let { (midActions, midStates) -> actionList.addAll(midActions) stateList.addAll(midStates) } @@ -86,9 +88,9 @@ internal class XcfaOcTraceExtractor( stateList.add(state.copy(processes = state.processes.toMutableMap().apply { put( event.pid, XcfaProcessState( - locs = LinkedList(listOf(lastEdge.target)), - varLookup = LinkedList(emptyList()) - ) + locs = LinkedList(listOf(lastEdge.target)), + varLookup = LinkedList(emptyList()) + ) ) }, sGlobal = explState, mutexes = state.mutexes.update(lastEdge, event.pid))) lastEdge = nextEdge ?: break @@ -96,8 +98,10 @@ internal class XcfaOcTraceExtractor( } if (!stateList.last().processes[violation.pid]!!.locs.peek().error) { - extend(stateList.last(), violation.pid, violation.errorLoc, - explState.innerState)?.let { (midActions, midStates) -> + extend( + stateList.last(), violation.pid, violation.errorLoc, + explState.innerState + )?.let { (midActions, midStates) -> actionList.addAll(midActions) stateList.addAll(midStates) } @@ -163,9 +167,9 @@ internal class XcfaOcTraceExtractor( currentState = currentState.copy(processes = currentState.processes.toMutableMap().apply { put( stepPid, XcfaProcessState( - locs = LinkedList(listOf(edge.target)), - varLookup = LinkedList(emptyList()) - ) + locs = LinkedList(listOf(edge.target)), + varLookup = LinkedList(emptyList()) + ) ) }, sGlobal = PtrState(explState), mutexes = currentState.mutexes.update(edge, stepPid)) states.add(currentState) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt index d036c61ecd..f454fd25e9 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt @@ -200,7 +200,8 @@ open class XcfaDporLts(private val xcfa: XCFA) : LTS { val lastButOne = stack[stack.size - 2] val mutexNeverReleased = last.mutexLocks.containsKey( - "") && (last.state.mutexes.keys subtract lastButOne.state.mutexes.keys).contains( + "" + ) && (last.state.mutexes.keys subtract lastButOne.state.mutexes.keys).contains( "" ) if (last.node.explored.isEmpty() || mutexNeverReleased) { @@ -260,7 +261,9 @@ open class XcfaDporLts(private val xcfa: XCFA) : LTS { val action = node.inEdge.get().action if (relevantProcesses.contains(action.pid)) { if (newLastDependents.containsKey(action.pid) && index <= checkNotNull( - newLastDependents[action.pid])) { + newLastDependents[action.pid] + ) + ) { // there is an action a' such that action -> a' -> newaction (->: happens-before) relevantProcesses.remove(action.pid) } else if (dependent(newaction, action)) { diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt index b4aa758303..8e01612ffa 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt @@ -82,23 +82,30 @@ class XcfaExplAnalysisTest { val lts = getXcfaLts() - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -127,23 +134,30 @@ class XcfaExplAnalysisTest { val lts = XcfaSporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -173,23 +187,30 @@ class XcfaExplAnalysisTest { val lts = XcfaDporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, ConsoleLogger( - Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> + Logger.Level.DETAIL + ) + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -218,24 +239,31 @@ class XcfaExplAnalysisTest { val lts = XcfaAasporLts(xcfa, mutableMapOf()) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) val atomicNodePruner = AtomicNodePruner>, XcfaAction>() val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> + atomicNodePruner + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) @@ -265,21 +293,26 @@ class XcfaExplAnalysisTest { val lts = XcfaAadporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner(ItpRefToPtrPrec(ItpRefToExplPrec())) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt index e398b5ed07..88d068adf7 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt @@ -84,23 +84,30 @@ class XcfaPredAnalysisTest { val lts = getXcfaLts() - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -130,23 +137,30 @@ class XcfaPredAnalysisTest { val lts = XcfaSporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -177,23 +191,30 @@ class XcfaPredAnalysisTest { val lts = XcfaDporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, ConsoleLogger( - Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> + Logger.Level.DETAIL + ) + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -223,24 +244,31 @@ class XcfaPredAnalysisTest { val lts = XcfaAasporLts(xcfa, mutableMapOf()) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) val atomicNodePruner = AtomicNodePruner>, XcfaAction>() val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> + atomicNodePruner + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) @@ -271,22 +299,28 @@ class XcfaPredAnalysisTest { val lts = XcfaAadporLts(xcfa) - val abstractor = getXcfaAbstractor(analysis, + val abstractor = getXcfaAbstractor( + analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION + ) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver() + ), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance() + ) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt index b1a815104b..d02b0687d3 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt @@ -67,7 +67,8 @@ class XcfaStateLtsTest { initState = XcfaState( xcfa, mapOf( - Pair(0, + Pair( + 0, XcfaProcessState( locs = LinkedList(listOf(edges[1].source)), varLookup = LinkedList(listOf(createLookup(xcfa.initProcedures[0].first, "T0", "P0"))) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index 9469c2eca3..afb0bb997a 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -176,13 +176,14 @@ fun frontend(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger): Tr logger.write( Logger.Level.INFO, "Frontend finished: ${xcfa.name} (in ${ - stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + } ms)\n" ) logger.write(RESULT, "ParsingResult Success\n") logger.write(RESULT, - "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n") + "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n" + ) return Triple(xcfa, mcm, parseContext) } @@ -226,8 +227,8 @@ private fun backend( logger.write( Logger.Level.INFO, "Backend finished (in ${ - stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + } ms)\n" ) logger.write(RESULT, result.toString() + "\n") @@ -331,8 +332,10 @@ private fun postVerificationLogging( traceFile.writeText(GraphvizWriter.getInstance().writeString(traceG)) val sequenceFile = File(resultFolder, "trace.plantuml") - writeSequenceTrace(sequenceFile, - safetyResult.asUnsafe().cex as Trace, XcfaAction>) { (_, act) -> + writeSequenceTrace( + sequenceFile, + safetyResult.asUnsafe().cex as Trace, XcfaAction> + ) { (_, act) -> act.label.getFlatLabels().map(XcfaLabel::toString) } @@ -363,8 +366,10 @@ private fun postVerificationLogging( } } -private fun writeSequenceTrace(sequenceFile: File, trace: Trace, XcfaAction>, - printer: (Pair, XcfaAction>) -> List) { +private fun writeSequenceTrace( + sequenceFile: File, trace: Trace, XcfaAction>, + printer: (Pair, XcfaAction>) -> List +) { sequenceFile.writeText("@startuml\n") var maxWidth = 0 trace.actions.forEachIndexed { i, it -> diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt index 18e0bd82ca..7feaca22b7 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt @@ -30,23 +30,31 @@ import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getBoundedChecker(xcfa: XCFA, mcm: MCM, +fun getBoundedChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + logger: Logger +): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { val boundedConfig = config.backendConfig.specConfig as BoundedConfig return BoundedChecker( monolithicExpr = xcfa.toMonolithicExpr(), - bmcSolver = tryGetSolver(boundedConfig.bmcConfig.bmcSolver, - boundedConfig.bmcConfig.validateBMCSolver)?.createSolver(), + bmcSolver = tryGetSolver( + boundedConfig.bmcConfig.bmcSolver, + boundedConfig.bmcConfig.validateBMCSolver + )?.createSolver(), bmcEnabled = { !boundedConfig.bmcConfig.disable }, lfPathOnly = { !boundedConfig.bmcConfig.nonLfPath }, - itpSolver = tryGetSolver(boundedConfig.itpConfig.itpSolver, - boundedConfig.itpConfig.validateItpSolver)?.createItpSolver(), + itpSolver = tryGetSolver( + boundedConfig.itpConfig.itpSolver, + boundedConfig.itpConfig.validateItpSolver + )?.createItpSolver(), imcEnabled = { !boundedConfig.itpConfig.disable }, - indSolver = tryGetSolver(boundedConfig.indConfig.indSolver, - boundedConfig.indConfig.validateIndSolver)?.createSolver(), + indSolver = tryGetSolver( + boundedConfig.indConfig.indSolver, + boundedConfig.indConfig.validateIndSolver + )?.createSolver(), kindEnabled = { !boundedConfig.indConfig.disable }, valToState = { xcfa.valToState(it) }, biValToAction = { val1, val2 -> xcfa.valToAction(val1, val2) }, diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt index 8c39486021..6417f4e57c 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt @@ -43,14 +43,20 @@ import hu.bme.mit.theta.xcfa.cli.params.* import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getCegarChecker(xcfa: XCFA, mcm: MCM, +fun getCegarChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { + logger: Logger +): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { val cegarConfig = config.backendConfig.specConfig as CegarConfig - val abstractionSolverFactory: SolverFactory = getSolver(cegarConfig.abstractorConfig.abstractionSolver, - cegarConfig.abstractorConfig.validateAbstractionSolver) - val refinementSolverFactory: SolverFactory = getSolver(cegarConfig.refinerConfig.refinementSolver, - cegarConfig.refinerConfig.validateRefinementSolver) + val abstractionSolverFactory: SolverFactory = getSolver( + cegarConfig.abstractorConfig.abstractionSolver, + cegarConfig.abstractorConfig.validateAbstractionSolver + ) + val refinementSolverFactory: SolverFactory = getSolver( + cegarConfig.refinerConfig.refinementSolver, + cegarConfig.refinerConfig.validateRefinementSolver + ) val ignoredVarRegistry = mutableMapOf, MutableSet>() @@ -59,12 +65,14 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, (cegarConfig.coi.porLts as XcfaDporLts).waitlist } else { PriorityWaitlist.create>, XcfaAction>>( - cegarConfig.abstractorConfig.search.getComp(xcfa)) + cegarConfig.abstractorConfig.search.getComp(xcfa) + ) } val abstractionSolverInstance = abstractionSolverFactory.createSolver() val globalStatePartialOrd: PartialOrd> = cegarConfig.abstractorConfig.domain.partialOrd( - abstractionSolverInstance) as PartialOrd> + abstractionSolverInstance + ) as PartialOrd> val corePartialOrd: PartialOrd>> = if (xcfa.isInlined) getPartialOrder(globalStatePartialOrd) else getStackPartialOrder(globalStatePartialOrd) @@ -91,18 +99,23 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, val precRefiner: PrecRefiner = cegarConfig.abstractorConfig.domain.itpPrecRefiner(cegarConfig.refinerConfig.exprSplitter.exprSplitter) as PrecRefiner - val atomicNodePruner: NodePruner = cegarConfig.abstractorConfig.domain.nodePruner as NodePruner + val atomicNodePruner: NodePruner = + cegarConfig.abstractorConfig.domain.nodePruner as NodePruner val refiner: Refiner = if (cegarConfig.refinerConfig.refinement == Refinement.MULTI_SEQ) if (cegarConfig.porLevel == POR.AASPOR) - MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner) + MultiExprTraceRefiner.create( + ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner + ) else MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) else if (cegarConfig.porLevel == POR.AASPOR) - XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner) + XcfaSingleExprTraceRefiner.create( + ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner + ) else XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) @@ -125,9 +138,11 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, return object : SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { override fun check( - prec: XcfaPrec<*>?): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { + prec: XcfaPrec<*>? + ): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { return cegarChecker.check( - prec) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> + prec + ) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> } override fun check(): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt index 4bd2dce149..2315b6405b 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt @@ -31,9 +31,11 @@ import hu.bme.mit.theta.xcfa.cli.params.Backend import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.model.XCFA -fun getChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, +fun getChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger, - uniqueLogger: Logger): SafetyChecker<*, *, XcfaPrec<*>> = + uniqueLogger: Logger +): SafetyChecker<*, *, XcfaPrec<*>> = if (config.backendConfig.inProcess) { InProcessChecker(xcfa, config, parseContext, logger) } else { diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt index df14f6ee8f..80cae60477 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt @@ -31,14 +31,18 @@ import hu.bme.mit.theta.xcfa.cli.params.OcConfig import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.model.XCFA -fun getOcChecker(xcfa: XCFA, mcm: MCM, +fun getOcChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + logger: Logger +): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { val ocChecker = XcfaOcChecker(xcfa, (config.backendConfig.specConfig as OcConfig).decisionProcedure, logger) return object : SafetyChecker>, XcfaAction>, XcfaPrec<*>> { override fun check( - prec: XcfaPrec<*>?): SafetyResult>, XcfaAction>> = check() + prec: XcfaPrec<*>? + ): SafetyResult>, XcfaAction>> = check() - override fun check(): SafetyResult>, XcfaAction>> = ocChecker.check() + override fun check(): SafetyResult>, XcfaAction>> = + ocChecker.check() } } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt index a105f36786..0daeedf5e8 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt @@ -40,47 +40,52 @@ import javax.script.ScriptEngine import javax.script.ScriptEngineManager import javax.script.SimpleBindings -fun getPortfolioChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, +fun getPortfolioChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger, - uniqueLogger: Logger): SafetyChecker>, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> = SafetyChecker { _ -> + uniqueLogger: Logger +): SafetyChecker>, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> = + SafetyChecker { _ -> - val sw = Stopwatch.createStarted() - val portfolioName = (config.backendConfig.specConfig as PortfolioConfig).portfolio + val sw = Stopwatch.createStarted() + val portfolioName = (config.backendConfig.specConfig as PortfolioConfig).portfolio - val portfolioStm = when (portfolioName) { - "STABLE", - "CEGAR", - "COMPLEX", - "COMPLEX24" -> complexPortfolio24(xcfa, mcm, parseContext, config, logger, uniqueLogger) + val portfolioStm = when (portfolioName) { + "STABLE", + "CEGAR", + "COMPLEX", + "COMPLEX24" -> complexPortfolio24(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "COMPLEX23" -> complexPortfolio23(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "COMPLEX23" -> complexPortfolio23(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "EMERGENT", - "BOUNDED" -> boundedPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "EMERGENT", + "BOUNDED" -> boundedPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "TESTING", - "CHC", - "HORN" -> hornPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "TESTING", + "CHC", + "HORN" -> hornPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) - else -> { - if (File(portfolioName).exists()) { - val kotlinEngine: ScriptEngine = ScriptEngineManager().getEngineByExtension("kts") - val bindings: Bindings = SimpleBindings() - bindings["xcfa"] = xcfa - bindings["mcm"] = mcm - bindings["parseContext"] = parseContext - bindings["portfolioConfig"] = config - bindings["logger"] = logger - bindings["uniqueLogger"] = uniqueLogger - kotlinEngine.eval(FileReader(portfolioName), bindings) as STM - } else { - error("No such file or built-in config: $portfolioName") + else -> { + if (File(portfolioName).exists()) { + val kotlinEngine: ScriptEngine = ScriptEngineManager().getEngineByExtension("kts") + val bindings: Bindings = SimpleBindings() + bindings["xcfa"] = xcfa + bindings["mcm"] = mcm + bindings["parseContext"] = parseContext + bindings["portfolioConfig"] = config + bindings["logger"] = logger + bindings["uniqueLogger"] = uniqueLogger + kotlinEngine.eval(FileReader(portfolioName), bindings) as STM + } else { + error("No such file or built-in config: $portfolioName") + } } } - } - val result = portfolioStm.execute() as Pair, SafetyResult<*, *>> + val result = portfolioStm.execute() as Pair, SafetyResult<*, *>> - logger.write(Logger.Level.RESULT, "Config ${result.first} succeeded in ${sw.elapsed(TimeUnit.MILLISECONDS)} ms\n") - result.second as SafetyResult>, XcfaAction>, Trace>, XcfaAction>>? -} \ No newline at end of file + logger.write( + Logger.Level.RESULT, "Config ${result.first} succeeded in ${sw.elapsed(TimeUnit.MILLISECONDS)} ms\n" + ) + result.second as SafetyResult>, XcfaAction>, Trace>, XcfaAction>>? + } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt index a20d9a5aaf..276f6455d8 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt @@ -47,7 +47,8 @@ class InProcessChecker( ) : SafetyChecker> { override fun check( - prec: XcfaPrec<*>?): SafetyResult { + prec: XcfaPrec<*>? + ): SafetyResult { return check() } @@ -80,16 +81,18 @@ class InProcessChecker( getGson(xcfa).toJson(processConfig) } - val pb = NuProcessBuilder(listOf( - ProcessHandle.current().info().command().orElse("java"), - "-Xss120m", - "-Xmx14210m", - "-cp", - File(XcfaCli::class.java.protectionDomain.codeSource.location.toURI()).absolutePath, - XcfaCli::class.qualifiedName, - "-c", - configJson.absolutePath - ).filterNotNull()) + val pb = NuProcessBuilder( + listOf( + ProcessHandle.current().info().command().orElse("java"), + "-Xss120m", + "-Xmx14210m", + "-cp", + File(XcfaCli::class.java.protectionDomain.codeSource.location.toURI()).absolutePath, + XcfaCli::class.qualifiedName, + "-c", + configJson.absolutePath + ).filterNotNull() + ) val processHandler = ProcessHandler() pb.setProcessListener(processHandler) val process: NuProcess = pb.start() @@ -102,8 +105,10 @@ class InProcessChecker( process.destroy(true) throw ErrorCodeException(ExitCodes.TIMEOUT.code) } else { - logger.write(Logger.Level.RESULT, - "Config timed out but started writing result, trying to wait an additional 10%...") + logger.write( + Logger.Level.RESULT, + "Config timed out but started writing result, trying to wait an additional 10%..." + ) val retCode = process.waitFor(config.backendConfig.timeoutMs / 10, TimeUnit.MILLISECONDS) if (retCode != 0) { throw ErrorCodeException(retCode) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt index ac5b3d3236..83dbae2747 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt @@ -116,8 +116,10 @@ enum class Domain( EXPL( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), d, - e, f, g, h) + getXcfaAbstractor( + ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), d, + e, f, g, h + ) }, itpPrecRefiner = { XcfaPrecRefiner, ExplPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToExplPrec())) @@ -129,8 +131,12 @@ enum class Domain( ), PRED_BOOL( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) + getXcfaAbstractor( + PredXcfaAnalysis( + a, b, PredAbstractors.booleanAbstractor(b), + i as PartialOrd>>, j + ), d, e, f, g, h + ) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -142,8 +148,12 @@ enum class Domain( ), PRED_CART( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.cartesianAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) + getXcfaAbstractor( + PredXcfaAnalysis( + a, b, PredAbstractors.cartesianAbstractor(b), + i as PartialOrd>>, j + ), d, e, f, g, h + ) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -155,8 +165,12 @@ enum class Domain( ), PRED_SPLIT( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanSplitAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) + getXcfaAbstractor( + PredXcfaAnalysis( + a, b, PredAbstractors.booleanSplitAbstractor(b), + i as PartialOrd>>, j + ), d, e, f, g, h + ) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -280,15 +294,19 @@ enum class Search { BFS { override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.bfs()) + return ArgNodeComparators.combine( + ArgNodeComparators.targetFirst(), + ArgNodeComparators.bfs() + ) } }, DFS { override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.dfs()) + return ArgNodeComparators.combine( + ArgNodeComparators.targetFirst(), + ArgNodeComparators.dfs() + ) } }, ERR { @@ -321,7 +339,8 @@ enum class InitPrec( ALLASSUMES( explPrec = { xcfa -> XcfaPrec( - PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet())) + PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet()) + ) }, predPrec = { xcfa -> XcfaPrec(PtrPrec(PredPrec.of(xcfa.collectAssumes()), emptySet())) }, ), diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt index a52a05c957..3a8e43940a 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt @@ -70,16 +70,22 @@ data class InputConfig( @Parameter(names = ["--cat"], description = "Path of the cat model") var catFile: File? = null, - @Parameter(names = ["--parse-ctx"], - description = "Path of the parse context JSON (may contain additional metadata)") + @Parameter( + names = ["--parse-ctx"], + description = "Path of the parse context JSON (may contain additional metadata)" + ) var parseCtx: File? = null, - @Parameter(names = ["--xcfa-w-ctx"], - description = "XCFA and ParseContext (will overwrite --input and --parse-ctx when given)") + @Parameter( + names = ["--xcfa-w-ctx"], + description = "XCFA and ParseContext (will overwrite --input and --parse-ctx when given)" + ) var xcfaWCtx: Triple? = null, - @Parameter(names = ["--property"], - description = "Path of the property file (will overwrite --property when given)") + @Parameter( + names = ["--property"], + description = "Path of the property file (will overwrite --property when given)" + ) var propertyFile: File? = null, @Parameter(names = ["--property-value"], description = "Property") @@ -100,16 +106,22 @@ data class FrontendConfig( @Parameter(names = ["--static-coi"], description = "Enable static cone-of-influence") var staticCoi: Boolean = false, - @Parameter(names = ["--unroll"], - description = "Max number of loop iterations to unroll (use -1 to unroll completely when possible)") + @Parameter( + names = ["--unroll"], + description = "Max number of loop iterations to unroll (use -1 to unroll completely when possible)" + ) var loopUnroll: Int = 1000, - @Parameter(names = ["--force-unroll"], - description = "Number of loop iteration to unroll even if the number of iterations is unknown; in case of such a bounded loop unrolling, the safety result cannot be safe (use -1 to disable)") + @Parameter( + names = ["--force-unroll"], + description = "Number of loop iteration to unroll even if the number of iterations is unknown; in case of such a bounded loop unrolling, the safety result cannot be safe (use -1 to disable)" + ) var forceUnroll: Int = -1, - @Parameter(names = ["--enable-few"], - description = "Enable the FetchExecuteWriteback pass, which introduces a local temp var for all memory accesses") + @Parameter( + names = ["--enable-few"], + description = "Enable the FetchExecuteWriteback pass, which introduces a local temp var for all memory accesses" + ) var enableFew: Boolean = false, @Parameter(names = ["--input-type"], description = "Format of the input") @@ -206,22 +218,28 @@ data class CegarAbstractorConfig( @Parameter(names = ["--abstraction-solver"], description = "Abstraction solver name") var abstractionSolver: String = "Z3", - @Parameter(names = ["--validate-abstraction-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-abstraction-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateAbstractionSolver: Boolean = false, @Parameter(names = ["--domain"], description = "Abstraction domain") var domain: Domain = Domain.EXPL, - @Parameter(names = ["--maxenum"], - description = "How many successors to enumerate in a transition. Only relevant to the explicit domain. Use 0 for no limit.") + @Parameter( + names = ["--maxenum"], + description = "How many successors to enumerate in a transition. Only relevant to the explicit domain. Use 0 for no limit." + ) var maxEnum: Int = 1, @Parameter(names = ["--search"], description = "Search strategy") var search: Search = Search.ERR, - @Parameter(names = ["--havoc-memory"], - description = "HAVOC memory model (do not track pointers in transition function)") + @Parameter( + names = ["--havoc-memory"], + description = "HAVOC memory model (do not track pointers in transition function)" + ) var havocMemory: Boolean = false ) : Config @@ -229,8 +247,10 @@ data class CegarRefinerConfig( @Parameter(names = ["--refinement-solver"], description = "Refinement solver name") var refinementSolver: String = "Z3", - @Parameter(names = ["--validate-refinement-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-refinement-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateRefinementSolver: Boolean = false, @Parameter(names = ["--refinement"], description = "Refinement strategy") @@ -281,8 +301,10 @@ data class BMCConfig( @Parameter(names = ["--bmc-solver"], description = "BMC solver name") var bmcSolver: String = "Z3", - @Parameter(names = ["--validate-bmc-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-bmc-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateBMCSolver: Boolean = false, ) : Config @@ -293,16 +315,22 @@ data class InductionConfig( @Parameter(names = ["--induction-solver", "--ind-solver"], description = "Induction solver name") var indSolver: String = "Z3", - @Parameter(names = ["--validate-induction-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-induction-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateIndSolver: Boolean = false, - @Parameter(names = ["--ind-min-bound"], - description = "Start induction after reaching this bound") + @Parameter( + names = ["--ind-min-bound"], + description = "Start induction after reaching this bound" + ) var indMinBound: Int = 0, - @Parameter(names = ["--ind-frequency"], - description = "Frequency of induction check") + @Parameter( + names = ["--ind-frequency"], + description = "Frequency of induction check" + ) var indFreq: Int = 1, ) : Config @@ -313,8 +341,10 @@ data class InterpolationConfig( @Parameter(names = ["--interpolation-solver", "--itp-solver"], description = "Interpolation solver name") var itpSolver: String = "Z3", - @Parameter(names = ["--validate-interpolation-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-interpolation-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateItpSolver: Boolean = false, ) : Config @@ -389,8 +419,10 @@ data class WitnessConfig( @Parameter(names = ["--cex-solver"], description = "Concretizer solver name") var concretizerSolver: String = "Z3", - @Parameter(names = ["--validate-cex-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") + @Parameter( + names = ["--validate-cex-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." + ) var validateConcretizerSolver: Boolean = false ) : Config @@ -409,11 +441,15 @@ data class DebugConfig( @Parameter(names = ["--loglevel"], description = "Detailedness of logging") var logLevel: Logger.Level = Logger.Level.MAINSTEP, - @Parameter(names = ["--arg-debug"], - description = "ARG debug mode (use the web-based debugger for ARG visualization)") + @Parameter( + names = ["--arg-debug"], + description = "ARG debug mode (use the web-based debugger for ARG visualization)" + ) var argdebug: Boolean = false, - @Parameter(names = ["--arg-to-file"], - description = "Visualize the resulting file here: https://ftsrg-edu.github.io/student-sisak-argviz/") + @Parameter( + names = ["--arg-to-file"], + description = "Visualize the resulting file here: https://ftsrg-edu.github.io/student-sisak-argviz/" + ) var argToFile: Boolean = false ) : Config \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt index 787774d93f..2cb473abb9 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt @@ -38,7 +38,8 @@ fun boundedPortfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger): STM { + uniqueLogger: Logger +): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -47,12 +48,14 @@ fun boundedPortfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property), + property = portfolioConfig.inputConfig.property + ), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) + ), backendConfig = BackendConfig( backend = Backend.BOUNDED, solverHome = portfolioConfig.backendConfig.solverHome, @@ -62,7 +65,8 @@ fun boundedPortfolio( maxBound = 0, indConfig = InductionConfig(true), itpConfig = InterpolationConfig(true) - )), + ) + ), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -114,40 +118,49 @@ fun boundedPortfolio( timeoutMs: Long = 0, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, BoundedConfig> { - return copy(backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - bmcConfig = backendConfig.specConfig!!.bmcConfig.copy(disable = !bmcEnabled, bmcSolver = bmcSolver), - indConfig = backendConfig.specConfig!!.indConfig.copy(disable = !indEnabled, indSolver = indSolver), - itpConfig = backendConfig.specConfig!!.itpConfig.copy(disable = !itpEnabled, itpSolver = itpSolver), + return copy( + backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + bmcConfig = backendConfig.specConfig!!.bmcConfig.copy(disable = !bmcEnabled, bmcSolver = bmcSolver), + indConfig = backendConfig.specConfig!!.indConfig.copy(disable = !indEnabled, indSolver = indSolver), + itpConfig = backendConfig.specConfig!!.itpConfig.copy(disable = !itpEnabled, itpSolver = itpSolver), + ) ) - )) + ) } fun getStm(inProcess: Boolean): STM { val edges = LinkedHashSet() - val configBmcZ3 = ConfigNode("BmcZ3-$inProcess", + val configBmcZ3 = ConfigNode( + "BmcZ3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcEnabled = true, timeoutMs = 30000 - ), checker) - val configBmcMathsat = ConfigNode("BmcMathsat-$inProcess", + ), checker + ) + val configBmcMathsat = ConfigNode( + "BmcMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcSolver = "mathsat:5.6.10", bmcEnabled = true, timeoutMs = 30000 - ), checker) - val configIndZ3 = ConfigNode("IndZ3-$inProcess", + ), checker + ) + val configIndZ3 = ConfigNode( + "IndZ3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcEnabled = true, indEnabled = true, timeoutMs = 300000 - ), checker) - val configIndMathsat = ConfigNode("IndMathsat-$inProcess", + ), checker + ) + val configIndMathsat = ConfigNode( + "IndMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcSolver = "mathsat:5.6.10", @@ -155,33 +168,54 @@ fun boundedPortfolio( bmcEnabled = true, indEnabled = true, timeoutMs = 300000 - ), checker) - val configItpCvc5 = ConfigNode("ItpCvc5-$inProcess", + ), checker + ) + val configItpCvc5 = ConfigNode( + "ItpCvc5-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, itpEnabled = true, itpSolver = "cvc5:1.0.8", timeoutMs = 0 - ), checker) - val configItpMathsat = ConfigNode("ItpMathsat-$inProcess", + ), checker + ) + val configItpMathsat = ConfigNode( + "ItpMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, itpSolver = "mathsat:5.6.10", itpEnabled = true, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(configBmcZ3, configBmcMathsat, solverError)) - edges.add(Edge(configBmcZ3, configIndZ3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(configBmcMathsat, configIndMathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add( + Edge( + configBmcZ3, configIndZ3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + configBmcMathsat, configIndMathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) edges.add(Edge(configIndZ3, configIndMathsat, solverError)) - edges.add(Edge(configIndZ3, configItpCvc5, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(configIndMathsat, configItpCvc5, - if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add( + Edge( + configIndZ3, configItpCvc5, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + configIndMathsat, configItpCvc5, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) edges.add(Edge(configItpCvc5, configItpMathsat, anyError)) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt index c6901d3838..9c62a7e047 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt @@ -29,11 +29,13 @@ import hu.bme.mit.theta.xcfa.model.XCFA import hu.bme.mit.theta.xcfa.passes.LbePass import java.nio.file.Paths -fun complexPortfolio23(xcfa: XCFA, mcm: MCM, +fun complexPortfolio23( + xcfa: XCFA, mcm: MCM, parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger): STM { + uniqueLogger: Logger +): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -42,12 +44,14 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property), + property = portfolioConfig.inputConfig.property + ), frontendConfig = FrontendConfig( lbeLevel = LbePass.LbeLevel.LBE_SEQ, loopUnroll = 50, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) + ), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -72,7 +76,9 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ))), + ) + ) + ), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -92,7 +98,8 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, refinerConfig = baseCegarConfig.refinerConfig.copy(pruneStrategy = PruneStrategy.LAZY) ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) + ) } val timeoutTrigger = ExceptionTrigger( @@ -123,23 +130,25 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, validateRefinementSolver: Boolean = this.backendConfig.specConfig!!.refinerConfig.validateRefinementSolver, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, CegarConfig> { - return copy(backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - initPrec = initPrec, - abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( - abstractionSolver = abstractionSolver, - validateAbstractionSolver = validateAbstractionSolver, - domain = domain, - ), - refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( - refinementSolver = refinementSolver, - validateRefinementSolver = validateRefinementSolver, - refinement = refinement, + return copy( + backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + initPrec = initPrec, + abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( + abstractionSolver = abstractionSolver, + validateAbstractionSolver = validateAbstractionSolver, + domain = domain, + ), + refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( + refinementSolver = refinementSolver, + validateRefinementSolver = validateRefinementSolver, + refinement = refinement, + ) ) ) - )) + ) } val quickExplConfig = baseConfig.adaptConfig(initPrec = InitPrec.ALLVARS, timeoutMs = 90_000) @@ -148,50 +157,92 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, fun integerStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_z3_4.10.1_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", + val config_1_1 = ConfigNode( + "QuickFullExpl_z3_4.10.1_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP), checker) - val config_2_1 = ConfigNode("EmptyExpl_z3_4.10.1_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_2_1 = ConfigNode( + "EmptyExpl_z3_4.10.1_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP), checker) - val config_3_1 = ConfigNode("PredCart_z3_4.10.1_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", - refinementSolver = "z3:4.10.1"), checker) - - val config_1_2 = ConfigNode("QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess), checker) - val config_2_2 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess), - checker) - val config_3_2 = ConfigNode("PredCart_Z3_$inProcess", predConfig.adaptConfig(inProcess = inProcess), - checker) - - val config_1_3 = ConfigNode("QuickFullExpl_princess_2022_07_01_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01"), - checker) - val config_2_3 = ConfigNode("EmptyExpl_princess_2022_07_01_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01"), - checker) - val config_3_3 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8"), - checker) - - val config_1_4 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8"), - checker) - val config_2_4 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8"), - checker) - val config_3_4 = ConfigNode("PredCart_princess_2022_07_01_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01"), - checker) + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_3_1 = ConfigNode( + "PredCart_z3_4.10.1_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinementSolver = "z3:4.10.1" + ), checker + ) + + val config_1_2 = ConfigNode( + "QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess), checker + ) + val config_2_2 = ConfigNode( + "EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess), + checker + ) + val config_3_2 = ConfigNode( + "PredCart_Z3_$inProcess", predConfig.adaptConfig(inProcess = inProcess), + checker + ) + + val config_1_3 = ConfigNode( + "QuickFullExpl_princess_2022_07_01_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01" + ), + checker + ) + val config_2_3 = ConfigNode( + "EmptyExpl_princess_2022_07_01_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01" + ), + checker + ) + val config_3_3 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8" + ), + checker + ) + + val config_1_4 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8" + ), + checker + ) + val config_2_4 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8" + ), + checker + ) + val config_3_4 = ConfigNode( + "PredCart_princess_2022_07_01_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01" + ), + checker + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -203,15 +254,23 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, Edge(config_1_3, config_2_3, timeoutTrigger), Edge(config_2_3, config_3_1, timeoutTrigger), - Edge(config_1_4, config_2_4, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), - Edge(config_2_4, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge( + config_1_4, config_2_4, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), + Edge( + config_2_4, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -229,8 +288,10 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode("InProcess", - getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode( + "InProcess", + getStm(!portfolioConfig.debugConfig.debug) + ) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) @@ -240,40 +301,72 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, fun bitwiseStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), checker) - val config_2_1 = ConfigNode("EmptyExpl_Z3_$inProcess", + val config_1_1 = ConfigNode( + "QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), checker + ) + val config_2_1 = ConfigNode( + "EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), - checker) - val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8"), - checker) - - val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + checker + ) + val config_3_1 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8" + ), + checker + ) + + val config_1_2 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) - val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_2_2 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) - val config_3_2 = ConfigNode("PredCart_z3_4.10.1_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", - refinementSolver = "z3:4.10.1"), checker) + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_3_2 = ConfigNode( + "PredCart_z3_4.10.1_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinementSolver = "z3:4.10.1" + ), checker + ) - val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + val config_1_3 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.NWT_IT_WP), checker) - val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_2_3 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.SEQ_ITP), checker) - val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP + ), checker + ) + val config_3_3 = ConfigNode( + "PredCart_cvc5_1.0.2_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) + refinement = Refinement.NWT_IT_WP + ), checker + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -282,15 +375,23 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, Edge(config_1_2, config_2_2, timeoutTrigger), Edge(config_2_2, config_3_1, timeoutTrigger), - Edge(config_1_3, config_2_3, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), - Edge(config_2_3, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge( + config_1_3, config_2_3, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), + Edge( + config_2_3, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -305,8 +406,10 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode("InProcess", - getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode( + "InProcess", + getStm(!portfolioConfig.debugConfig.debug) + ) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) @@ -316,74 +419,134 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, fun floatsStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + val config_1_1 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) - val config_2_1 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_2_1 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) - val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8"), - checker) - - val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_seq_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_3_1 = ConfigNode( + "PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8" + ), + checker + ) + + val config_1_2 = ConfigNode( + "QuickFullExpl_cvc5_1.0.2_seq_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP), checker) - val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_seq_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP + ), checker + ) + val config_2_2 = ConfigNode( + "EmptyExpl_cvc5_1.0.2_seq_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP), checker) - val config_3_2 = ConfigNode("PredCart_bitwuzla_latest_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "bitwuzla:latest", + refinement = Refinement.SEQ_ITP + ), checker + ) + val config_3_2 = ConfigNode( + "PredCart_bitwuzla_latest_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", - refinement = Refinement.NWT_IT_WP), checker) + refinement = Refinement.NWT_IT_WP + ), checker + ) - val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + val config_1_3 = ConfigNode( + "QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", validateAbstractionSolver = true, validateRefinementSolver = true, - refinement = Refinement.NWT_IT_WP), - checker) - val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP + ), + checker + ) + val config_2_3 = ConfigNode( + "EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", validateAbstractionSolver = true, validateRefinementSolver = true, - refinement = Refinement.NWT_IT_WP), - checker) - val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP + ), + checker + ) + val config_3_3 = ConfigNode( + "PredCart_cvc5_1.0.2_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP), checker) + refinement = Refinement.NWT_IT_WP + ), checker + ) - val config_1_4 = ConfigNode("QuickFullExpl_mathsat_fp_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", + val config_1_4 = ConfigNode( + "QuickFullExpl_mathsat_fp_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker) - val config_2_4 = ConfigNode("EmptyExpl_mathsat_fp_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker + ) + val config_2_4 = ConfigNode( + "EmptyExpl_mathsat_fp_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker) - val config_3_4 = ConfigNode("PredCart_mathsat_fp_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker + ) + val config_3_4 = ConfigNode( + "PredCart_mathsat_fp_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true), checker) + validateAbstractionSolver = true, validateRefinementSolver = true + ), checker + ) - val config_1_5 = ConfigNode("QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + val config_1_5 = ConfigNode( + "QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker) - val config_2_5 = ConfigNode("EmptyExpl_Z3_$inProcess", - emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_2_5 = ConfigNode( + "EmptyExpl_Z3_$inProcess", + emptyExplConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker) - val config_3_5 = ConfigNode("PredCart_Z3_$inProcess", - predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP), - checker) + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP + ), checker + ) + val config_3_5 = ConfigNode( + "PredCart_Z3_$inProcess", + predConfig.adaptConfig( + inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP + ), + checker + ) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -398,15 +561,23 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, Edge(config_1_4, config_2_4, timeoutTrigger), Edge(config_2_4, config_3_1, timeoutTrigger), - Edge(config_1_5, config_2_5, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), - Edge(config_2_5, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge( + config_1_5, config_2_5, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), + Edge( + config_2_5, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") + ), ) - val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout") + val notTimeout = if (inProcess) ExceptionTrigger( + ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError" + ) else ExceptionTrigger( + fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout" + ) val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -427,8 +598,10 @@ fun complexPortfolio23(xcfa: XCFA, mcm: MCM, return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode("InProcess", - getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode( + "InProcess", + getStm(!portfolioConfig.debugConfig.debug) + ) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt index ca6f147553..8a5c005c3e 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt @@ -37,7 +37,8 @@ fun complexPortfolio24( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger): STM { + uniqueLogger: Logger +): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -46,12 +47,14 @@ fun complexPortfolio24( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property), + property = portfolioConfig.inputConfig.property + ), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) + ), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -75,7 +78,9 @@ fun complexPortfolio24( refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ))), + ) + ) + ), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -95,7 +100,8 @@ fun complexPortfolio24( abstractorConfig = baseCegarConfig.abstractorConfig.copy(search = Search.DFS), ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) + ) } if (!xcfa.isInlined) { @@ -140,28 +146,31 @@ fun complexPortfolio24( validateRefinementSolver: Boolean = this.backendConfig.specConfig!!.refinerConfig.validateRefinementSolver, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, CegarConfig> { - return copy(backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - initPrec = initPrec, - abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( - abstractionSolver = abstractionSolver, - validateAbstractionSolver = validateAbstractionSolver, - domain = domain, - ), - refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( - refinementSolver = refinementSolver, - validateRefinementSolver = validateRefinementSolver, - refinement = refinement, + return copy( + backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + initPrec = initPrec, + abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( + abstractionSolver = abstractionSolver, + validateAbstractionSolver = validateAbstractionSolver, + domain = domain, + ), + refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( + refinementSolver = refinementSolver, + validateRefinementSolver = validateRefinementSolver, + refinement = refinement, + ) ) ) - )) + ) } fun getStm(trait: ArithmeticTrait, inProcess: Boolean): STM { val edges = LinkedHashSet() - val config_BITWISE_EXPL_NWT_IT_WP_cvc5 = ConfigNode("BITWISE_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + val config_BITWISE_EXPL_NWT_IT_WP_cvc5 = ConfigNode( + "BITWISE_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -169,8 +178,10 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) - val config_BITWISE_EXPL_NWT_IT_WP_Z3 = ConfigNode("BITWISE_EXPL_NWT_IT_WP_Z3-$inProcess", + ), checker + ) + val config_BITWISE_EXPL_NWT_IT_WP_Z3 = ConfigNode( + "BITWISE_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -178,9 +189,11 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) + ), checker + ) edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_EXPL_NWT_IT_WP_Z3, solverError)) - val config_BITWISE_EXPL_NWT_IT_WP_mathsat = ConfigNode("BITWISE_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_BITWISE_EXPL_NWT_IT_WP_mathsat = ConfigNode( + "BITWISE_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -188,9 +201,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) + ), checker + ) edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_BITWISE_PRED_CART_SEQ_ITP_mathsat = ConfigNode("BITWISE_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_BITWISE_PRED_CART_SEQ_ITP_mathsat = ConfigNode( + "BITWISE_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -198,14 +213,28 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) - val config_BITWISE_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("BITWISE_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_BITWISE_EXPL_NWT_IT_WP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_BITWISE_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( + "BITWISE_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -213,9 +242,11 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_BITWISE_EXPL_SEQ_ITP_mathsat = ConfigNode("BITWISE_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_BITWISE_EXPL_SEQ_ITP_mathsat = ConfigNode( + "BITWISE_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -223,12 +254,22 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_cvc5, config_BITWISE_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) - val config_BITWISE_EXPL_SEQ_ITP_cvc5 = ConfigNode("BITWISE_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_BITWISE_PRED_CART_SEQ_ITP_cvc5, config_BITWISE_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_BITWISE_EXPL_SEQ_ITP_cvc5 = ConfigNode( + "BITWISE_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -236,9 +277,11 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_BITWISE_EXPL_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_cvc5, solverError)) - val config_FLOAT_EXPL_NWT_IT_WP_cvc5 = ConfigNode("FLOAT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + val config_FLOAT_EXPL_NWT_IT_WP_cvc5 = ConfigNode( + "FLOAT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -246,17 +289,21 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 200000 - ), checker) - val config_FLOAT_EXPL_NWT_IT_WP_Z3 = ConfigNode("FLOAT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 200000 - ), checker) + ), checker + ) + val config_FLOAT_EXPL_NWT_IT_WP_Z3 = ConfigNode( + "FLOAT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 200000 + ), checker + ) edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_EXPL_NWT_IT_WP_Z3, solverError)) - val config_FLOAT_EXPL_NWT_IT_WP_mathsat = ConfigNode("FLOAT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_FLOAT_EXPL_NWT_IT_WP_mathsat = ConfigNode( + "FLOAT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -264,9 +311,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP, timeoutMs = 200000 - ), checker) + ), checker + ) edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_FLOAT_PRED_CART_SEQ_ITP_mathsat = ConfigNode("FLOAT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_FLOAT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( + "FLOAT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -274,14 +323,28 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) - val config_FLOAT_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("FLOAT_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_FLOAT_EXPL_NWT_IT_WP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_FLOAT_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( + "FLOAT_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -289,9 +352,11 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_FLOAT_EXPL_SEQ_ITP_mathsat = ConfigNode("FLOAT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_FLOAT_EXPL_SEQ_ITP_mathsat = ConfigNode( + "FLOAT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -299,12 +364,22 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_cvc5, config_FLOAT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) - val config_FLOAT_EXPL_SEQ_ITP_cvc5 = ConfigNode("FLOAT_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_FLOAT_PRED_CART_SEQ_ITP_cvc5, config_FLOAT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_FLOAT_EXPL_SEQ_ITP_cvc5 = ConfigNode( + "FLOAT_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -312,9 +387,11 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_FLOAT_EXPL_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_cvc5, solverError)) - val config_LIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode("LIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_LIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode( + "LIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -322,8 +399,10 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) - val config_LIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode("LIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", + ), checker + ) + val config_LIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode( + "LIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -331,21 +410,33 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) + ), checker + ) edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_NWT_IT_WP_Z3, solverError)) - val config_LIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode("LIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.SEQ_ITP, - timeoutMs = 300000 - ), checker) - edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_Z3, config_LIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError)) - val config_LIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode("LIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_LIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode( + "LIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.SEQ_ITP, + timeoutMs = 300000 + ), checker + ) + edges.add( + Edge( + config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_LIN_INT_EXPL_NWT_IT_WP_Z3, config_LIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_LIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode( + "LIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -353,9 +444,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 300000 - ), checker) + ), checker + ) edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_EXPL_SEQ_ITP_mathsat, solverError)) - val config_LIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", + val config_LIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode( + "LIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -363,12 +456,22 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError)) - val config_LIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + ), checker + ) + edges.add( + Edge( + config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_LIN_INT_EXPL_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_LIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( + "LIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -376,9 +479,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_LIN_INT_PRED_CART_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_mathsat, solverError)) - val config_LIN_INT_PRED_CART_SEQ_ITP_z3 = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + val config_LIN_INT_PRED_CART_SEQ_ITP_z3 = ConfigNode( + "LIN_INT_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -386,9 +491,11 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add(Edge(config_LIN_INT_PRED_CART_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_z3, solverError)) - val config_NONLIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", + val config_NONLIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode( + "NONLIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -396,8 +503,10 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) - val config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + ), checker + ) + val config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode( + "NONLIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -405,9 +514,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) + ), checker + ) edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_NONLIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", + val config_NONLIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode( + "NONLIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -415,12 +526,22 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 100000 - ), checker) - edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError)) - val config_NONLIN_INT_EXPL_SEQ_ITP_z3 = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_z3:4.12.2-$inProcess", + ), checker + ) + edges.add( + Edge( + config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_NONLIN_INT_EXPL_SEQ_ITP_z3 = ConfigNode( + "NONLIN_INT_EXPL_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -428,9 +549,11 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 100000 - ), checker) + ), checker + ) edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_z3, solverError)) - val config_NONLIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_NONLIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode( + "NONLIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -438,23 +561,38 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 200000 - ), checker) - edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) + ), checker + ) + edges.add( + Edge( + config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_NONLIN_INT_EXPL_SEQ_ITP_z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) val config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( "NONLIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.SEQ_ITP, - timeoutMs = 0 - ), checker) - edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError)) - val config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode("NONLIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.SEQ_ITP, + timeoutMs = 0 + ), checker + ) + edges.add( + Edge( + config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode( + "NONLIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -462,10 +600,13 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add( - Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, solverError)) - val config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5 = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, solverError) + ) + val config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5 = ConfigNode( + "NONLIN_INT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -473,12 +614,22 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, - if (inProcess) timeoutOrSolverError else anyError)) - val config_ARR_EXPL_NWT_IT_WP_cvc5 = ConfigNode("ARR_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_ARR_EXPL_NWT_IT_WP_cvc5 = ConfigNode( + "ARR_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -486,29 +637,43 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker) - val config_ARR_EXPL_NWT_IT_WP_Z3 = ConfigNode("ARR_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 100000 - ), checker) + ), checker + ) + val config_ARR_EXPL_NWT_IT_WP_Z3 = ConfigNode( + "ARR_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 100000 + ), checker + ) edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_EXPL_NWT_IT_WP_Z3, solverError)) - val config_ARR_PRED_CART_SEQ_ITP_Z3 = ConfigNode("ARR_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.SEQ_ITP, - timeoutMs = 300000 - ), checker) - edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_Z3, config_ARR_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError)) - val config_ARR_PRED_CART_SEQ_ITP_z3 = ConfigNode("ARR_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + val config_ARR_PRED_CART_SEQ_ITP_Z3 = ConfigNode( + "ARR_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.SEQ_ITP, + timeoutMs = 300000 + ), checker + ) + edges.add( + Edge( + config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_ARR_EXPL_NWT_IT_WP_Z3, config_ARR_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_ARR_PRED_CART_SEQ_ITP_z3 = ConfigNode( + "ARR_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -516,9 +681,11 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 300000 - ), checker) + ), checker + ) edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_z3, solverError)) - val config_ARR_PRED_CART_SEQ_ITP_princess = ConfigNode("ARR_PRED_CART_SEQ_ITP_princess:2023-06-19-$inProcess", + val config_ARR_PRED_CART_SEQ_ITP_princess = ConfigNode( + "ARR_PRED_CART_SEQ_ITP_princess:2023-06-19-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -526,12 +693,22 @@ fun complexPortfolio24( refinementSolver = "princess:2023-06-19", refinement = Refinement.SEQ_ITP, timeoutMs = 500000 - ), checker) - edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_princess, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_z3, config_ARR_PRED_CART_SEQ_ITP_princess, - if (inProcess) timeoutOrSolverError else anyError)) - val config_ARR_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("ARR_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker + ) + edges.add( + Edge( + config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_princess, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_ARR_PRED_CART_SEQ_ITP_z3, config_ARR_PRED_CART_SEQ_ITP_princess, + if (inProcess) timeoutOrSolverError else anyError + ) + ) + val config_ARR_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( + "ARR_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -539,9 +716,11 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 500000 - ), checker) + ), checker + ) edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_princess, config_ARR_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_MULTITHREAD_EXPL_SEQ_ITP_Z3 = ConfigNode("MULTITHREAD_EXPL_SEQ_ITP_Z3-$inProcess", + val config_MULTITHREAD_EXPL_SEQ_ITP_Z3 = ConfigNode( + "MULTITHREAD_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -549,8 +728,10 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 150000 - ), checker) - val config_MULTITHREAD_EXPL_SEQ_ITP_mathsat = ConfigNode("MULTITHREAD_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + ), checker + ) + val config_MULTITHREAD_EXPL_SEQ_ITP_mathsat = ConfigNode( + "MULTITHREAD_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -558,9 +739,11 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 150000 - ), checker) + ), checker + ) edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, solverError)) - val config_MULTITHREAD_EXPL_NWT_IT_WP_z3 = ConfigNode("MULTITHREAD_EXPL_NWT_IT_WP_z3:4.12.2-$inProcess", + val config_MULTITHREAD_EXPL_NWT_IT_WP_z3 = ConfigNode( + "MULTITHREAD_EXPL_NWT_IT_WP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -568,22 +751,33 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.NWT_IT_WP, timeoutMs = 300000 - ), checker) - edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, - if (inProcess) timeoutOrSolverError else anyError)) + ), checker + ) + edges.add( + Edge( + config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) val config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat = ConfigNode( "MULTITHREAD_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 300000 - ), checker) + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 300000 + ), checker + ) edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3 = ConfigNode("MULTITHREAD_PRED_CART_SEQ_ITP_Z3-$inProcess", + val config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3 = ConfigNode( + "MULTITHREAD_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -591,23 +785,35 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) - edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError)) - edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError)) + ), checker + ) + edges.add( + Edge( + config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError + ) + ) + edges.add( + Edge( + config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError + ) + ) val config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat = ConfigNode( "MULTITHREAD_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.SEQ_ITP, - timeoutMs = 0 - ), checker) + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.SEQ_ITP, + timeoutMs = 0 + ), checker + ) edges.add( - Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, solverError)) - val config_MULTITHREAD_PRED_CART_SEQ_ITP_z3 = ConfigNode("MULTITHREAD_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, solverError) + ) + val config_MULTITHREAD_PRED_CART_SEQ_ITP_z3 = ConfigNode( + "MULTITHREAD_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -615,9 +821,11 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker) + ), checker + ) edges.add( - Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_z3, solverError)) + Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_z3, solverError) + ) if (trait == ArithmeticTrait.BITWISE) { return STM(config_BITWISE_EXPL_NWT_IT_WP_cvc5, edges) } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt index 5a3933b59c..1a56abd89c 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt @@ -34,7 +34,8 @@ fun hornPortfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger): STM { + uniqueLogger: Logger +): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -43,12 +44,14 @@ fun hornPortfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property), + property = portfolioConfig.inputConfig.property + ), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) + ), backendConfig = BackendConfig( backend = Backend.CHC, solverHome = portfolioConfig.backendConfig.solverHome, @@ -56,7 +59,8 @@ fun hornPortfolio( specConfig = HornConfig( solver = "z3:4.13.0", validateSolver = false - )), + ) + ), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -103,34 +107,42 @@ fun hornPortfolio( timeoutMs: Long = 0, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, HornConfig> { - return copy(backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - solver = solver, + return copy( + backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + solver = solver, + ) ) - )) + ) } fun getStm(inProcess: Boolean): STM { val edges = LinkedHashSet() - val configZ3 = ConfigNode("Z3-$inProcess", + val configZ3 = ConfigNode( + "Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, timeoutMs = 100_000 - ), checker) - val configEldarica = ConfigNode("Eldarica-$inProcess", + ), checker + ) + val configEldarica = ConfigNode( + "Eldarica-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, solver = "eldarica:2.1", timeoutMs = 500_000 - ), checker) - val configGolem = ConfigNode("Golem-$inProcess", + ), checker + ) + val configGolem = ConfigNode( + "Golem-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, solver = "golem:0.5.0", timeoutMs = 300_000 - ), checker) + ), checker + ) edges.add(Edge(configZ3, configEldarica, anyError)) edges.add(Edge(configEldarica, configGolem, anyError)) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt index d98b44e8f9..27d08a1c2b 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt @@ -36,8 +36,10 @@ ${innerSTM.visualize()} }""".trimIndent() } -class ConfigNode(name: String, private val config: XcfaConfig<*, *>, - private val check: (config: XcfaConfig<*, *>) -> SafetyResult<*, *>) : Node(name) { +class ConfigNode( + name: String, private val config: XcfaConfig<*, *>, + private val check: (config: XcfaConfig<*, *>) -> SafetyResult<*, *> +) : Node(name) { override fun execute(): Pair { println("Current configuration: $config") @@ -48,10 +50,12 @@ class ConfigNode(name: String, private val config: XcfaConfig<*, *>, .map { "state ${name.replace(Regex("[:\\.-]+"), "_")}: $it" }.reduce { a, b -> "$a\n$b" } } -data class Edge(val source: Node, +data class Edge( + val source: Node, val target: Node, val trigger: (Throwable) -> Boolean, - val guard: (Node, Edge) -> Boolean = { _, _ -> true }) { + val guard: (Node, Edge) -> Boolean = { _, _ -> true } +) { init { source.outEdges.add(this) @@ -70,8 +74,10 @@ class ExceptionTrigger( val label: String? = null ) : (Throwable) -> Boolean { - constructor(vararg exceptions: Throwable, label: String? = null) : this(exceptions.toSet(), - label = label) + constructor(vararg exceptions: Throwable, label: String? = null) : this( + exceptions.toSet(), + label = label + ) override fun invoke(e: Throwable): Boolean = if (exceptions.isNotEmpty()) @@ -89,7 +95,8 @@ data class STM(val initNode: Node, val edges: Set) { val nodes = edges.map { listOf(it.source, it.target) }.flatten().toSet() nodes.forEach { check( - it.parent == null || it.parent === this) { "Edges to behave encapsulated (offender: $it)" } + it.parent == null || it.parent === this + ) { "Edges to behave encapsulated (offender: $it)" } it.parent = this } } @@ -116,9 +123,11 @@ ${edges.map { it.visualize() }.reduce { a, b -> "$a\n$b" }} println("Handling exception as ${edge.trigger}") currentNode = edge.target } else { - println("Could not handle trigger $e (Available triggers: ${ - currentNode.outEdges.map { it.trigger }.toList() - })") + println( + "Could not handle trigger $e (Available triggers: ${ + currentNode.outEdges.map { it.trigger }.toList() + })" + ) throw e } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt index ad9011bd82..72ddc379d7 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt @@ -76,30 +76,39 @@ private fun traceHelper(stateType: java.lang.reflect.Type): java.lang.reflect.Ty ).type @JvmOverloads -internal fun getGson(xcfa: XCFA, domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") }): Gson { +internal fun getGson( + xcfa: XCFA, domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") } +): Gson { val (scope, env) = xcfa.getSymbols() return getGson(scope, env, false, domain, solver) } @JvmOverloads -internal fun getGson(domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") }): Gson { +internal fun getGson( + domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") } +): Gson { return getGson(XcfaScope(SymbolTable()), Env(), true, domain, solver) } -private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> Domain, - solver: () -> Solver): Gson { +private fun getGson( + scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> Domain, + solver: () -> Solver +): Gson { val gsonBuilder = GsonBuilder() lateinit var gson: Gson gsonBuilder.registerTypeHierarchyAdapter(FrontendConfig::class.java, SpecFrontendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(BackendConfig::class.java, SpecBackendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(File::class.java, StringTypeAdapter { File(it) }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter)) + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLocation::class.java, + StringTypeAdapter(xcfaLocationAdapter) + ) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope)) + VarDeclAdapter({ gson }, scope, env, !newScope) + ) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -110,9 +119,11 @@ private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, - PredStateAdapter({ gson }, scope, env)) + PredStateAdapter({ gson }, scope, env) + ) gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson })) + XcfaLabelAdapter(scope, env, { gson }) + ) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) @@ -120,15 +131,19 @@ private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> XcfaStateAdapter({ gson }) { domain().stateType }) gsonBuilder.registerTypeHierarchyAdapter(XcfaAction::class.java, XcfaActionAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, TraceAdapter({ gson }, { - TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, - domain().stateType).type + TypeToken.getParameterized( + TypeToken.get(XcfaState::class.java).type, + domain().stateType + ).type }, TypeToken.get(XcfaAction::class.java).type)) gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, ArgAdapter({ gson }, { domain().partialOrd(solver()) }, - { argAdapterHelper(domain().stateType) })) + { argAdapterHelper(domain().stateType) }) + ) gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, SafetyResultAdapter({ gson }, { argHelper(domain().stateType) }, - { traceHelper(domain().stateType) })) + { traceHelper(domain().stateType) }) + ) gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, ParseContextAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(FrontendMetadata::class.java, diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt index c053280a14..cc3c24338d 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt @@ -36,8 +36,10 @@ fun determineProperty(config: XcfaConfig<*, *>, logger: Logger): ErrorDetection } else -> { - logger.write(Logger.Level.INFO, - "Unknown property $propertyFile, using full state space exploration (no refinement)\n") + logger.write( + Logger.Level.INFO, + "Unknown property $propertyFile, using full state space exploration (no refinement)\n" + ) ErrorDetection.NO_ERROR } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt index cb18d5c237..a987f153d7 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt @@ -46,13 +46,17 @@ fun getXcfa(config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger when (config.frontendConfig.inputType) { InputType.CHC -> { val chcConfig = config.frontendConfig.specConfig as CHCFrontendConfig - parseChc(config.inputConfig.input!!, chcConfig.chcTransformation, parseContext, logger, - uniqueWarningLogger) + parseChc( + config.inputConfig.input!!, chcConfig.chcTransformation, parseContext, logger, + uniqueWarningLogger + ) } InputType.C -> { - parseC(config.inputConfig.input!!, config.inputConfig.property, parseContext, logger, - uniqueWarningLogger) + parseC( + config.inputConfig.input!!, config.inputConfig.property, parseContext, logger, + uniqueWarningLogger + ) } InputType.LLVM -> XcfaUtils.fromFile(config.inputConfig.input!!, ArithmeticType.efficient) @@ -76,48 +80,65 @@ fun getXcfa(config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger exitProcess(ExitCodes.FRONTEND_FAILED.code) } -private fun parseC(input: File, explicitProperty: ErrorDetection, parseContext: ParseContext, logger: Logger, - uniqueWarningLogger: Logger): XCFA { +private fun parseC( + input: File, explicitProperty: ErrorDetection, parseContext: ParseContext, logger: Logger, + uniqueWarningLogger: Logger +): XCFA { val xcfaFromC = try { val stream = FileInputStream(input) - getXcfaFromC(stream, parseContext, false, - explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger).first + getXcfaFromC( + stream, parseContext, false, + explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger + ).first } catch (e: Throwable) { if (parseContext.arithmetic == ArchitectureConfig.ArithmeticType.efficient) { parseContext.arithmetic = ArchitectureConfig.ArithmeticType.bitvector logger.write(Logger.Level.INFO, "Retrying parsing with bitvector arithmetic...\n") val stream = FileInputStream(input) - val xcfa = getXcfaFromC(stream, parseContext, false, - explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger).first + val xcfa = getXcfaFromC( + stream, parseContext, false, + explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger + ).first parseContext.addArithmeticTrait(ArithmeticTrait.BITWISE) xcfa } else { throw e } } - logger.write(Logger.Level.RESULT, - "Arithmetic: ${parseContext.arithmeticTraits}\n") + logger.write( + Logger.Level.RESULT, + "Arithmetic: ${parseContext.arithmeticTraits}\n" + ) return xcfaFromC } -private fun parseChc(input: File, chcTransformation: ChcFrontend.ChcTransformation, parseContext: ParseContext, - logger: Logger, uniqueWarningLogger: Logger): XCFA { +private fun parseChc( + input: File, chcTransformation: ChcFrontend.ChcTransformation, parseContext: ParseContext, + logger: Logger, uniqueWarningLogger: Logger +): XCFA { var chcFrontend: ChcFrontend - val xcfaBuilder = if (chcTransformation == ChcFrontend.ChcTransformation.PORTFOLIO) { // try forward, fallback to backward - chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.FORWARD) - try { - chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger)) - } catch (e: UnsupportedOperationException) { - logger.write(Logger.Level.INFO, "Non-linear CHC found, retrying using backward transformation...\n") - chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.BACKWARD) - chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger)) + val xcfaBuilder = + if (chcTransformation == ChcFrontend.ChcTransformation.PORTFOLIO) { // try forward, fallback to backward + chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.FORWARD) + try { + chcFrontend.buildXcfa( + CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger) + ) + } catch (e: UnsupportedOperationException) { + logger.write(Logger.Level.INFO, "Non-linear CHC found, retrying using backward transformation...\n") + chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.BACKWARD) + chcFrontend.buildXcfa( + CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger) + ) + } + } else { + chcFrontend = ChcFrontend(chcTransformation) + chcFrontend.buildXcfa( + CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger) + ) } - } else { - chcFrontend = ChcFrontend(chcTransformation) - chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger)) - } return xcfaBuilder.build() } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt index 722fa7d91d..5ad00f3717 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt @@ -47,7 +47,8 @@ class XcfaWitnessWriter { if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, cexSolverFactory, - parseContext) + parseContext + ) val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) val witness = Witness(witnessTrace, inputFile) @@ -57,63 +58,93 @@ class XcfaWitnessWriter { val taskHash = WitnessWriter.createTaskHash(inputFile.absolutePath) val dummyWitness = StringBuilder() dummyWitness.append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "false").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") + "false" + ).append(System.lineSeparator()).append( + "" + ).append(System.lineSeparator()).append( + "" + ) .append(System.lineSeparator()).append( - "false").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") + "false" + ).append(System.lineSeparator()).append( + "" + ).append(System.lineSeparator()).append( + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "") + "" + ) .append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "correctness_witness") + "" + ).append(System.lineSeparator()).append( + "correctness_witness" + ) .append(System.lineSeparator()).append( - "theta").append(System.lineSeparator()).append( - "CHECK( init(main()), LTL(G ! call(reach_error())) )") + "theta" + ).append(System.lineSeparator()).append( + "CHECK( init(main()), LTL(G ! call(reach_error())) )" + ) .append(System.lineSeparator()).append( - "C").append(System.lineSeparator()).append( - "32bit").append(System.lineSeparator()) + "C" + ).append(System.lineSeparator()).append( + "32bit" + ).append(System.lineSeparator()) .append( - "") + "" + ) dummyWitness.append(taskHash) dummyWitness.append("").append(System.lineSeparator()).append( - "") + "" + ) val tz: TimeZone = TimeZone.getTimeZone("UTC") val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ) // Quoted "Z" to indicate UTC, no timezone offset df.timeZone = tz val isoDate: String = df.format(Date()) dummyWitness.append(isoDate) dummyWitness.append("").append(System.lineSeparator()).append( - "") + "" + ) dummyWitness.append(inputFile.name) dummyWitness.append("").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "true").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "").append(System.lineSeparator()).append( - "") + "" + ).append(System.lineSeparator()).append( + "true" + ).append(System.lineSeparator()).append( + "" + ).append(System.lineSeparator()).append( + "" + ).append(System.lineSeparator()).append( + "" + ) try { BufferedWriter(FileWriter(witnessfile)).use { bw -> diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt index 38ab39f52b..d6848feffe 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt @@ -46,8 +46,10 @@ fun traceToWitness( val newStates = ArrayList() val newActions = ArrayList() - var lastNode = WitnessNode(id = "N${newStates.size}", entry = true, sink = false, - violation = false) + var lastNode = WitnessNode( + id = "N${newStates.size}", entry = true, sink = false, + violation = false + ) newStates.add(lastNode) for (i in 0 until trace.length()) { @@ -67,8 +69,10 @@ fun traceToWitness( ) if (node != WitnessNode(id = "N${newStates.size}")) { newStates.add(node) - val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, - threadId = trace.actions[i].pid.toString()) + val edge = WitnessEdge( + sourceId = lastNode.id, targetId = node.id, + threadId = trace.actions[i].pid.toString() + ) newActions.add(edge) lastNode = node } @@ -76,10 +80,14 @@ fun traceToWitness( val action = trace.actions[i] val flattenedSequence = flattenSequence(action.edge.label) for (xcfaLabel in flattenedSequence) { - val node = WitnessNode(id = "N${newStates.size}", entry = false, sink = false, - violation = false) - var edge = labelToEdge(lastNode, node, xcfaLabel, action.pid, - nextState.sGlobal.getVal(), parseContext) + val node = WitnessNode( + id = "N${newStates.size}", entry = false, sink = false, + violation = false + ) + var edge = labelToEdge( + lastNode, node, xcfaLabel, action.pid, + nextState.sGlobal.getVal(), parseContext + ) if (newThreads.isNotEmpty() && xcfaLabel is StartLabel) { edge = edge.copy(createThread = newThreads.joinToString(",")) } @@ -120,8 +128,10 @@ fun shouldInclude(edge: WitnessEdge, verbosity: Verbosity): Boolean = } -private fun labelToEdge(lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, - valuation: Valuation, parseContext: ParseContext): WitnessEdge = +private fun labelToEdge( + lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, + valuation: Valuation, parseContext: ParseContext +): WitnessEdge = WitnessEdge( sourceId = lastNode.id, targetId = node.id, @@ -190,14 +200,17 @@ private fun printLit(litExpr: LitExpr<*>): String? { for (i in boolList.indices) { if (i % 4 == 0 && i > 0) { if (aggregate < 10) hexDigits.add( - ('0'.code + aggregate).toChar()) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar()) + ('0'.code + aggregate).toChar() + ) else hexDigits.add( + ('A'.code - 10 + aggregate).toChar() + ) aggregate = 0 } if (boolList[i]) aggregate += 1 shl i % 4 } if (aggregate < 10) hexDigits.add(('0'.code + aggregate).toChar()) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar()) + ('A'.code - 10 + aggregate).toChar() + ) val stringBuilder = StringBuilder("0x") for (character in Lists.reverse(hexDigits)) { stringBuilder.append(character) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt index 4569a1b557..4bcbcc99bb 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt @@ -59,8 +59,12 @@ class Witness(private val trace: Trace, programFile: F attributes.add(WitnessAttribute("assumption", "string", "edge", "assumption")) attributes.add(WitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")) - attributes.add(WitnessAttribute("assumption.resultfunction", "string", "edge", - "assumption.resultfunction")) + attributes.add( + WitnessAttribute( + "assumption.resultfunction", "string", "edge", + "assumption.resultfunction" + ) + ) attributes.add(WitnessAttribute("control", "string", "edge", "control")) attributes.add(WitnessAttribute("startline", "string", "edge", "startline")) attributes.add(WitnessAttribute("endline", "string", "edge", "endline")) @@ -69,7 +73,8 @@ class Witness(private val trace: Trace, programFile: F attributes.add(WitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) attributes.add(WitnessAttribute("enterFunction", "string", "edge", "enterFunction")) attributes.add( - WitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction")) + WitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction") + ) attributes.add(WitnessAttribute("threadId", "string", "edge", "threadId")) attributes.add(WitnessAttribute("createThread", "string", "edge", "createThread")) attributes.add(WitnessAttribute("stmt", "string", "edge", "stmt")) @@ -271,7 +276,8 @@ private fun bytesToHex(hash: ByteArray): String { private fun getIsoDate(): String { val tz: TimeZone = TimeZone.getTimeZone("UTC") val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ) // Quoted "Z" to indicate UTC, no timezone offset df.timeZone = tz return df.format(Date()) @@ -281,7 +287,8 @@ private fun getIsoDate(): String { private fun prettyFormat(input: String, indent: Int): String { return try { val xmlInput: Source = StreamSource( - StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) + StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), "")) + ) val stringWriter = StringWriter() val xmlOutput = StreamResult(stringWriter) val transformerFactory: TransformerFactory = TransformerFactory.newInstance() diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt index a6aa6b8bb5..d886fe23dd 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt @@ -169,12 +169,14 @@ class XcfaCliParseTest { @ParameterizedTest @MethodSource("cFiles") fun testCParse(filePath: String) { - main(arrayOf( - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", "--stacktrace", + "--debug" + ) + ) } // @ParameterizedTest @@ -192,61 +194,71 @@ class XcfaCliParseTest { @ParameterizedTest @MethodSource("chcFiles") fun testCHCParse(filePath: String, chcTransformation: ChcFrontend.ChcTransformation) { - main(arrayOf( - "--input-type", "CHC", - "--chc-transformation", chcTransformation.toString(), - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "CHC", + "--chc-transformation", chcTransformation.toString(), + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + ) + ) } @ParameterizedTest @MethodSource("dslFiles") fun testDSLParse(filePath: String) { - main(arrayOf( - "--input-type", "DSL", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "DSL", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + ) + ) } @ParameterizedTest @MethodSource("jsonFiles") fun testJSONParse(filePath: String) { - main(arrayOf( - "--input-type", "JSON", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "JSON", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + ) + ) } @ParameterizedTest @MethodSource("cFiles") fun testJSONParseRoundTrip(filePath: String) { val temp = createTempDirectory() - main(arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - )) + main( + arrayOf( + "--enable-output", + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--output-directory", temp.toAbsolutePath().toString(), + "--debug" + ) + ) val xcfaJson = temp.resolve("xcfa.json").toFile() - main(arrayOf( - "--input-type", "JSON", - "--input", xcfaJson.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "JSON", + "--input", xcfaJson.absolutePath.toString(), + "--backend", "NONE", + "--stacktrace", + "--debug" + ) + ) temp.toFile().deleteRecursively() } @@ -254,24 +266,28 @@ class XcfaCliParseTest { @MethodSource("simpleCFiles") fun testCParseRoundTrip(filePath: String) { val temp = createTempDirectory() - main(arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - )) + main( + arrayOf( + "--enable-output", + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--output-directory", temp.toAbsolutePath().toString(), + "--debug" + ) + ) val xcfaC = temp.resolve("xcfa.c").toFile() checkState(xcfaC.exists(), "File does not exist: $xcfaC") - main(arrayOf( - "--input-type", "C", - "--input", xcfaC.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - )) + main( + arrayOf( + "--input-type", "C", + "--input", xcfaC.absolutePath.toString(), + "--backend", "NONE", + "--stacktrace", + "--debug" + ) + ) temp.toFile().deleteRecursively() } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt index 9d9dc0e0f2..d7838c0403 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt @@ -63,17 +63,23 @@ class XcfaCliPortfolioTest { @ParameterizedTest @MethodSource("portfolios") - fun testPortfolio(portfolio: (xcfa: XCFA, - mcm: MCM, - parseContext: ParseContext, - portfolioConfig: XcfaConfig<*, *>, - logger: Logger, - uniqueLogger: Logger) -> STM) { + fun testPortfolio( + portfolio: ( + xcfa: XCFA, + mcm: MCM, + parseContext: ParseContext, + portfolioConfig: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger + ) -> STM + ) { for (value in ArithmeticTrait.values()) { - val stm = portfolio(XCFA("name", setOf()), emptySet(), ParseContext(), - XcfaConfig(), NullLogger.getInstance(), NullLogger.getInstance()) + val stm = portfolio( + XCFA("name", setOf()), emptySet(), ParseContext(), + XcfaConfig(), NullLogger.getInstance(), NullLogger.getInstance() + ) Assertions.assertTrue(stm.visualize().isNotEmpty()) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt index c5fb4dbb56..8b1c73b540 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt @@ -144,8 +144,10 @@ class XcfaCliVerifyTest { fun chcFiles(): Stream { return Stream.of( Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.FORWARD, "--domain PRED_CART"), - Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD, - "--domain PRED_CART --search BFS"), + Arguments.of( + "/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD, + "--domain PRED_CART --search BFS" + ), ) } } @@ -243,14 +245,16 @@ class XcfaCliVerifyTest { @ParameterizedTest @MethodSource("chcFiles") fun testCHCVerify(filePath: String, chcTransformation: ChcFrontend.ChcTransformation, extraArgs: String?) { - main(arrayOf( - "--input-type", "CHC", - "--chc-transformation", chcTransformation.toString(), - "--input", javaClass.getResource(filePath)!!.path, - "--stacktrace", - *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), - "--debug" - )) + main( + arrayOf( + "--input-type", "CHC", + "--chc-transformation", chcTransformation.toString(), + "--input", javaClass.getResource(filePath)!!.path, + "--stacktrace", + *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), + "--debug" + ) + ) } @ParameterizedTest diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt index bc5657f5ba..8405c761ae 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt @@ -39,24 +39,28 @@ class XcfaCliWitnessTest { @JvmStatic fun cFiles(): Stream { return Stream.of( - Arguments.of("/c/litmustest/singlethread/witness_test.c", null, listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - )), - Arguments.of("/c/litmustest/singlethread/witness_test.c", "--backend BOUNDED", listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - )), + Arguments.of( + "/c/litmustest/singlethread/witness_test.c", null, listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ), + ) + ), + Arguments.of( + "/c/litmustest/singlethread/witness_test.c", "--backend BOUNDED", listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ), + ) + ), ) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt index 53d5ba6130..8fb8f64b90 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt @@ -88,18 +88,23 @@ class XcfaDslTest { fun verifyXcfa() { SolverManager.registerSolverManager(Z3SolverManager.create()) val config = XcfaConfig( - backendConfig = BackendConfig(backend = Backend.CEGAR, specConfig = CegarConfig())) + backendConfig = BackendConfig(backend = Backend.CEGAR, specConfig = CegarConfig()) + ) run { val xcfa = getSyncXcfa() - val checker = getChecker(xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), - NullLogger.getInstance()) + val checker = getChecker( + xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), + NullLogger.getInstance() + ) val safetyResult = checker.check() Assert.assertTrue(safetyResult.isSafe) } run { val xcfa = getAsyncXcfa() - val checker = getChecker(xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), - NullLogger.getInstance()) + val checker = getChecker( + xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), + NullLogger.getInstance() + ) val safetyResult = checker.check() Assert.assertTrue(safetyResult.isUnsafe) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt index 51372ee26d..fc7783b64f 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt @@ -55,11 +55,17 @@ class XcfaToCTest { val chcFrontend = ChcFrontend(chcTransformation) val xcfa = chcFrontend.buildXcfa( CharStreams.fromStream(FileInputStream(javaClass.getResource(filePath)!!.path)), ChcPasses( - ParseContext(), NullLogger.getInstance())).build() + ParseContext(), NullLogger.getInstance() + ) + ).build() val temp = createTempDirectory() val file = temp.resolve("${filePath.split("/").last()}.c").also { - it.toFile().writeText(xcfa.toC(ParseContext(), - true, false, false)) + it.toFile().writeText( + xcfa.toC( + ParseContext(), + true, false, false + ) + ) } System.err.println(file) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts b/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts index fb98c7344d..2a8aaae312 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts @@ -34,7 +34,8 @@ fun portfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger): STM { + uniqueLogger: Logger +): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -43,12 +44,14 @@ fun portfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property), + property = portfolioConfig.inputConfig.property + ), frontendConfig = FrontendConfig( lbeLevel = LbePass.LbeLevel.LBE_SEQ, loopUnroll = 50, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) + ), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -72,7 +75,9 @@ fun portfolio( refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ))), + ) + ) + ), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -91,7 +96,8 @@ fun portfolio( abstractorConfig = baseCegarConfig.abstractorConfig.copy(search = Search.DFS), ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) + ) } if (!xcfa.isInlined) { diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt index cc6f24571b..924f0f7a24 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt @@ -453,27 +453,35 @@ fun XcfaLabel.simplify(valuation: MutableValuation, parseContext: ParseContext): is MemoryAssignStmt<*, *, *> -> { simplified as MemoryAssignStmt<*, *, *> if (parseContext.metadata.getMetadataValue(stmt.expr, "cType").isPresent) - parseContext.metadata.create(simplified.expr, "cType", - CComplexType.getType(stmt.expr, parseContext)) + parseContext.metadata.create( + simplified.expr, "cType", + CComplexType.getType(stmt.expr, parseContext) + ) if (parseContext.metadata.getMetadataValue(stmt.deref, "cType").isPresent) - parseContext.metadata.create(simplified.deref, "cType", - CComplexType.getType(stmt.deref, parseContext)) + parseContext.metadata.create( + simplified.deref, "cType", + CComplexType.getType(stmt.deref, parseContext) + ) StmtLabel(simplified, metadata = metadata) } is AssignStmt<*> -> { simplified as AssignStmt<*> if (parseContext.metadata.getMetadataValue(stmt.expr, "cType").isPresent) - parseContext.metadata.create(simplified.expr, "cType", - CComplexType.getType(stmt.expr, parseContext)) + parseContext.metadata.create( + simplified.expr, "cType", + CComplexType.getType(stmt.expr, parseContext) + ) StmtLabel(simplified, metadata = metadata) } is AssumeStmt -> { simplified as AssumeStmt if (parseContext.metadata.getMetadataValue(stmt.cond, "cType").isPresent) { - parseContext.metadata.create(simplified.cond, "cType", - CComplexType.getType(stmt.cond, parseContext)) + parseContext.metadata.create( + simplified.cond, "cType", + CComplexType.getType(stmt.cond, parseContext) + ) } parseContext.metadata.create(simplified, "cTruth", stmt.cond is NeqExpr<*>) StmtLabel(simplified, metadata = metadata, choiceType = choiceType) @@ -520,8 +528,10 @@ val XCFA.lazyPointsToGraph: Lazy, Set>>> .filter { (i, pair) -> pair.second != ParamDirection.IN && it.params[i] is RefExpr<*> } .map { (i, pair) -> val (param, _) = pair - Assign(cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), - cast(param.ref, param.type)) + Assign( + cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), + cast(param.ref, param.type) + ) } } ?: listOf() } @@ -534,8 +544,10 @@ val XCFA.lazyPointsToGraph: Lazy, Set>>> Assign(cast(param, param.type), cast(it.params[i], param.type)) } + proc.params.filter { it.second != ParamDirection.IN }.mapIndexed { i, (param, _) -> - Assign(cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), - cast(param.ref, param.type)) + Assign( + cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), + cast(param.ref, param.type) + ) } } ?: listOf() } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt index 6eacb8f086..0114015fc1 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt @@ -57,8 +57,10 @@ import hu.bme.mit.theta.xcfa.model.* private const val arraySize = 10; -fun XCFA.toC(parseContext: ParseContext, arraySupport: Boolean, exactArraySupport: Boolean, - intRangeConstraint: Boolean): String = """ +fun XCFA.toC( + parseContext: ParseContext, arraySupport: Boolean, exactArraySupport: Boolean, + intRangeConstraint: Boolean +): String = """ extern void abort(); extern unsigned short __VERIFIER_nondet_ushort(); extern short __VERIFIER_nondet_short(); diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt index 9cf2736445..338ff8d66d 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt @@ -111,7 +111,8 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { private fun parseInitProcedures( reader: JsonReader, - procedures: Map): List>>> { + procedures: Map + ): List>>> { reader.beginArray() val ret = ArrayList>>>() val paramsType = object : TypeToken>>() {}.type @@ -190,9 +191,11 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { } } } - ret[name] = XcfaProcedure(name, params, vars, locs.values.toSet(), edges, initLoc, + ret[name] = XcfaProcedure( + name, params, vars, locs.values.toSet(), edges, initLoc, Optional.ofNullable(finalLoc), - Optional.ofNullable(errorLoc)).also { it.parent = xcfa } + Optional.ofNullable(errorLoc) + ).also { it.parent = xcfa } reader.endObject() } reader.endArray() diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt index eeebe05881..a06254cf5b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt @@ -80,11 +80,14 @@ class XcfaLabelAdapter(val scope: Scope, val env: Env, val gsonSupplier: () -> G checkNotNull(constructor) { "${clazz.simpleName} has no fromString() method." } val obj = try { - constructor.call(clazz.companionObject!!.objectInstance, content, scope, env, - metadata) + constructor.call( + clazz.companionObject!!.objectInstance, content, scope, env, + metadata + ) } catch (e: Exception) { System.err.println( - "Could not parse $content\nscope: ${scope}\nenv: $env\ntype: ${clazz.simpleName}") + "Could not parse $content\nscope: ${scope}\nenv: $env\ntype: ${clazz.simpleName}" + ) throw e } check(obj is XcfaLabel) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt index b146c7d4f9..e3885b34b8 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt @@ -39,10 +39,14 @@ class VarContext(val builder: XcfaBuilder, private val local: Boolean) { infix fun Pair.init(initValue: String): VarDecl { val varDecl = Var(first, second) builder.addVar( - XcfaGlobalVar(varDecl, + XcfaGlobalVar( + varDecl, ExpressionWrapper(SimpleScope(SymbolTable()), initValue).instantiate( - Env()) as LitExpr<*>, - local)) + Env() + ) as LitExpr<*>, + local + ) + ) return varDecl } } @@ -89,7 +93,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun start(vararg expr: Any) { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } builder.parent.addEntryPoint(builder, exprs) } @@ -112,7 +117,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { infix fun String.assign(to: String): SequenceLabel { val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this) as VarDecl + this + ) as VarDecl val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr val label = StmtLabel(Assign(lhs, rhs)) labelList.add(label) @@ -128,7 +134,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { infix fun String.assign(to: Expr<*>): SequenceLabel { val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this) as VarDecl + this + ) as VarDecl val rhs: Expr = to as Expr val label = StmtLabel(Assign(lhs, rhs)) labelList.add(label) @@ -171,7 +178,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { operator fun XcfaProcedureBuilderContext.invoke(vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = InvokeLabel(this.builder.name, exprs, EmptyMetaData) this@SequenceLabelContext.labelList.add(label) @@ -181,7 +189,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { operator fun String.invoke(vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = InvokeLabel(this, exprs, EmptyMetaData) this@SequenceLabelContext.labelList.add(label) @@ -192,7 +201,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = StartLabel(ctx.builder.name, exprs, lhs, EmptyMetaData) labelList.add(label) @@ -202,7 +212,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun VarDecl<*>.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = StartLabel(ctx.builder.name, exprs, this, EmptyMetaData) labelList.add(label) @@ -213,7 +224,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = StartLabel(ctx, exprs, lhs, EmptyMetaData) labelList.add(label) @@ -223,7 +235,8 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun VarDecl<*>.start(ctx: String, vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it) else error("Bad type") + it + ) else error("Bad type") } val label = StartLabel(ctx, exprs, this, EmptyMetaData) labelList.add(label) @@ -301,8 +314,10 @@ fun XcfaBuilder.threadlocal(lambda: VarContext.() -> Unit) { context.apply(lambda) } -fun XcfaBuilder.procedure(name: String, passManager: ProcedurePassManager, - lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { +fun XcfaBuilder.procedure( + name: String, passManager: ProcedurePassManager, + lambda: XcfaProcedureBuilderContext.() -> Unit +): XcfaProcedureBuilderContext { val builder = XcfaProcedureBuilder(name, passManager) builder.parent = this val procBuilder = XcfaProcedureBuilderContext(builder).apply(lambda) @@ -310,7 +325,9 @@ fun XcfaBuilder.procedure(name: String, passManager: ProcedurePassManager, return procBuilder } -fun XcfaBuilder.procedure(name: String, - lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { +fun XcfaBuilder.procedure( + name: String, + lambda: XcfaProcedureBuilderContext.() -> Unit +): XcfaProcedureBuilderContext { return procedure(name, ProcedurePassManager(), lambda) } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt index 177c75758d..4080379efa 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt @@ -37,7 +37,8 @@ fun XcfaProcedure.toDot(edgeLabelCustomizer: ((XcfaEdge) -> String)?): String { locs.forEach { builder.appendLine("${it.name}[];") } edges.forEach { builder.appendLine( - "${it.source.name} -> ${it.target.name} [label=\"${it.label} ${edgeLabelCustomizer?.invoke(it) ?: ""}\"];") + "${it.source.name} -> ${it.target.name} [label=\"${it.label} ${edgeLabelCustomizer?.invoke(it) ?: ""}\"];" + ) } return builder.toString() } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt index 93f636b306..519a9d8627 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt @@ -50,9 +50,11 @@ data class InvokeLabel @JvmOverloads constructor( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (name, params) = Regex("([^\\(]*)\\((.*)\\)").matchEntire(s)!!.destructured - return InvokeLabel(name, + return InvokeLabel( + name, params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, - metadata = metadata) + metadata = metadata + ) } } } @@ -87,11 +89,14 @@ data class StartLabel( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (pidVarName, pidVarType, name, params) = Regex( - "\\(var (.*) (.*)\\) = start (.*)\\((.*)\\)").matchEntire(s)!!.destructured + "\\(var (.*) (.*)\\) = start (.*)\\((.*)\\)" + ).matchEntire(s)!!.destructured val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> - return StartLabel(name, + return StartLabel( + name, params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, pidVar, - metadata = metadata) + metadata = metadata + ) } } } @@ -109,7 +114,8 @@ data class JoinLabel( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (pidVarName, pidVarType) = Regex("join \\(var (.*) (.*)\\)").matchEntire( - s)!!.destructured + s + )!!.destructured val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> return JoinLabel(pidVar, metadata = metadata) } @@ -130,7 +136,8 @@ data class StmtLabel @JvmOverloads constructor( init { check( - stmt !is NonDetStmt && stmt !is SequenceStmt) { "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } + stmt !is NonDetStmt && stmt !is SequenceStmt + ) { "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } } override fun toStmt(): Stmt = stmt @@ -147,11 +154,15 @@ data class StmtLabel @JvmOverloads constructor( val matchResult = Regex("\\((.*)\\)\\[choiceType=(.*)]").matchEntire(s) if (matchResult != null) { val (stmt, choiceTypeStr) = matchResult.destructured - return StmtLabel(StatementWrapper(stmt, scope).instantiate(env), - choiceType = ChoiceType.valueOf(choiceTypeStr), metadata = metadata) + return StmtLabel( + StatementWrapper(stmt, scope).instantiate(env), + choiceType = ChoiceType.valueOf(choiceTypeStr), metadata = metadata + ) } else { - return StmtLabel(StatementWrapper(s, scope).instantiate(env), - choiceType = ChoiceType.NONE, metadata = metadata) + return StmtLabel( + StatementWrapper(s, scope).instantiate(env), + choiceType = ChoiceType.NONE, metadata = metadata + ) } } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt index 17bbdde26e..7db5191f4b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt @@ -29,7 +29,8 @@ class AssumeFalseRemovalPass : ProcedurePass { override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { builder.getEdges().toSet().forEach { edge -> if (edge.getFlatLabels() - .any { it is StmtLabel && it.stmt is AssumeStmt && it.stmt.cond is FalseExpr }) { + .any { it is StmtLabel && it.stmt is AssumeStmt && it.stmt.cond is FalseExpr } + ) { builder.removeEdge(edge) } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt index d4927ebaad..5366595cc5 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt @@ -160,9 +160,12 @@ class AtomicReadsOneWritePass : ProcedurePass { private fun XcfaLabel.replaceAccesses(localVersions: Map, VarDecl<*>>): XcfaLabel { return when (this) { is StmtLabel -> when (val stmt = stmt) { - is AssignStmt<*> -> StmtLabel(AssignStmt.of( - cast(localVersions[stmt.varDecl] ?: stmt.varDecl, stmt.varDecl.type), - cast(stmt.expr.replace(localVersions), stmt.varDecl.type))) + is AssignStmt<*> -> StmtLabel( + AssignStmt.of( + cast(localVersions[stmt.varDecl] ?: stmt.varDecl, stmt.varDecl.type), + cast(stmt.expr.replace(localVersions), stmt.varDecl.type) + ) + ) is AssumeStmt -> StmtLabel(AssumeStmt.of(stmt.cond.replace(localVersions))) is HavocStmt<*> -> StmtLabel(HavocStmt.of(localVersions[stmt.varDecl] ?: stmt.varDecl)) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt index 7803f1daaf..9fddf43123 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt @@ -71,9 +71,13 @@ class CLibraryFunctionsPass : ProcedurePass { val param = invokeLabel.params[4] - listOf(StartLabel((funcptr as RefExpr).decl.name, - listOf(Int(0), param), // int(0) to solve StartLabel not handling return params - (handle as RefExpr).decl as VarDecl<*>, metadata)) + listOf( + StartLabel( + (funcptr as RefExpr).decl.name, + listOf(Int(0), param), // int(0) to solve StartLabel not handling return params + (handle as RefExpr).decl as VarDecl<*>, metadata + ) + ) } "pthread_mutex_lock" -> { @@ -101,8 +105,10 @@ class CLibraryFunctionsPass : ProcedurePass { check(handle is RefExpr && (handle as RefExpr).decl is VarDecl) listOf( - FenceLabel(setOf("start_cond_wait(${cond.decl.name},${handle.decl.name})"), - metadata), + FenceLabel( + setOf("start_cond_wait(${cond.decl.name},${handle.decl.name})"), + metadata + ), FenceLabel(setOf("cond_wait(${cond.decl.name},${handle.decl.name})"), metadata) ) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt index d539cb6240..6dd64e2b45 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt @@ -29,13 +29,16 @@ class ErrorLocationPass(private val checkOverflow: Boolean) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( - XcfaEdge(it.source, builder.errorLoc.get(), SequenceLabel(listOf()))) + XcfaEdge(it.source, builder.errorLoc.get(), SequenceLabel(listOf())) + ) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt index 0ed1eee7a1..89c11f3a78 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt @@ -74,28 +74,39 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { StmtLabel(Assign(cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type))) - } + InvokeLabel(this.name, this.params.map { it.replaceDerefs(lut) }, metadata, - tempLookup), metadata) + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) + ) + ) + } + InvokeLabel( + this.name, this.params.map { it.replaceDerefs(lut) }, metadata, + tempLookup + ), metadata + ) } is StartLabel -> { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { StmtLabel(Assign(cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type))) + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) + ) + ) } + StartLabel(name, params.map { it.replaceDerefs(lut) }, pidVar, metadata, tempLookup), metadata) } - is StmtLabel -> SequenceLabel(stmt.replaceDerefs(builder).map { StmtLabel(it, choiceType, metadata) }, - metadata) + is StmtLabel -> SequenceLabel( + stmt.replaceDerefs(builder).map { StmtLabel(it, choiceType, metadata) }, + metadata + ) else -> error("Not implemented for ${this.javaClass.simpleName}") } } else this - private fun getDerefLut(dereferences: List>, - builder: XcfaProcedureBuilder) = dereferences.associateWith { + private fun getDerefLut( + dereferences: List>, + builder: XcfaProcedureBuilder + ) = dereferences.associateWith { val tmpVar = Var("__THETA_heap_tmp_$cnt", it.type) builder.addVar(tmpVar) tmpVar @@ -119,14 +130,21 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { val accessType = dereferencesWithAccessTypes.filter { dereferences.contains(it.first) } for (dereference in accessType.filter { it.second.isRead }.map { it.first }) { ret.add(Assign(cast(lut[dereference]!!, dereference.type), - cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type))) + cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type) + ) + ) } ret.add(stmt) for (dereference in accessType.filter { it.second.isWritten }.map { it.first }) { - ret.add(MemoryAssign( - cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, - dereference.type) as Dereference<*, *, Type>, - cast(lut[dereference]!!, dereference.type).ref)) + ret.add( + MemoryAssign( + cast( + dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, + dereference.type + ) as Dereference<*, *, Type>, + cast(lut[dereference]!!, dereference.type).ref + ) + ) } return ret } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt index 987722b622..e586621cad 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt @@ -31,15 +31,23 @@ class FinalLocationPass(private val checkOverflow: Boolean) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { if (builder.finalLoc.isEmpty) builder.createFinalLoc() - builder.addEdge(XcfaEdge(it.source, builder.finalLoc.get(), SequenceLabel( - listOf( - StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata)), - metadata = it.metadata))) + builder.addEdge( + XcfaEdge( + it.source, builder.finalLoc.get(), SequenceLabel( + listOf( + StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata) + ), + metadata = it.metadata + ) + ) + ) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt index 8a05f0ef2b..8cabaf35e0 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt @@ -57,44 +57,78 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private val handlers: MutableMap> = LinkedHashMap() - private fun addHandler(names: Array, - handler: BiFunction) { + private fun addHandler( + names: Array, + handler: BiFunction + ) { for (name in names) { handlers[name] = handler } } init { - addHandler(arrayOf("fabs", "fabsf", - "fabsl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "fabs", "fabsf", + "fabsl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFabs(builder, callStmt) } - addHandler(arrayOf("floor", "floorf", - "floorl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "floor", "floorf", + "floorl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFloor(builder, callStmt) } - addHandler(arrayOf("fmax", "fmaxf", - "fmaxl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "fmax", "fmaxf", + "fmaxl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmax(builder, callStmt) } - addHandler(arrayOf("fmin", "fminf", - "fminl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "fmin", "fminf", + "fminl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmin(builder, callStmt) } - addHandler(arrayOf("fmod", "fmodf", - "fmodl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "fmod", "fmodf", + "fmodl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmod(builder, callStmt) } - addHandler(arrayOf("sqrt", "sqrtf", - "sqrtl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "sqrt", "sqrtf", + "sqrtl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleSqrt(builder, callStmt) } - addHandler(arrayOf("round", "roundf", - "roundl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "round", "roundf", + "roundl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleRound(builder, callStmt) } - addHandler(arrayOf("isnan", "__isnan", "isnanf", "__isnanf", "isnanl", - "__isnanl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "isnan", "__isnan", "isnanf", "__isnanf", "isnanl", + "__isnanl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsnan(builder, callStmt) } addHandler(arrayOf("trunc")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> @@ -103,22 +137,37 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { addHandler(arrayOf("ceil")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleCeil(builder, callStmt) } - addHandler(arrayOf( - "isnormal")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "isnormal" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsnormal(builder, callStmt) } - addHandler(arrayOf("isinf", "__isinf", "__isinff", "isinff", - "__isinfl", "isinfl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "isinf", "__isinf", "__isinff", "isinff", + "__isinfl", "isinfl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsinf(builder, callStmt) } - addHandler(arrayOf( - "isfinite", "finite", "isfinitef", "finitef", "isfinite", "finitel", "__finite", "__finitef", "__finitel", - "__isfinite", - "__isfinitef", "__isfinitel")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "isfinite", "finite", "isfinitef", "finitef", "isfinite", "finitel", "__finite", "__finitef", + "__finitel", + "__isfinite", + "__isfinitef", "__isfinitel" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsfinite(builder, callStmt) } - addHandler(arrayOf("__fpclassify", "__fpclassifyf", - "__fpclassifyl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler( + arrayOf( + "__fpclassify", "__fpclassifyf", + "__fpclassifyl" + ) + ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFpclassify(builder, callStmt) } } @@ -127,10 +176,16 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTZ, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTZ, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -141,10 +196,16 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTP, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTP, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -158,38 +219,54 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { val type = CSignedInt(null, parseContext) val assign: AssignStmt<*> = Stmts.Assign( TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast(AbstractExprs.Ite( - FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue), - type.smtType)) + TypeUtils.cast( + AbstractExprs.Ite( + FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + type.unitValue, type.nullValue + ), + type.smtType + ) + ) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } - private fun handleIsfinite(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { + private fun handleIsfinite( + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel + ): XcfaLabel { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) val type = CSignedInt(null, parseContext) val assign: AssignStmt<*> = Stmts.Assign( TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast(AbstractExprs.Ite( - Or(FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - FpIsNanExpr.of(callStmt.params[1] as Expr)), - type.nullValue, type.unitValue), - type.smtType)) + TypeUtils.cast( + AbstractExprs.Ite( + Or( + FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + FpIsNanExpr.of(callStmt.params[1] as Expr) + ), + type.nullValue, type.unitValue + ), + type.smtType + ) + ) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } - private fun handleIsnormal(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { + private fun handleIsnormal( + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel + ): XcfaLabel { throw UnsupportedOperationException() } - private fun handleFpclassify(builder: XcfaProcedureBuilder, - callStmt: InvokeLabel): XcfaLabel { + private fun handleFpclassify( + builder: XcfaProcedureBuilder, + callStmt: InvokeLabel + ): XcfaLabel { throw UnsupportedOperationException() } @@ -204,7 +281,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { TypeUtils.cast( AbstractExprs.Ite( FpIsNanExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue), type.smtType)) + type.unitValue, type.nullValue + ), type.smtType + ) + ) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } else { @@ -216,10 +296,16 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RNA, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RNA, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -230,10 +316,16 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpSqrtExpr.of(FpRoundingMode.RNE, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpSqrtExpr.of( + FpRoundingMode.RNE, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -245,15 +337,25 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private fun handleFmin(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 3, - "Function is presumed to be binary!") + Preconditions.checkState( + callStmt.params.size == 3, + "Function is presumed to be binary!" + ) val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpMinExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpMinExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -261,15 +363,25 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private fun handleFmax(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState(callStmt.params.size == 3, - "Function is presumed to be binary!") + Preconditions.checkState( + callStmt.params.size == 3, + "Function is presumed to be binary!" + ) val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpMaxExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpMaxExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -280,10 +392,16 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of(FpRoundingMode.RTN, - TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of( + FpRoundingMode.RTN, + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -294,9 +412,15 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, - FpAbsExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType) as Expr)) + val assign = Stmts.Assign( + (expr as RefExpr<*>).decl as VarDecl, + FpAbsExpr.of( + TypeUtils.cast( + CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType + ) as Expr + ) + ) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt index 7b0b3eccfa..b1fb46146a 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt @@ -75,7 +75,8 @@ class HavocPromotionAndRange(val parseContext: ParseContext) : ProcedurePass { // val type = CComplexType.getType(((edge.label.labels[index + 1] as StmtLabel).stmt as AssignStmt<*>).expr, parseContext) val havoc = Havoc(varDecl) newLabels.add( - StmtLabel(havoc, metadata = edge.label.labels[index].metadata)) + StmtLabel(havoc, metadata = edge.label.labels[index].metadata) + ) // newLabels.add(StmtLabel(type.limit(varDecl.ref))) } else if (index == indices[offset] + 1) { offset++ @@ -98,11 +99,15 @@ class HavocPromotionAndRange(val parseContext: ParseContext) : ProcedurePass { for ((index, value) in reversed) { val varDecl = ((value as StmtLabel).stmt as HavocStmt<*>).varDecl if (parseContext.metadata.getMetadataValue(varDecl.ref, "cType").isPresent) { - val type = CComplexType.getType(varDecl.ref, - parseContext) // TODO: what to do when no info is available? + val type = CComplexType.getType( + varDecl.ref, + parseContext + ) // TODO: what to do when no info is available? if (type !is CVoid) { - list.add(index + 1, - StmtLabel(type.limit(varDecl.ref), metadata = value.metadata)) + list.add( + index + 1, + StmtLabel(type.limit(varDecl.ref), metadata = value.metadata) + ) } } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt index 48114fc020..c4656380c5 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt @@ -63,25 +63,34 @@ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { procedure.getVars().forEach { builder.addVar(it) } procedure.getParams().forEach { builder.addVar(it.first) } procedure.getEdges().forEach { - builder.addEdge(it.withSource(checkNotNull(newLocs[it.source])) - .withTarget(checkNotNull(newLocs[it.target]))) + builder.addEdge( + it.withSource(checkNotNull(newLocs[it.source])) + .withTarget(checkNotNull(newLocs[it.target])) + ) } val inStmts: MutableList = ArrayList() val outStmts: MutableList = ArrayList() for ((i, param) in procedure.getParams().withIndex()) { if (param.second != ParamDirection.OUT) { - val stmt = AssignStmt.of(cast(param.first, param.first.type), - cast(CComplexType.getType(param.first.ref, parseContext) - .castTo(invokeLabel.params[i]), param.first.type)) + val stmt = AssignStmt.of( + cast(param.first, param.first.type), + cast( + CComplexType.getType(param.first.ref, parseContext) + .castTo(invokeLabel.params[i]), param.first.type + ) + ) inStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) } if (param.second != ParamDirection.IN) { val varDecl = (invokeLabel.params[i] as RefExpr<*>).decl as VarDecl<*> - val stmt = AssignStmt.of(cast(varDecl, param.first.type), cast( - CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), - param.first.type)) + val stmt = AssignStmt.of( + cast(varDecl, param.first.type), cast( + CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), + param.first.type + ) + ) outStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) } } @@ -92,13 +101,20 @@ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { builder.addEdge(XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts))) if (finalLoc.isPresent) - builder.addEdge(XcfaEdge(checkNotNull(newLocs[finalLoc.get()]), target, - SequenceLabel(outStmts))) + builder.addEdge( + XcfaEdge( + checkNotNull(newLocs[finalLoc.get()]), target, + SequenceLabel(outStmts) + ) + ) if (errorLoc.isPresent) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( - XcfaEdge(checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), - SequenceLabel(listOf()))) + XcfaEdge( + checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), + SequenceLabel(listOf()) + ) + ) } } else { builder.addEdge(e) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt index bc745cfe67..8e37818330 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt @@ -145,8 +145,10 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. * @return Returns the list of removed locations. */ - private fun collapseParallelsAndSnakes(locationsToVisit: List, - strict: Boolean): List { + private fun collapseParallelsAndSnakes( + locationsToVisit: List, + strict: Boolean + ): List { val editedLocationsToVisit = locationsToVisit.toMutableList() val removedLocations = mutableListOf() while (editedLocationsToVisit.isNotEmpty()) { @@ -200,8 +202,10 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * @param locationsToVisit Adds the targets of parallel edges to this list (new parallel edges and snakes * can appear in these locations) */ - private fun collapseParallelEdges(location: XcfaLocation, - locationsToVisit: MutableList) { + private fun collapseParallelEdges( + location: XcfaLocation, + locationsToVisit: MutableList + ) { val edgesByTarget = mutableMapOf>() for (edge in location.outgoingEdges) { val edgesToTarget = edgesByTarget.getOrDefault(edge.target, ArrayList()) @@ -235,8 +239,10 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * added to this list * @param removedLocations The list of removed locations: the collapsed location is added to this list */ - private fun collapsePartOfSnake(location: XcfaLocation, - locationsToVisit: MutableList, removedLocations: MutableList) { + private fun collapsePartOfSnake( + location: XcfaLocation, + locationsToVisit: MutableList, removedLocations: MutableList + ) { if (location.incomingEdges.size == 1 && location.outgoingEdges.size == 1) { val previousLocation = location.incomingEdges.first().source val removed = removeMiddleLocation(location) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt index 07a1b62bb9..638bee932d 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt @@ -45,7 +45,9 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { @@ -54,15 +56,21 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { val mallocVar = builder.parent.malloc if (builder.parent.getVars().none { it.wrappedVar == mallocVar }) { // initial creation builder.parent.addVar( - XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue)) + XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue) + ) val initProc = builder.parent.getInitProcedures().map { it.first } checkState(initProc.size == 1, "Multiple start procedure are not handled well") initProc.forEach { - val initAssign = StmtLabel(Assign(cast(mallocVar, mallocVar.type), - cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type))) + val initAssign = StmtLabel( + Assign( + cast(mallocVar, mallocVar.type), + cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type) + ) + ) val newEdges = it.initLoc.outgoingEdges.map { it.withLabel( - SequenceLabel(listOf(initAssign) + it.label.getFlatLabels(), it.label.metadata)) + SequenceLabel(listOf(initAssign) + it.label.getFlatLabels(), it.label.metadata) + ) } it.initLoc.outgoingEdges.forEach(it::removeEdge) newEdges.forEach(it::addEdge) @@ -70,14 +78,24 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { } val assign1 = AssignStmt.of( cast(mallocVar, ret.type), - cast(Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), - ret.type)) + cast( + Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), + ret.type + ) + ) val assign2 = AssignStmt.of( - cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type)) - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( - listOf( - StmtLabel(assign1, metadata = invokeLabel.metadata), - StmtLabel(assign2, metadata = invokeLabel.metadata))))) + cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type) + ) + builder.addEdge( + XcfaEdge( + it.source, it.target, SequenceLabel( + listOf( + StmtLabel(assign1, metadata = invokeLabel.metadata), + StmtLabel(assign2, metadata = invokeLabel.metadata) + ) + ) + ) + ) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt index ffcda3e8bb..cf88e7314b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt @@ -30,7 +30,9 @@ class NoSideEffectPass(val parseContext: ParseContext) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt index fd7dfcb847..b5b4eb8faf 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt @@ -32,15 +32,23 @@ class NondetFunctionPass : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { val invokeLabel = it.label.labels[0] as InvokeLabel val havoc = HavocStmt.of( - (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*>) - builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( - listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))))) + (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*> + ) + builder.addEdge( + XcfaEdge( + it.source, it.target, SequenceLabel( + listOf(StmtLabel(havoc, metadata = invokeLabel.metadata)) + ) + ) + ) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt index 418090364d..db22bd7169 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt @@ -65,7 +65,9 @@ class NormalizePass : ProcedurePass { is NopLabel -> {} is StmtLabel -> if (!(label.stmt is AssumeStmt && label.stmt.cond.equals( - True()))) collector.forEach { it.add(label) } + True() + )) + ) collector.forEach { it.add(label) } else -> collector.forEach { it.add(label) } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt index 02cb00683e..836a01d635 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt @@ -78,26 +78,28 @@ class CPasses(checkOverflow: Boolean, parseContext: ParseContext, uniqueWarningL ) ) -class ChcPasses(parseContext: ParseContext, uniqueWarningLogger: Logger) : ProcedurePassManager(listOf( - // formatting - NormalizePass(), - DeterministicPass(), - // removing redundant elements - EmptyEdgeRemovalPass(), - UnusedLocRemovalPass(), - // optimizing - SimplifyExprsPass(parseContext), -), listOf( - // trying to inline procedures - InlineProceduresPass(parseContext), - RemoveDeadEnds(), - EliminateSelfLoops(), - // handling remaining function calls - LbePass(parseContext), - NormalizePass(), // needed after lbe, TODO - DeterministicPass(), // needed after lbe, TODO - // Final cleanup - UnusedVarPass(uniqueWarningLogger), -)) +class ChcPasses(parseContext: ParseContext, uniqueWarningLogger: Logger) : ProcedurePassManager( + listOf( + // formatting + NormalizePass(), + DeterministicPass(), + // removing redundant elements + EmptyEdgeRemovalPass(), + UnusedLocRemovalPass(), + // optimizing + SimplifyExprsPass(parseContext), + ), listOf( + // trying to inline procedures + InlineProceduresPass(parseContext), + RemoveDeadEnds(), + EliminateSelfLoops(), + // handling remaining function calls + LbePass(parseContext), + NormalizePass(), // needed after lbe, TODO + DeterministicPass(), // needed after lbe, TODO + // Final cleanup + UnusedVarPass(uniqueWarningLogger), + ) +) class LitmusPasses : ProcedurePassManager() \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt index e06e7ce39f..b216917361 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt @@ -60,8 +60,12 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { val lit = CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt") builder.parent.addVar(XcfaGlobalVar(varDecl, lit)) parseContext.metadata.create(varDecl.ref, "cType", ptrType) - val assign = StmtLabel(AssignStmt.of(cast(varDecl, varDecl.type), - cast(lit, varDecl.type))) + val assign = StmtLabel( + AssignStmt.of( + cast(varDecl, varDecl.type), + cast(lit, varDecl.type) + ) + ) Pair(varDecl, assign) } } @@ -77,8 +81,12 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { val varDecl = Var(it.name + "*", ptrType.smtType) builder.addVar(varDecl) parseContext.metadata.create(varDecl.ref, "cType", ptrType) - val assign = StmtLabel(AssignStmt.of(cast(varDecl, varDecl.type), - cast(CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt"), varDecl.type))) + val assign = StmtLabel( + AssignStmt.of( + cast(varDecl, varDecl.type), + cast(CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt"), varDecl.type) + ) + ) Pair(varDecl, assign) } + globalReferredVars @@ -106,25 +114,37 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } @JvmOverloads - fun XcfaLabel.changeReferredVars(varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null): XcfaLabel = + fun XcfaLabel.changeReferredVars( + varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null + ): XcfaLabel = if (varLut.isNotEmpty()) when (this) { - is InvokeLabel -> InvokeLabel(name, params.map { it.changeReferredVars(varLut, parseContext) }, - metadata = metadata) - - is NondetLabel -> NondetLabel(labels.map { it.changeReferredVars(varLut, parseContext) }.toSet(), - metadata = metadata) - - is SequenceLabel -> SequenceLabel(labels.map { it.changeReferredVars(varLut, parseContext) }, - metadata = metadata) - - is StartLabel -> StartLabel(name, params.map { it.changeReferredVars(varLut, parseContext) }, - pidVar, metadata = metadata) + is InvokeLabel -> InvokeLabel( + name, params.map { it.changeReferredVars(varLut, parseContext) }, + metadata = metadata + ) + + is NondetLabel -> NondetLabel( + labels.map { it.changeReferredVars(varLut, parseContext) }.toSet(), + metadata = metadata + ) + + is SequenceLabel -> SequenceLabel( + labels.map { it.changeReferredVars(varLut, parseContext) }, + metadata = metadata + ) + + is StartLabel -> StartLabel( + name, params.map { it.changeReferredVars(varLut, parseContext) }, + pidVar, metadata = metadata + ) is StmtLabel -> SequenceLabel(stmt.changeReferredVars(varLut, parseContext).map { - StmtLabel(it, metadata = metadata, - choiceType = this.choiceType) + StmtLabel( + it, metadata = metadata, + choiceType = this.choiceType + ) }).let { if (it.labels.size == 1) it.labels[0] else it } else -> this @@ -132,8 +152,10 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { else this @JvmOverloads - fun Stmt.changeReferredVars(varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null): List { + fun Stmt.changeReferredVars( + varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null + ): List { val stmts = when (this) { is AssignStmt<*> -> if (this.varDecl in varLut.keys) { val newVar = varLut[this.varDecl]!!.first @@ -142,20 +164,31 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { Dereference( cast(newVar.ref, newVar.type), cast(CComplexType.getSignedLong(parseContext).nullValue, newVar.type), - this.expr.type), - this.expr.changeReferredVars(varLut, parseContext))) + this.expr.type + ), + this.expr.changeReferredVars(varLut, parseContext) + ) + ) } else { - listOf(AssignStmt.of(cast(this.varDecl, this.varDecl.type), - cast(this.expr.changeReferredVars(varLut, parseContext), this.varDecl.type))) + listOf( + AssignStmt.of( + cast(this.varDecl, this.varDecl.type), + cast(this.expr.changeReferredVars(varLut, parseContext), this.varDecl.type) + ) + ) } is MemoryAssignStmt<*, *, *> -> listOf( - MemoryAssignStmt.create(deref.changeReferredVars(varLut, parseContext) as Dereference<*, *, *>, - expr.changeReferredVars(varLut, parseContext))) + MemoryAssignStmt.create( + deref.changeReferredVars(varLut, parseContext) as Dereference<*, *, *>, + expr.changeReferredVars(varLut, parseContext) + ) + ) is AssumeStmt -> listOf(AssumeStmt.of(cond.changeReferredVars(varLut, parseContext))) is SequenceStmt -> listOf( - SequenceStmt.of(this.stmts.flatMap { it.changeReferredVars(varLut, parseContext) })) + SequenceStmt.of(this.stmts.flatMap { it.changeReferredVars(varLut, parseContext) }) + ) is SkipStmt -> listOf(this) else -> TODO("Not yet implemented ($this)") @@ -170,8 +203,10 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } @JvmOverloads - fun Expr.changeReferredVars(varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null): Expr = + fun Expr.changeReferredVars( + varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null + ): Expr = if (this is RefExpr) { (decl as VarDecl).changeReferredVars(varLut) } else if (this is Reference<*, *> && this.expr is RefExpr<*> && (this.expr as RefExpr<*>).decl in varLut.keys) { @@ -185,10 +220,13 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } fun VarDecl.changeReferredVars( - varLut: Map, Pair, StmtLabel>>): Expr = + varLut: Map, Pair, StmtLabel>> + ): Expr = varLut[this]?.first?.let { - Dereference(cast(it.ref, it.type), cast(CComplexType.getSignedInt(parseContext).nullValue, it.type), - this.type) as Expr + Dereference( + cast(it.ref, it.type), cast(CComplexType.getSignedInt(parseContext).nullValue, it.type), + this.type + ) as Expr } ?: this.ref } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt index 46933ea4e9..c92d5f08ee 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt @@ -40,7 +40,8 @@ class SvCompIntrinsicsPass : ProcedurePass { builder.addEdge(outgoingEdge.withLabel(SequenceLabel(labels))) } for (incomingEdge in ArrayList( - builder.finalLoc.getOrNull()?.incomingEdges ?: listOf())) { + builder.finalLoc.getOrNull()?.incomingEdges ?: listOf() + )) { builder.removeEdge(incomingEdge) val labels = ArrayList((incomingEdge.label as SequenceLabel).labels) labels.add(FenceLabel(setOf("ATOMIC_END"), metadata = incomingEdge.metadata)) @@ -50,18 +51,24 @@ class SvCompIntrinsicsPass : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0]))) { + (edges[0].label as SequenceLabel).labels[0] + )) + ) { builder.removeEdge(edge) val labels: MutableList = ArrayList() edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { val invokeLabel = it.label.labels[0] as InvokeLabel val fence = when (invokeLabel.name) { - "__VERIFIER_atomic_begin" -> FenceLabel(setOf("ATOMIC_BEGIN"), - metadata = invokeLabel.metadata) + "__VERIFIER_atomic_begin" -> FenceLabel( + setOf("ATOMIC_BEGIN"), + metadata = invokeLabel.metadata + ) - "__VERIFIER_atomic_end" -> FenceLabel(setOf("ATOMIC_END"), - metadata = invokeLabel.metadata) + "__VERIFIER_atomic_end" -> FenceLabel( + setOf("ATOMIC_END"), + metadata = invokeLabel.metadata + ) else -> invokeLabel } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt index 1f88251fab..8825144189 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt @@ -64,7 +64,8 @@ class UnusedVarPass(private val uniqueWarningLogger: Logger) : ProcedurePass { if (!varsAndParams.containsAll(usedVars)) { uniqueWarningLogger.write(Logger.Level.INFO, "WARNING: There are some used variables not present as declarations: " + - "${usedVars.filter { it !in varsAndParams }}\n") + "${usedVars.filter { it !in varsAndParams }}\n" + ) } builder.getVars().filter { it !in usedVars }.forEach { builder.removeVar(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt index cb5c74b8cb..55ae7e42e0 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt @@ -76,27 +76,41 @@ fun Stmt.flatten(): List { fun XcfaLabel.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): XcfaLabel = if (varLut.isNotEmpty()) when (this) { - is InvokeLabel -> InvokeLabel(name, params.map { it.changeVars(varLut, parseContext) }, - metadata = metadata) + is InvokeLabel -> InvokeLabel( + name, params.map { it.changeVars(varLut, parseContext) }, + metadata = metadata + ) is JoinLabel -> JoinLabel(pidVar.changeVars(varLut), metadata = metadata) - is NondetLabel -> NondetLabel(labels.map { it.changeVars(varLut, parseContext) }.toSet(), - metadata = metadata) - - is ReadLabel -> ReadLabel(local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata) - - is SequenceLabel -> SequenceLabel(labels.map { it.changeVars(varLut, parseContext) }, - metadata = metadata) - - is StartLabel -> StartLabel(name, params.map { it.changeVars(varLut, parseContext) }, - pidVar.changeVars(varLut), metadata = metadata) - - is StmtLabel -> StmtLabel(stmt.changeVars(varLut, parseContext), metadata = metadata, - choiceType = this.choiceType) - - is WriteLabel -> WriteLabel(local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata) + is NondetLabel -> NondetLabel( + labels.map { it.changeVars(varLut, parseContext) }.toSet(), + metadata = metadata + ) + + is ReadLabel -> ReadLabel( + local.changeVars(varLut), global.changeVars(varLut), labels, + metadata = metadata + ) + + is SequenceLabel -> SequenceLabel( + labels.map { it.changeVars(varLut, parseContext) }, + metadata = metadata + ) + + is StartLabel -> StartLabel( + name, params.map { it.changeVars(varLut, parseContext) }, + pidVar.changeVars(varLut), metadata = metadata + ) + + is StmtLabel -> StmtLabel( + stmt.changeVars(varLut, parseContext), metadata = metadata, + choiceType = this.choiceType + ) + + is WriteLabel -> WriteLabel( + local.changeVars(varLut), global.changeVars(varLut), labels, + metadata = metadata + ) is ReturnLabel -> ReturnLabel(enclosedLabel.changeVars(varLut)) @@ -107,11 +121,15 @@ fun XcfaLabel.changeVars(varLut: Map, VarDecl<*>>, parseContext: Par @JvmOverloads fun Stmt.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): Stmt { val stmt = when (this) { - is AssignStmt<*> -> AssignStmt.of(cast(varDecl.changeVars(varLut), varDecl.type), - cast(expr.changeVars(varLut, parseContext), varDecl.type)) - - is MemoryAssignStmt<*, *, *> -> MemoryAssignStmt.create(deref.changeVars(varLut) as Dereference, - expr.changeVars(varLut)) + is AssignStmt<*> -> AssignStmt.of( + cast(varDecl.changeVars(varLut), varDecl.type), + cast(expr.changeVars(varLut, parseContext), varDecl.type) + ) + + is MemoryAssignStmt<*, *, *> -> MemoryAssignStmt.create( + deref.changeVars(varLut) as Dereference, + expr.changeVars(varLut) + ) is HavocStmt<*> -> HavocStmt.of(varDecl.changeVars(varLut)) is AssumeStmt -> AssumeStmt.of(cond.changeVars(varLut, parseContext)) diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index 65a89e0533..056ed4d9f0 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -46,11 +46,14 @@ class GsonTest { private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean): Gson { val gsonBuilder = GsonBuilder() lateinit var gson: Gson - gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter)) + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLocation::class.java, + StringTypeAdapter(xcfaLocationAdapter) + ) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope)) + VarDeclAdapter({ gson }, scope, env, !newScope) + ) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -60,7 +63,8 @@ class GsonTest { gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson })) + XcfaLabelAdapter(scope, env, { gson }) + ) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) @@ -112,8 +116,10 @@ class GsonTest { val env = Env() val gson = getGson(symbolTable, env, true) - assertEquals(parseContext.metadata.lookupKeyValue, - gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue) + assertEquals( + parseContext.metadata.lookupKeyValue, + gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue + ) } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt index 570ab2b126..e1084b1fab 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt @@ -45,7 +45,8 @@ class PassTests { global: VarContext.() -> Unit, input: XcfaProcedureBuilderContext.() -> Unit, output: (XcfaProcedureBuilderContext.() -> Unit)?, - val passes: List) : Arguments { + val passes: List + ) : Arguments { private val builder = XcfaBuilder("").also { it.global(global) } private val inputBuilder = builder.procedure("", input).builder @@ -332,11 +333,13 @@ class PassTests { } (init to final) { "y".assign( - "(ite (isinfinite x) #b00000000000000000000000000000001 #b00000000000000000000000000000000)") + "(ite (isinfinite x) #b00000000000000000000000000000001 #b00000000000000000000000000000000)" + ) } (init to final) { "y".assign( - "(ite (or (isinfinite x) (fpisnan x)) #b00000000000000000000000000000000 #b00000000000000000000000000000001)") + "(ite (or (isinfinite x) (fpisnan x)) #b00000000000000000000000000000000 #b00000000000000000000000000000001)" + ) } }, ), @@ -372,7 +375,8 @@ class PassTests { "y".assign("x").also { parseContext.metadata.create( ((it.labels.last() as StmtLabel).stmt as AssignStmt<*>).varDecl.ref, "cType", - CSignedInt(null, parseContext)) + CSignedInt(null, parseContext) + ) } } }, @@ -531,8 +535,10 @@ class PassTests { @ParameterizedTest @MethodSource("getData") - fun testPass(input: XcfaProcedureBuilder, output: XcfaProcedureBuilder?, - passes: List) { + fun testPass( + input: XcfaProcedureBuilder, output: XcfaProcedureBuilder?, + passes: List + ) { println("Trying to run $passes on input...") val actualOutput = passes.fold(input) { acc, procedurePass -> procedurePass.run(acc) } .build(dummyXcfa) @@ -562,10 +568,15 @@ class PassTests { @Test fun testInline() { val xcfaSource = xcfa("example") { - procedure("main", ProcedurePassManager(listOf( - NormalizePass(), - DeterministicPass(), - InlineProceduresPass(parseContext)))) { + procedure( + "main", ProcedurePassManager( + listOf( + NormalizePass(), + DeterministicPass(), + InlineProceduresPass(parseContext) + ) + ) + ) { (init to final) { "proc1"() } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt index 77c48dc44e..f2f25a473a 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt @@ -39,25 +39,37 @@ class UtilsTest { @JvmStatic fun getLabels(): List = listOf( - Arguments.of(InvokeLabel("", listOf(x.ref, y.ref), EmptyMetaData), - InvokeLabel("", listOf(xPrime.ref, y.ref), EmptyMetaData)), + Arguments.of( + InvokeLabel("", listOf(x.ref, y.ref), EmptyMetaData), + InvokeLabel("", listOf(xPrime.ref, y.ref), EmptyMetaData) + ), Arguments.of(JoinLabel(x, EmptyMetaData), JoinLabel(xPrime, EmptyMetaData)), Arguments.of(NondetLabel(setOf(NopLabel), EmptyMetaData), NondetLabel(setOf(NopLabel), EmptyMetaData)), - Arguments.of(SequenceLabel(listOf(NopLabel), EmptyMetaData), - SequenceLabel(listOf(NopLabel), EmptyMetaData)), + Arguments.of( + SequenceLabel(listOf(NopLabel), EmptyMetaData), + SequenceLabel(listOf(NopLabel), EmptyMetaData) + ), Arguments.of(ReadLabel(x, y, setOf(), EmptyMetaData), ReadLabel(xPrime, y, setOf(), EmptyMetaData)), Arguments.of(WriteLabel(x, y, setOf(), EmptyMetaData), WriteLabel(xPrime, y, setOf(), EmptyMetaData)), Arguments.of(FenceLabel(setOf(), EmptyMetaData), FenceLabel(setOf(), EmptyMetaData)), - Arguments.of(StartLabel("", listOf(x.ref), y, EmptyMetaData), - StartLabel("", listOf(xPrime.ref), y, EmptyMetaData)), + Arguments.of( + StartLabel("", listOf(x.ref), y, EmptyMetaData), + StartLabel("", listOf(xPrime.ref), y, EmptyMetaData) + ), Arguments.of(ReturnLabel(JoinLabel(x, EmptyMetaData)), ReturnLabel(JoinLabel(xPrime, EmptyMetaData))), - Arguments.of(StmtLabel(Assign(x, y.ref)), - StmtLabel(Assign(xPrime, y.ref))), - Arguments.of(StmtLabel(Havoc(x)), - StmtLabel(Havoc(xPrime))), - Arguments.of(StmtLabel(Assume(Eq(x.ref, y.ref))), - StmtLabel(Assume(Eq(xPrime.ref, y.ref)))), + Arguments.of( + StmtLabel(Assign(x, y.ref)), + StmtLabel(Assign(xPrime, y.ref)) + ), + Arguments.of( + StmtLabel(Havoc(x)), + StmtLabel(Havoc(xPrime)) + ), + Arguments.of( + StmtLabel(Assume(Eq(x.ref, y.ref))), + StmtLabel(Assume(Eq(xPrime.ref, y.ref))) + ), Arguments.of(StmtLabel(Skip()), StmtLabel(Skip())), ) } diff --git a/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt b/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt index 487a206379..63d339aeb7 100644 --- a/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt +++ b/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt @@ -139,27 +139,47 @@ class TestChcUtils { val init = Relation("init", i2i, i2i, i2i, i2i, Int()) // br, co, rf, com - val T0 = Relation("T0", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0G = Relation("T0_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0C = Relation("T0_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0CF = Relation("T0_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0F = Relation("T0_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - - val T1 = Relation("T1", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1G = Relation("T1_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1C = Relation("T1_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1CF = Relation("T1_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1F = Relation("T1_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0 = Relation( + "T0", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0G = Relation( + "T0_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0C = Relation( + "T0_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0CF = Relation( + "T0_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0F = Relation( + "T0_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + + val T1 = Relation( + "T1", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1G = Relation( + "T1_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1C = Relation( + "T1_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1CF = Relation( + "T1_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1F = Relation( + "T1_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt val W = Relation("W", i2i, i2i, i2i, i2i, Int(), Int(), Int()) // br, co, rf, com, eid, vid, val @@ -440,23 +460,39 @@ class TestChcUtils { val init = Relation("init", i2i, i2i, i2i, i2i, Int()) // br, co, rf, com - val T0 = Relation("T0", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0G = Relation("T0_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0C = Relation("T0_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0F = Relation("T0_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - - val T1 = Relation("T1", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1G = Relation("T1_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1C = Relation("T1_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1F = Relation("T1_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0 = Relation( + "T0", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0G = Relation( + "T0_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0C = Relation( + "T0_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0F = Relation( + "T0_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + + val T1 = Relation( + "T1", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1G = Relation( + "T1_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1C = Relation( + "T1_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1F = Relation( + "T1_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool() + ) // br, co, rf, com, eid, turn, flag0, flag1, cnt val W = Relation("W", i2i, i2i, i2i, i2i, Int(), Int(), Bool()) // br, co, rf, com, eid, vid, val diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt index 4e4a63908b..8d733b0bfe 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt @@ -55,7 +55,8 @@ fun XSTS.toRelations(): List { is EnumLitExpr -> { val value = enumValueLut.computeIfAbsent(this.type) { LinkedHashMap() }.computeIfAbsent( - this.value) { cnt++ } + this.value + ) { cnt++ } return IntLitExpr.of(BigInteger.valueOf(value.toLong())) } diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt index a78b5bb70c..06eead3068 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt @@ -29,8 +29,10 @@ import hu.bme.mit.theta.xsts.XSTS import kotlin.random.Random @JvmOverloads -fun generateXsts(seed: Int, numCtrl: Int = 1, numClock: Int = 1, numOther: Int = 3, - requireAllVarsWritten: Boolean = false): XSTS { +fun generateXsts( + seed: Int, numCtrl: Int = 1, numClock: Int = 1, numOther: Int = 3, + requireAllVarsWritten: Boolean = false +): XSTS { val writtenVars = object : StmtVisitor>, Set>> { override fun visit(stmt: SkipStmt?, param: Set>): Set> { return param @@ -77,7 +79,8 @@ fun generateXsts(seed: Int, numCtrl: Int = 1, numClock: Int = 1, numOther: Int = } override fun visit( - stmt: MemoryAssignStmt?, param: Set>?): Set> { + stmt: MemoryAssignStmt?, param: Set>? + ): Set> { TODO("Not yet implemented") } @@ -178,17 +181,21 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { } fun randomSeq(currDepth: Int, maxDepth: Int): Stmt { - return Stmts.SequenceStmt(listOf( - randomIntermediate(currDepth + 1, maxDepth), - randomIntermediate(currDepth + 1, maxDepth) - )) + return Stmts.SequenceStmt( + listOf( + randomIntermediate(currDepth + 1, maxDepth), + randomIntermediate(currDepth + 1, maxDepth) + ) + ) } fun randomNonDet(currDepth: Int, maxDepth: Int): Stmt { - return Stmts.NonDetStmt(listOf( - randomIntermediate(currDepth + 1, maxDepth), - randomIntermediate(currDepth + 1, maxDepth) - )) + return Stmts.NonDetStmt( + listOf( + randomIntermediate(currDepth + 1, maxDepth), + randomIntermediate(currDepth + 1, maxDepth) + ) + ) } @@ -196,7 +203,8 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { var expr: Expr do expr = randomBoolExpr(0) while (ExprUtils.getVars(expr).isEmpty()) - return IfStmt.of(expr, + return IfStmt.of( + expr, randomIntermediate(currDepth + 1, maxDepth), randomIntermediate(currDepth + 1, maxDepth) ) @@ -222,7 +230,8 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { { BoolExprs.Or( randomBoolExpr(currDepth + 1), - randomBoolExpr(currDepth + 1)) + randomBoolExpr(currDepth + 1) + ) }, { BoolExprs.Imply(randomBoolExpr(currDepth + 1), randomBoolExpr(currDepth + 1)) }, { BoolExprs.Iff(randomBoolExpr(currDepth + 1), randomBoolExpr(currDepth + 1)) }, @@ -296,7 +305,8 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { } fun randomAssume() = (listOf(this::randomDataAssume) + (if (clockVars.isEmpty()) listOf() else listOf( - this::randomClockConstraint))).random(random)() + this::randomClockConstraint + ))).random(random)() fun randomDataAssume(): Stmt { var expr: Expr @@ -323,13 +333,15 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { ).random()() val compareTo = IntExprs.Int(random.nextInt(10)) - return Stmts.Assume(listOf( - { IntExprs.Leq(c, compareTo) }, - { IntExprs.Lt(c, compareTo) }, - { IntExprs.Geq(c, compareTo) }, - { IntExprs.Gt(c, compareTo) }, - { IntExprs.Eq(c, compareTo) }, - ).random(random)()) + return Stmts.Assume( + listOf( + { IntExprs.Leq(c, compareTo) }, + { IntExprs.Lt(c, compareTo) }, + { IntExprs.Geq(c, compareTo) }, + { IntExprs.Gt(c, compareTo) }, + { IntExprs.Eq(c, compareTo) }, + ).random(random)() + ) } fun randomHavoc(): Stmt { diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt index 833a03799a..e3d98a6c68 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt @@ -100,7 +100,8 @@ object XstsSerializer : StmtVisitor { } override fun visit( - stmt: MemoryAssignStmt?, param: Void?): String { + stmt: MemoryAssignStmt?, param: Void? + ): String { TODO("Not yet implemented") } diff --git a/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt b/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt index c38b044ec5..7c9fd82f2f 100644 --- a/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt +++ b/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt @@ -25,7 +25,9 @@ fun XSTS.copyWithReplacingVars(variableMapping: Map>): XSTS { val matchingCtrlVarNames = ctrlVars.filter { variableMapping.containsKey(it.name) }.map { it.name } val newCtrlVars = ctrlVars.filter { it.name !in variableMapping } .toSet() + variableMapping.filter { it.key in matchingCtrlVarNames }.values.toSet() - return XSTS(newCtrlVars, init.changeVars(variableMapping) as NonDetStmt, + return XSTS( + newCtrlVars, init.changeVars(variableMapping) as NonDetStmt, tran.changeVars(variableMapping) as NonDetStmt, env.changeVars(variableMapping) as NonDetStmt, - initFormula.changeVars(variableMapping), prop.changeVars(variableMapping)) + initFormula.changeVars(variableMapping), prop.changeVars(variableMapping) + ) } \ No newline at end of file From e37b32302b2cb72893e26b52bc63d305e999a98f Mon Sep 17 00:00:00 2001 From: "ThetaBotMaintainer[bot]" <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> Date: Fri, 18 Oct 2024 18:24:37 +0000 Subject: [PATCH 17/40] Reformatted code --- .../bounded/BoundedCheckerBuilder.kt | 6 +++-- .../hu/bme/mit/theta/analysis/ptr/PtrUtils.kt | 3 ++- .../mit/theta/grammar/gson/StateAdapters.kt | 3 ++- .../hu/bme/mit/theta/grammar/gson/TestGson.kt | 18 +++++++++----- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 3 ++- .../bme/mit/theta/xcfa/cli/utils/GsonUtils.kt | 9 ++++--- .../xcfa/passes/FetchExecuteWriteback.kt | 24 ++++++++++++------- .../mit/theta/xcfa/passes/UnusedVarPass.kt | 3 ++- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 6 +++-- 9 files changed, 49 insertions(+), 26 deletions(-) diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt index b54dc029aa..03de89fb27 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt @@ -34,7 +34,8 @@ fun buildBMC( bmcEnabled: () -> Boolean = { true }, lfPathOnly: () -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, null, + return BoundedChecker( + monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, null, { false }, valToState, biValToAction, logger ) } @@ -71,7 +72,8 @@ fun buildIMC( lfPathOnly: () -> Boolean = { true }, imcEnabled: (Int) -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, itpSolver, imcEnabled, null, + return BoundedChecker( + monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, itpSolver, imcEnabled, null, { false }, valToState, biValToAction, logger ) } \ No newline at end of file diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt index d1748f2526..e051625334 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt @@ -149,7 +149,8 @@ fun Expr.uniqueDereferences( Pair(ret, retDeref) } else { val ret = ArrayList() - Pair(ret, + Pair( + ret, this.withOps(this.ops.map { it.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second }) ) } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt index 1675ec639a..30031d82e0 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt @@ -89,7 +89,8 @@ class PredStateAdapter(val gsonSupplier: () -> Gson, val scope: Scope, val env: check(reader.nextName() == "bottom") if (reader.nextBoolean()) ret = PredState.bottom() check(reader.nextName() == "preds") - val preds = gson.fromJson>>(reader, + val preds = gson.fromJson>>( + reader, object : TypeToken>>() {}.type ) if (ret == null) ret = PredState.of(preds) diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt index 026a4626ee..c4d39653a0 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt @@ -101,13 +101,16 @@ class TestGson { private fun getExplBuilder(gsonSuppl: () -> Gson): GsonBuilder { val gsonBuilder = GsonBuilder() - gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + ARG::class.java, ArgAdapter(gsonSuppl, { ExplOrd.getInstance() }, { explArgAdapterHelper() }) ) - gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + Trace::class.java, TraceAdapter(gsonSuppl, { ExplState::class.java }, SimpleStmtAction::class.java) ) - gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + SafetyResult::class.java, SafetyResultAdapter(gsonSuppl, { explArgHelper() }, { explTraceHelper() }) ) @@ -117,13 +120,16 @@ class TestGson { private fun getPredBuilder(gsonSuppl: () -> Gson): GsonBuilder { val gsonBuilder = GsonBuilder() - gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + ARG::class.java, ArgAdapter(gsonSuppl, { PartialOrd { a, b -> true } }, { predArgAdapterHelper() }) ) - gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + Trace::class.java, TraceAdapter(gsonSuppl, { PredState::class.java }, SimpleStmtAction::class.java) ) - gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + SafetyResult::class.java, SafetyResultAdapter(gsonSuppl, { predArgHelper() }, { predTraceHelper() }) ) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index afb0bb997a..e835aaf239 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -181,7 +181,8 @@ fun frontend(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger): Tr ) logger.write(RESULT, "ParsingResult Success\n") - logger.write(RESULT, + logger.write( + RESULT, "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n" ) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt index 72ddc379d7..8ef9ed0318 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt @@ -106,7 +106,8 @@ private fun getGson( StringTypeAdapter(xcfaLocationAdapter) ) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + VarDecl::class.java, VarDeclAdapter({ gson }, scope, env, !newScope) ) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, @@ -118,10 +119,12 @@ private fun getGson( gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) - gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + PredState::class.java, PredStateAdapter({ gson }, scope, env) ) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLabel::class.java, XcfaLabelAdapter(scope, env, { gson }) ) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt index 89c11f3a78..894f89ccb2 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt @@ -73,9 +73,11 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { is InvokeLabel -> { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { - StmtLabel(Assign(cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) - ) + StmtLabel( + Assign( + cast(it.value, it.value.type), + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) + ) ) } + InvokeLabel( this.name, this.params.map { it.replaceDerefs(lut) }, metadata, @@ -87,9 +89,11 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { is StartLabel -> { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { - StmtLabel(Assign(cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) - ) + StmtLabel( + Assign( + cast(it.value, it.value.type), + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) + ) ) } + StartLabel(name, params.map { it.replaceDerefs(lut) }, pidVar, metadata, tempLookup), metadata) } @@ -129,9 +133,11 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { val ret = ArrayList() val accessType = dereferencesWithAccessTypes.filter { dereferences.contains(it.first) } for (dereference in accessType.filter { it.second.isRead }.map { it.first }) { - ret.add(Assign(cast(lut[dereference]!!, dereference.type), - cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type) - ) + ret.add( + Assign( + cast(lut[dereference]!!, dereference.type), + cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type) + ) ) } ret.add(stmt) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt index 8825144189..c8ed0b0c27 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt @@ -62,7 +62,8 @@ class UnusedVarPass(private val uniqueWarningLogger: Logger) : ProcedurePass { val allVars = Sets.union(builder.getVars(), builder.parent.getVars().map { it.wrappedVar }.toSet()) val varsAndParams = Sets.union(allVars, builder.getParams().map { it.first }.toSet()) if (!varsAndParams.containsAll(usedVars)) { - uniqueWarningLogger.write(Logger.Level.INFO, + uniqueWarningLogger.write( + Logger.Level.INFO, "WARNING: There are some used variables not present as declarations: " + "${usedVars.filter { it !in varsAndParams }}\n" ) diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index 056ed4d9f0..b7b48eb5a4 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -51,7 +51,8 @@ class GsonTest { StringTypeAdapter(xcfaLocationAdapter) ) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + VarDecl::class.java, VarDeclAdapter({ gson }, scope, env, !newScope) ) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, @@ -62,7 +63,8 @@ class GsonTest { StringTypeAdapter { TypeWrapper(it).instantiate() }) gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) - gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, + gsonBuilder.registerTypeHierarchyAdapter( + XcfaLabel::class.java, XcfaLabelAdapter(scope, env, { gson }) ) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) From ad26bfb24720ea453c5ff4c2bab1965d38bfb188 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Fri, 18 Oct 2024 22:44:41 +0200 Subject: [PATCH 18/40] Fixed pre- and post statements of ternary operators --- .../grammar/function/FunctionVisitor.java | 79 ++++++++++++++++--- 1 file changed, 68 insertions(+), 11 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index 427034fb2c..83adb2c0ed 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -465,6 +465,18 @@ public CStatement visitBodyDeclaration(CParser.BodyDeclarationContext ctx) { CAssignment cAssignment = new CAssignment(declaration.getVarDecls().get(0).getRef(), declaration.getInitExpr(), "=", parseContext); recordMetadata(ctx, cAssignment); compound.getcStatementList().add(cAssignment); + if (declaration.getInitExpr() instanceof CCompound compoundInitExpr) { + final var preCompound = new CCompound(parseContext); + final var postCompound = new CCompound(parseContext); + final var preStatements = collectPreStatements(compoundInitExpr); + preCompound.getcStatementList().addAll(preStatements); + final var postStatements = collectPostStatements(compoundInitExpr); + postCompound.getcStatementList().addAll(postStatements); + resetPreStatements(compoundInitExpr); + resetPostStatements(compoundInitExpr); + compound.setPreStatements(preCompound); + compound.setPostStatements(postCompound); + } } } } else { @@ -509,7 +521,16 @@ public CStatement visitAssignmentExpressionAssignmentExpression(CParser.Assignme CCompound preStatements = new CCompound(parseContext); CCompound postStatements = new CCompound(parseContext); Expr ret = ctx.unaryExpression().accept(expressionVisitor); - CAssignment cAssignment = new CAssignment(ret, ctx.assignmentExpression().accept(this), ctx.assignmentOperator().getText(), parseContext); + CStatement rhs = ctx.assignmentExpression().accept(this); + if (rhs instanceof CCompound compoundInitExpr) { + final var preStatementList = collectPreStatements(compoundInitExpr); + preStatements.getcStatementList().addAll(preStatementList); + final var postStatementList = collectPostStatements(compoundInitExpr); + postStatements.getcStatementList().addAll(postStatementList); + resetPreStatements(compoundInitExpr); + resetPostStatements(compoundInitExpr); + } + CAssignment cAssignment = new CAssignment(ret, rhs, ctx.assignmentOperator().getText(), parseContext); compound.getcStatementList().add(cAssignment); preStatements.getcStatementList().addAll(expressionVisitor.getPreStatements()); compound.setPreStatements(preStatements); @@ -525,6 +546,34 @@ public CStatement visitAssignmentExpressionConditionalExpression(CParser.Assignm return ctx.conditionalExpression().accept(this); } + private void resetPreStatements(CStatement statement) { + if (statement instanceof CCompound compound) { + compound.setPreStatements(null); + for (CStatement cStatement : compound.getcStatementList()) { + resetPreStatements(cStatement); + } + } + } + + private void resetPostStatements(CStatement statement) { + if (statement instanceof CCompound compound) { + compound.setPostStatements(null); + for (CStatement cStatement : compound.getcStatementList()) { + resetPostStatements(cStatement); + } + } + } + + private List getStatementList(CStatement statement) { + if (statement instanceof CCompound compound) { + return compound.getcStatementList(); + } else if (statement != null) { + return List.of(statement); + } else { + return List.of(); + } + } + /* This collects the following: - the current compound's pre-statement @@ -536,7 +585,7 @@ private List collectPreStatements(CStatement cStatement) { return Stream.concat( Stream.concat( collectPreStatements(cStatement.getPreStatements()).stream(), - Stream.of(cStatement.getPreStatements())), + getStatementList(cStatement.getPreStatements()).stream()), ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPreStatements(cStatement1).stream()) ).toList(); } else return List.of(); @@ -553,8 +602,8 @@ private List collectPostStatements(CStatement cStatement) { return Stream.concat( ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPostStatements(cStatement1).stream()), Stream.concat( - Stream.of(cStatement.getPreStatements()), - collectPostStatements(cStatement.getPreStatements()).stream()) + getStatementList(cStatement.getPostStatements()).stream(), + collectPostStatements(cStatement.getPostStatements()).stream()) ).toList(); } else return List.of(); } @@ -586,26 +635,34 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex CCompound ifTruePre = new CCompound(parseContext); - ifTruePre.getcStatementList().addAll(collectPreStatements(ifTrue)); + List ifTruePreList = collectPreStatements(ifTrue); + ifTruePre.getcStatementList().addAll(ifTruePreList); ifTruePre.setPostStatements(new CCompound(parseContext)); ifTruePre.setPreStatements(new CCompound(parseContext)); CCompound ifFalsePre = new CCompound(parseContext); - ifFalsePre.getcStatementList().addAll(collectPreStatements(ifFalse)); + List ifFalsePreList = collectPreStatements(ifFalse); + ifFalsePre.getcStatementList().addAll(ifFalsePreList); ifFalsePre.setPostStatements(new CCompound(parseContext)); ifFalsePre.setPreStatements(new CCompound(parseContext)); CCompound ifTruePost = new CCompound(parseContext); - ifTruePost.getcStatementList().addAll(collectPostStatements(ifTrue)); + List ifTruePostList = collectPostStatements(ifTrue); + ifTruePost.getcStatementList().addAll(ifTruePostList); ifTruePost.setPostStatements(new CCompound(parseContext)); ifTruePost.setPreStatements(new CCompound(parseContext)); CCompound ifFalsePost = new CCompound(parseContext); - ifFalsePost.getcStatementList().addAll(collectPostStatements(ifFalse)); + List ifFalsePostList = collectPostStatements(ifFalse); + ifFalsePost.getcStatementList().addAll(ifFalsePostList); ifFalsePost.setPostStatements(new CCompound(parseContext)); ifFalsePost.setPreStatements(new CCompound(parseContext)); - preStatements.getcStatementList().add(new CIf(guardCompound, ifTruePre, ifFalsePre, parseContext)); - postStatements.getcStatementList().add(new CIf(guardCompound, ifTruePost, ifFalsePost, parseContext)); + if (!ifTruePreList.isEmpty() || !ifFalsePreList.isEmpty()) { + preStatements.getcStatementList().add(new CIf(guardCompound, ifTruePre, ifFalsePre, parseContext)); + } + if (!ifTruePostList.isEmpty() || !ifFalsePostList.isEmpty()) { + postStatements.getcStatementList().add(new CIf(guardCompound, ifTruePost, ifFalsePost, parseContext)); + } CComplexType smallestCommonType = CComplexType.getSmallestCommonType(List.of(CComplexType.getType(lhs, parseContext), CComplexType.getType(rhs, parseContext)), parseContext); IteExpr ite = Ite( @@ -621,7 +678,7 @@ public CStatement visitConditionalExpression(CParser.ConditionalExpressionContex CExpr cexpr = new CExpr(iteExpr, parseContext); compound.getcStatementList().add(cexpr); - preStatements.getcStatementList().addAll(expressionVisitor.getPreStatements()); + preStatements.getcStatementList().addAll(0, expressionVisitor.getPreStatements()); compound.setPreStatements(preStatements); recordMetadata(ctx, compound); compound.setPostStatements(postStatements); From 8749d326dfa13f155135295f5bd726e774252ec5 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 10:17:28 +0200 Subject: [PATCH 19/40] Fixed pre- and post statements of nested ternary operators --- .../transformation/grammar/function/FunctionVisitor.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java index 83adb2c0ed..4f9041fa08 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/transformation/grammar/function/FunctionVisitor.java @@ -566,7 +566,7 @@ private void resetPostStatements(CStatement statement) { private List getStatementList(CStatement statement) { if (statement instanceof CCompound compound) { - return compound.getcStatementList(); + return compound.getcStatementList().stream().flatMap(i -> getStatementList(i).stream()).toList(); } else if (statement != null) { return List.of(statement); } else { @@ -587,7 +587,7 @@ private List collectPreStatements(CStatement cStatement) { collectPreStatements(cStatement.getPreStatements()).stream(), getStatementList(cStatement.getPreStatements()).stream()), ((CCompound) cStatement).getcStatementList().stream().flatMap(cStatement1 -> collectPreStatements(cStatement1).stream()) - ).toList(); + ).filter(i -> !(i instanceof CExpr)).toList(); } else return List.of(); } @@ -604,7 +604,7 @@ private List collectPostStatements(CStatement cStatement) { Stream.concat( getStatementList(cStatement.getPostStatements()).stream(), collectPostStatements(cStatement.getPostStatements()).stream()) - ).toList(); + ).filter(i -> !(i instanceof CExpr)).toList(); } else return List.of(); } From fe0d7449e5f8c777226aea32b8e3b475fe243f39 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 20 Oct 2024 19:34:00 +0200 Subject: [PATCH 20/40] Added thorn creation to action --- .github/workflows/linux-build-test-deploy.yml | 5 +++++ build.gradle.kts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/linux-build-test-deploy.yml b/.github/workflows/linux-build-test-deploy.yml index 80040fd800..6d5b209e16 100644 --- a/.github/workflows/linux-build-test-deploy.yml +++ b/.github/workflows/linux-build-test-deploy.yml @@ -105,6 +105,11 @@ jobs: with: name: "EmergenTheta" inputflag: "--algorithm EMERGENT" + - name: Create thorn.zip + uses: ./.github/actions/build-archive + with: + name: "Thorn" + inputflag: "--algorithm HORN" javadoc: diff --git a/build.gradle.kts b/build.gradle.kts index 20a45bf13f..108baa86d1 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -28,7 +28,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.6.0" + version = "6.6.1" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } From 9709d84c0d5b06160a3b0858762843d3a4350474 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 20 Oct 2024 20:19:16 +0200 Subject: [PATCH 21/40] Added support for --svcomp shorthand --- .../main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt index f5257effa4..a8652b79ea 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt @@ -41,6 +41,9 @@ class XcfaCli(private val args: Array) { @Parameter(names = ["--help", "-h"], help = true) private var help = false + @Parameter(names = ["--svcomp"]) + private var svcomp = false + @Parameter var remainingFlags: MutableList = ArrayList() @@ -55,6 +58,17 @@ class XcfaCli(private val args: Array) { } else { config = XcfaConfig() } + if (svcomp) { + remainingFlags.addAll( + listOf( + "--enable-output", + "--disable-xcfa-serialization", + "--disable-chc-serialization", + "--disable-c-serialization", + "--only-svcomp-witness" + ) + ) + } while (remainingFlags.isNotEmpty()) { val nextArgs = remainingFlags.toTypedArray() remainingFlags.clear() From aca85baf4991e2d085a30c3c8734cbc0284d4655 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sun, 20 Oct 2024 20:25:40 +0200 Subject: [PATCH 22/40] Disabling arg serialization if --svcomp is given --- .../xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt index a8652b79ea..54e2c0d406 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/XcfaCli.kt @@ -63,6 +63,7 @@ class XcfaCli(private val args: Array) { listOf( "--enable-output", "--disable-xcfa-serialization", + "--disable-arg-generation", "--disable-chc-serialization", "--disable-c-serialization", "--only-svcomp-witness" From 7cece7f07c8533b4ad97c7c57e7efc0d609d2d79 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 12:03:08 +0200 Subject: [PATCH 23/40] Added spotless for java --- buildSrc/build.gradle.kts | 2 ++ buildSrc/gradle.properties | 3 ++- .../src/main/kotlin/java-common.gradle.kts | 25 +++++++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 5b1c79903a..f731f11685 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -30,6 +30,7 @@ apply(from = rootDir.resolve("../gradle/shared-with-buildSrc/mirrors.gradle.kts" val kotlinVersion: String by project val shadowVersion: String by project +val spotlessVersion: String by project // https://github.com/gradle/kotlin-dsl/issues/430#issuecomment-414768887 fun gradlePlugin(id: String, version: String): String = "$id:$id.gradle.plugin:$version" @@ -38,6 +39,7 @@ dependencies { compileOnly(gradleKotlinDsl()) implementation(kotlin("gradle-plugin", kotlinVersion)) implementation(gradlePlugin("com.github.johnrengelman.shadow", shadowVersion)) + implementation(gradlePlugin("com.diffplug.spotless", spotlessVersion)) } // Force the embeddable Kotlin compiler version to be the selected kotlinVersion. diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index e9c71bc25e..48f1a02d7d 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -39,4 +39,5 @@ deltaCollectionsVersion=0.0.1 gsonVersion=2.9.1 javasmtVersion=4.1.1 sosylabVersion=0.3000-569-g89796f98 -cliktVersion=4.4.0 \ No newline at end of file +cliktVersion=4.4.0 +spotlessVersion=7.0.0.BETA3 \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/java-common.gradle.kts b/buildSrc/src/main/kotlin/java-common.gradle.kts index 96ffbd8ec6..4c1438291f 100644 --- a/buildSrc/src/main/kotlin/java-common.gradle.kts +++ b/buildSrc/src/main/kotlin/java-common.gradle.kts @@ -17,6 +17,7 @@ plugins { java id("jacoco-common") id("maven-artifact") + id("com.diffplug.spotless") } dependencies { @@ -65,3 +66,27 @@ tasks { jvmArgs("-Xss5m", "-Xms512m", "-Xmx1g") } } + +spotless { + java { + // apply a specific flavor of google-java-format + googleJavaFormat("1.8").aosp().reflowLongStrings().skipJavadocFormatting() + // fix formatting of type annotations + formatAnnotations() + licenseHeader( + """ Copyright $(YEAR) Budapest University of Technology and Economics + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License.""".trimIndent() + ) + } +} \ No newline at end of file From 1aed01bfe0fa521a3a8d4721bc5d2925b0725d12 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 13:02:46 +0200 Subject: [PATCH 24/40] Initial java formatting --- build.gradle.kts | 3 ++- buildSrc/build.gradle.kts | 2 +- buildSrc/gradle.properties | 2 +- buildSrc/src/main/kotlin/java-common.gradle.kts | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 108baa86d1..7c35deef20 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + plugins { base id("jacoco-common") @@ -88,4 +89,4 @@ tasks { username = System.getenv("OSSRH_USERNAME") password = System.getenv("OSSRH_PASSWORD") } -} +} \ No newline at end of file diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index f731f11685..17bd8d751c 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -106,4 +106,4 @@ tasks { named("compileKotlin", KotlinCompile::class) { dependsOn(generateVersions) } -} +} \ No newline at end of file diff --git a/buildSrc/gradle.properties b/buildSrc/gradle.properties index 48f1a02d7d..77da25281b 100644 --- a/buildSrc/gradle.properties +++ b/buildSrc/gradle.properties @@ -40,4 +40,4 @@ gsonVersion=2.9.1 javasmtVersion=4.1.1 sosylabVersion=0.3000-569-g89796f98 cliktVersion=4.4.0 -spotlessVersion=7.0.0.BETA3 \ No newline at end of file +spotlessVersion=6.25.0 \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/java-common.gradle.kts b/buildSrc/src/main/kotlin/java-common.gradle.kts index 4c1438291f..3700580aa8 100644 --- a/buildSrc/src/main/kotlin/java-common.gradle.kts +++ b/buildSrc/src/main/kotlin/java-common.gradle.kts @@ -70,7 +70,7 @@ tasks { spotless { java { // apply a specific flavor of google-java-format - googleJavaFormat("1.8").aosp().reflowLongStrings().skipJavadocFormatting() + googleJavaFormat("1.24.0").aosp().reflowLongStrings() // fix formatting of type annotations formatAnnotations() licenseHeader( From 81228be5bc593e9ee4c0e85a830923a13a38e4f8 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 13:24:14 +0200 Subject: [PATCH 25/40] Added kotlin and kotlin-script formatting Finalized formatting script --- .../src/main/kotlin/java-common.gradle.kts | 45 +++++++++++++------ 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/buildSrc/src/main/kotlin/java-common.gradle.kts b/buildSrc/src/main/kotlin/java-common.gradle.kts index 3700580aa8..1eb2c30393 100644 --- a/buildSrc/src/main/kotlin/java-common.gradle.kts +++ b/buildSrc/src/main/kotlin/java-common.gradle.kts @@ -68,25 +68,42 @@ tasks { } spotless { + ratchetFrom("origin/master") + + val year = "\$YEAR" // you can't escape $ in raw strings.. + val licenseHeader = """ /* + * Copyright $year Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */""".trimIndent() + + java { - // apply a specific flavor of google-java-format + importOrder("java|javax", "hu.bme.", "") + removeUnusedImports() googleJavaFormat("1.24.0").aosp().reflowLongStrings() - // fix formatting of type annotations formatAnnotations() - licenseHeader( - """ Copyright $(YEAR) Budapest University of Technology and Economics - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + licenseHeader(licenseHeader) + } + kotlin { + ktfmt("0.51").googleStyle() - http://www.apache.org/licenses/LICENSE-2.0 + licenseHeader(licenseHeader) + } + kotlinGradle { + target("*.gradle.kts") // default target for kotlinGradle - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License.""".trimIndent() - ) + ktlint() } } \ No newline at end of file From 35c33b8047fcf44fdb23712e07b5f4a688192c80 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:22:23 +0200 Subject: [PATCH 26/40] Revert "Reformatted code" This reverts commit e37b32302b2cb72893e26b52bc63d305e999a98f. Revert "Reformatted code" This reverts commit 185dc7ad29920254fc689ac68ff01952a1c65c5a. --- buildSrc/build.gradle.kts | 3 +- .../src/main/kotlin/maven-artifact.gradle.kts | 9 +- scripts/complex.kts | 324 +++------ scripts/simple.kts | 6 +- .../theta/cfa/analysis/CfaToMonolithicExpr.kt | 12 +- .../bounded/BoundedCheckerBuilder.kt | 18 +- .../analysis/algorithm/chc/HornChecker.kt | 3 +- .../analysis/algorithm/mcm/MemoryEvent.kt | 12 +- .../algorithm/mcm/analysis/PartialSolver.kt | 3 +- .../mit/theta/analysis/ptr/ItpRefToPtrPrec.kt | 6 +- .../bme/mit/theta/analysis/ptr/PtrAction.kt | 23 +- .../bme/mit/theta/analysis/ptr/PtrAnalysis.kt | 15 +- .../hu/bme/mit/theta/analysis/ptr/PtrUtils.kt | 40 +- .../analysis/runtimemonitor/CexMonitor.kt | 9 +- .../runtimemonitor/MonitorCheckpoint.kt | 3 +- .../mit/theta/analysis/multi/MultiInitFunc.kt | 2 +- .../theta/analysis/multi/MultiPartialOrd.kt | 2 +- .../theta/analysis/multi/MultiTransFunc.kt | 2 +- .../multi/builder/MultiBuilderResult.kt | 2 +- .../multi/builder/MultiControlInitFunc.kt | 2 +- .../theta/analysis/algorithm/BoundedTest.kt | 9 +- .../mit/theta/analysis/ptr/PtrAnalysisTest.kt | 37 +- .../java/hu/bme/mit/theta/core/ChcUtils.kt | 6 +- .../hu/bme/mit/theta/grammar/dsl/Utils.kt | 6 +- .../mit/theta/grammar/dsl/expr/ExprParser.kt | 210 ++---- .../mit/theta/grammar/dsl/stmt/StmtParser.kt | 3 +- .../bme/mit/theta/grammar/gson/ArgAdapter.kt | 6 +- .../theta/grammar/gson/ArgAdapterHelper.kt | 9 +- .../theta/grammar/gson/SafetyResultAdapter.kt | 12 +- .../mit/theta/grammar/gson/StateAdapters.kt | 6 +- .../mit/theta/grammar/gson/TraceAdapter.kt | 18 +- .../mit/theta/grammar/gson/VarDeclAdapter.kt | 6 +- .../hu/bme/mit/theta/grammar/dsl/ExprTest.kt | 283 +++----- .../hu/bme/mit/theta/grammar/dsl/StmtTest.kt | 18 +- .../hu/bme/mit/theta/grammar/dsl/TypeTest.kt | 6 +- .../hu/bme/mit/theta/grammar/gson/TestGson.kt | 54 +- .../MultiNondetDiningPhilosophersTest.kt | 30 +- .../hu/bme/mit/theta/frontend/CStatistics.kt | 6 +- subprojects/frontends/llvm/build.gradle.kts | 30 +- .../compilers/DefaultGraphPatternCompiler.kt | 6 +- .../compilers/GraphPatternCompiler.kt | 6 +- .../pattern2expr/Pattern2ExprCompiler.kt | 24 +- .../mit/theta/graphsolver/GraphSolverTest.kt | 162 ++--- .../smtlib/GenericSmtLibHornSolverTest.kt | 7 +- .../mit/theta/solver/z3/Z3HornSolverTest.kt | 7 +- .../mit/theta/c2xcfa/FrontendXcfaBuilder.kt | 488 +++++--------- .../java/hu/bme/mit/theta/c2xcfa/Utils.kt | 6 +- .../hu/bme/mit/theta/cat/dsl/CatVisitor.kt | 3 +- subprojects/xcfa/llvm2xcfa/build.gradle.kts | 6 +- .../hu/bme/mit/theta/xcfa/analysis/Utils.kt | 3 +- .../mit/theta/xcfa/analysis/XcfaAbstractor.kt | 7 +- .../bme/mit/theta/xcfa/analysis/XcfaAction.kt | 12 +- .../mit/theta/xcfa/analysis/XcfaAnalysis.kt | 148 ++--- .../theta/xcfa/analysis/XcfaPrecRefiner.kt | 15 +- .../analysis/XcfaSingeExprTraceRefiner.kt | 13 +- .../bme/mit/theta/xcfa/analysis/XcfaState.kt | 125 ++-- .../theta/xcfa/analysis/XcfaStateAdapter.kt | 6 +- .../xcfa/analysis/XcfaToMonolithicExpr.kt | 36 +- .../xcfa/analysis/coi/XcfaCoiMultiThread.kt | 6 +- .../theta/xcfa/analysis/oc/XcfaOcChecker.kt | 6 +- .../xcfa/analysis/oc/XcfaOcTraceExtractor.kt | 24 +- .../theta/xcfa/analysis/por/XcfaDporLts.kt | 7 +- .../xcfa/analysis/XcfaExplAnalysisTest.kt | 97 +-- .../xcfa/analysis/XcfaPredAnalysisTest.kt | 100 +-- .../theta/xcfa/analysis/XcfaStateLtsTest.kt | 3 +- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 26 +- .../cli/checkers/ConfigToBoundedChecker.kt | 24 +- .../xcfa/cli/checkers/ConfigToCegarChecker.kt | 45 +- .../xcfa/cli/checkers/ConfigToChecker.kt | 6 +- .../xcfa/cli/checkers/ConfigToOcChecker.kt | 12 +- .../xcfa/cli/checkers/ConfigToPortfolio.kt | 71 +- .../xcfa/cli/checkers/InProcessChecker.kt | 31 +- .../mit/theta/xcfa/cli/params/ParamValues.kt | 45 +- .../mit/theta/xcfa/cli/params/XcfaConfig.kt | 108 +-- .../mit/theta/xcfa/cli/portfolio/bounded.kt | 98 +-- .../mit/theta/xcfa/cli/portfolio/complex23.kt | 507 +++++--------- .../mit/theta/xcfa/cli/portfolio/complex24.kt | 616 ++++++------------ .../bme/mit/theta/xcfa/cli/portfolio/horn.kt | 44 +- .../bme/mit/theta/xcfa/cli/portfolio/stm.kt | 29 +- .../bme/mit/theta/xcfa/cli/utils/GsonUtils.kt | 54 +- .../mit/theta/xcfa/cli/utils/PropertyUtils.kt | 6 +- .../mit/theta/xcfa/cli/utils/XcfaParser.kt | 79 +-- .../theta/xcfa/cli/utils/XcfaWitnessWriter.kt | 93 +-- .../xcfa/cli/witnesses/TraceToWitness.kt | 39 +- .../mit/theta/xcfa/cli/witnesses/Witness.kt | 17 +- .../mit/theta/xcfa/cli/XcfaCliParseTest.kt | 136 ++-- .../theta/xcfa/cli/XcfaCliPortfolioTest.kt | 22 +- .../mit/theta/xcfa/cli/XcfaCliVerifyTest.kt | 24 +- .../mit/theta/xcfa/cli/XcfaCliWitnessTest.kt | 40 +- .../hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt | 15 +- .../hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt | 12 +- .../xcfa-cli/src/test/resources/simple.kts | 16 +- .../main/java/hu/bme/mit/theta/xcfa/Utils.kt | 36 +- .../java/hu/bme/mit/theta/xcfa/XcfaToC.kt | 6 +- .../hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt | 9 +- .../mit/theta/xcfa/gson/XcfaLabelAdapter.kt | 9 +- .../java/hu/bme/mit/theta/xcfa/model/Dsl.kt | 49 +- .../hu/bme/mit/theta/xcfa/model/Visualizer.kt | 3 +- .../hu/bme/mit/theta/xcfa/model/XcfaLabel.kt | 33 +- .../xcfa/passes/AssumeFalseRemovalPass.kt | 3 +- .../xcfa/passes/AtomicReadsOneWritePass.kt | 9 +- .../xcfa/passes/CLibraryFunctionsPass.kt | 16 +- .../theta/xcfa/passes/ErrorLocationPass.kt | 7 +- .../xcfa/passes/FetchExecuteWriteback.kt | 56 +- .../theta/xcfa/passes/FinalLocationPass.kt | 18 +- .../xcfa/passes/FpFunctionsToExprsPass.kt | 286 +++----- .../xcfa/passes/HavocPromotionAndRange.kt | 15 +- .../theta/xcfa/passes/InlineProceduresPass.kt | 40 +- .../hu/bme/mit/theta/xcfa/passes/LbePass.kt | 18 +- .../theta/xcfa/passes/MallocFunctionPass.kt | 42 +- .../mit/theta/xcfa/passes/NoSideEffectPass.kt | 4 +- .../theta/xcfa/passes/NondetFunctionPass.kt | 16 +- .../mit/theta/xcfa/passes/NormalizePass.kt | 4 +- .../theta/xcfa/passes/ProcedurePassManager.kt | 44 +- .../theta/xcfa/passes/ReferenceElimination.kt | 104 +-- .../theta/xcfa/passes/SvCompIntrinsicsPass.kt | 19 +- .../mit/theta/xcfa/passes/UnusedVarPass.kt | 6 +- .../hu/bme/mit/theta/xcfa/passes/Utils.kt | 66 +- .../hu/bme/mit/theta/xcfa/gson/GsonTest.kt | 24 +- .../hu/bme/mit/theta/xcfa/passes/PassTests.kt | 31 +- .../hu/bme/mit/theta/xcfa/passes/UtilsTest.kt | 36 +- .../hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt | 112 ++-- .../theta/xsts/analysis/XstsToRelations.kt | 3 +- .../theta/xsts/analysis/util/RandomXsts.kt | 54 +- .../xsts/analysis/util/XstsSerializer.kt | 3 +- .../mit/theta/xsts/utils/XSTSVarChanger.kt | 6 +- 126 files changed, 2007 insertions(+), 3969 deletions(-) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 17bd8d751c..7b1e3380f6 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -46,8 +46,7 @@ dependencies { // https://github.com/gradle/kotlin-dsl/issues/1207 configurations.all { val isKotlinCompiler = name == "embeddedKotlin" || name.startsWith("kotlin") || name.startsWith( - "kapt" - ) + "kapt") if (!isKotlinCompiler) { resolutionStrategy.eachDependency { if (requested.group == "org.jetbrains.kotlin" && requested.module.name == "kotlin-compiler-embeddable") { diff --git a/buildSrc/src/main/kotlin/maven-artifact.gradle.kts b/buildSrc/src/main/kotlin/maven-artifact.gradle.kts index acb489be5d..95ddb2d588 100644 --- a/buildSrc/src/main/kotlin/maven-artifact.gradle.kts +++ b/buildSrc/src/main/kotlin/maven-artifact.gradle.kts @@ -107,14 +107,11 @@ tasks { repositories { maven { val releasesRepoUrl = uri( - "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/" - ) + "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/") val snapshotsRepoUrl = uri( - "https://s01.oss.sonatype.org/content/repositories/snapshots/" - ) + "https://s01.oss.sonatype.org/content/repositories/snapshots/") url = if (version.toString() - .endsWith("SNAPSHOT") - ) snapshotsRepoUrl else releasesRepoUrl + .endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl credentials { username = System.getenv("OSSRH_USERNAME") password = System.getenv("OSSRH_PASSWORD") diff --git a/scripts/complex.kts b/scripts/complex.kts index 98e5e6d073..b90d3907cc 100644 --- a/scripts/complex.kts +++ b/scripts/complex.kts @@ -89,60 +89,38 @@ val predConfig = baseConfig.copy(domain = Domain.PRED_CART, refinement = Refinem fun integerStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_z3_4.10.1_$inProcess", - quickExplConfig.copy( - abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_2_1 = ConfigNode( - "EmptyExpl_z3_4.10.1_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_3_1 = ConfigNode( - "PredCart_z3_4.10.1_$inProcess", - predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess - ) + val config_1_1 = ConfigNode("QuickFullExpl_z3_4.10.1_$inProcess", + quickExplConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_1 = ConfigNode("EmptyExpl_z3_4.10.1_$inProcess", + emptyExplConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_3_1 = ConfigNode("PredCart_z3_4.10.1_$inProcess", + predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess) val config_1_2 = ConfigNode("QuickFullExpl_Z3_$inProcess", quickExplConfig.copy(), checker, inProcess) val config_2_2 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(), checker, inProcess) val config_3_2 = ConfigNode("PredCart_Z3_$inProcess", predConfig.copy(), checker, inProcess) - val config_1_3 = ConfigNode( - "QuickFullExpl_princess_2022_07_01_$inProcess", + val config_1_3 = ConfigNode("QuickFullExpl_princess_2022_07_01_$inProcess", quickExplConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess - ) - val config_2_3 = ConfigNode( - "EmptyExpl_princess_2022_07_01_$inProcess", + checker, inProcess) + val config_2_3 = ConfigNode("EmptyExpl_princess_2022_07_01_$inProcess", emptyExplConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess - ) - val config_3_3 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", + checker, inProcess) + val config_3_3 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess - ) + inProcess) - val config_1_4 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", + val config_1_4 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess - ) - val config_2_4 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", + inProcess) + val config_2_4 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess - ) - val config_3_4 = ConfigNode( - "PredCart_princess_2022_07_01_$inProcess", + inProcess) + val config_3_4 = ConfigNode("PredCart_princess_2022_07_01_$inProcess", predConfig.copy(abstractionSolver = "princess:2022-07-01", refinementSolver = "princess:2022-07-01"), - checker, inProcess - ) + checker, inProcess) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -158,13 +136,9 @@ fun integerStm(): STM { Edge(config_2_4, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -192,60 +166,32 @@ fun integerStm(): STM { fun bitwiseStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_Z3_$inProcess", - quickExplConfig.copy(refinement = Refinement.NWT_IT_WP), checker, inProcess - ) - val config_2_1 = ConfigNode( - "EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(refinement = Refinement.NWT_IT_WP), - checker, inProcess - ) - val config_3_1 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", + val config_1_1 = ConfigNode("QuickFullExpl_Z3_$inProcess", + quickExplConfig.copy(refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_1 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.copy(refinement = Refinement.NWT_IT_WP), + checker, inProcess) + val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess - ) - - val config_1_2 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_2_2 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_3_2 = ConfigNode( - "PredCart_z3_4.10.1_$inProcess", - predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess - ) - - val config_1_3 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.copy( - abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_2_3 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.SEQ_ITP - ), checker, inProcess - ) - val config_3_3 = ConfigNode( - "PredCart_cvc5_1.0.2_$inProcess", - predConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) + inProcess) + + val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", + emptyExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_3_2 = ConfigNode("PredCart_z3_4.10.1_$inProcess", + predConfig.copy(abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1"), checker, inProcess) + + val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + refinement = Refinement.SEQ_ITP), checker, inProcess) + val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", + predConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -258,13 +204,9 @@ fun bitwiseStm(): STM { Edge(config_2_3, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -289,113 +231,57 @@ fun bitwiseStm(): STM { fun floatsStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_2_1 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_3_1 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", + val config_1_1 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_1 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", predConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8"), checker, - inProcess - ) - - val config_1_2 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_seq_$inProcess", - quickExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP - ), checker, inProcess - ) - val config_2_2 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_seq_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP - ), checker, inProcess - ) - val config_3_2 = ConfigNode( - "PredCart_bitwuzla_latest_$inProcess", - predConfig.copy( - abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - - val config_1_3 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.copy( - abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), - checker, inProcess - ) - val config_2_3 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), - checker, inProcess - ) - val config_3_3 = ConfigNode( - "PredCart_cvc5_1.0.2_$inProcess", - predConfig.copy( - abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - - val config_1_4 = ConfigNode( - "QuickFullExpl_mathsat_fp_$inProcess", - quickExplConfig.copy( - abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker, inProcess - ) - val config_2_4 = ConfigNode( - "EmptyExpl_mathsat_fp_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker, inProcess - ) - val config_3_4 = ConfigNode( - "PredCart_mathsat_fp_$inProcess", - predConfig.copy( - abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker, inProcess - ) - - val config_1_5 = ConfigNode( - "QuickFullExpl_Z3_$inProcess", - quickExplConfig.copy( - abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_2_5 = ConfigNode( - "EmptyExpl_Z3_$inProcess", - emptyExplConfig.copy( - abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), checker, inProcess - ) - val config_3_5 = ConfigNode( - "PredCart_Z3_$inProcess", + inProcess) + + val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_seq_$inProcess", + quickExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP), checker, inProcess) + val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_seq_$inProcess", + emptyExplConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP), checker, inProcess) + val config_3_2 = ConfigNode("PredCart_bitwuzla_latest_$inProcess", + predConfig.copy(abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + + val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), + checker, inProcess) + val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.copy(abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", + validateAbstractionSolver = true, validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), + checker, inProcess) + val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", + predConfig.copy(abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker, inProcess) + + val config_1_4 = ConfigNode("QuickFullExpl_mathsat_fp_$inProcess", + quickExplConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) + val config_2_4 = ConfigNode("EmptyExpl_mathsat_fp_$inProcess", + emptyExplConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) + val config_3_4 = ConfigNode("PredCart_mathsat_fp_$inProcess", + predConfig.copy(abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true), checker, inProcess) + + val config_1_5 = ConfigNode("QuickFullExpl_Z3_$inProcess", + quickExplConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_2_5 = ConfigNode("EmptyExpl_Z3_$inProcess", + emptyExplConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker, inProcess) + val config_3_5 = ConfigNode("PredCart_Z3_$inProcess", predConfig.copy(abstractionSolver = "Z3", refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP), - checker, inProcess - ) + checker, inProcess) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -414,13 +300,9 @@ fun floatsStm(): STM { Edge(config_2_5, config_3_1, if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), diff --git a/scripts/simple.kts b/scripts/simple.kts index da95633e75..78c2678a13 100644 --- a/scripts/simple.kts +++ b/scripts/simple.kts @@ -47,10 +47,8 @@ var baseConfig = XcfaCegarConfig( ) if (traitsTyped.multithreaded) { - baseConfig = baseConfig.copy( - search = Search.BFS, porLevel = POR.AAPOR, - pruneStrategy = PruneStrategy.LAZY - ) + baseConfig = baseConfig.copy(search = Search.BFS, porLevel = POR.AAPOR, + pruneStrategy = PruneStrategy.LAZY) if (propertyTyped == ErrorDetection.DATA_RACE) { baseConfig = baseConfig.copy(porLevel = POR.BASIC) diff --git a/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt b/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt index 1164bb66af..ca6c125314 100644 --- a/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt +++ b/subprojects/cfa/cfa-analysis/src/main/kotlin/hu/bme/mit/theta/cfa/analysis/CfaToMonolithicExpr.kt @@ -41,13 +41,11 @@ fun CFA.toMonolithicExpr(): MonolithicExpr { } val locVar = Decls.Var("__loc__", Int()) val tranList = this.edges.map { e -> - SequenceStmt.of( - listOf( - AssumeStmt.of(Eq(locVar.ref, Int(map[e.source]!!))), - e.stmt, - AssignStmt.of(locVar, Int(map[e.target]!!)) - ) - ) + SequenceStmt.of(listOf( + AssumeStmt.of(Eq(locVar.ref, Int(map[e.source]!!))), + e.stmt, + AssignStmt.of(locVar, Int(map[e.target]!!)) + )) }.toList() val trans = NonDetStmt.of(tranList); val transUnfold = StmtUtils.toExpr(trans, VarIndexingFactory.indexing(0)); diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt index 03de89fb27..bfd1aeadf9 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedCheckerBuilder.kt @@ -34,10 +34,8 @@ fun buildBMC( bmcEnabled: () -> Boolean = { true }, lfPathOnly: () -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker( - monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, null, - { false }, valToState, biValToAction, logger - ) + return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, null, + { false }, valToState, biValToAction, logger) } @JvmOverloads @@ -53,10 +51,8 @@ fun buildKIND( lfPathOnly: () -> Boolean = { true }, kindEnabled: (Int) -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker( - monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, indSolver, - kindEnabled, valToState, biValToAction, logger - ) + return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, null, { false }, indSolver, + kindEnabled, valToState, biValToAction, logger) } @JvmOverloads @@ -72,8 +68,6 @@ fun buildIMC( lfPathOnly: () -> Boolean = { true }, imcEnabled: (Int) -> Boolean = { true }, ): BoundedChecker { - return BoundedChecker( - monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, itpSolver, imcEnabled, null, - { false }, valToState, biValToAction, logger - ) + return BoundedChecker(monolithicExpr, shouldGiveUp, bmcSolver, bmcEnabled, lfPathOnly, itpSolver, imcEnabled, null, + { false }, valToState, biValToAction, logger) } \ No newline at end of file diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt index 8630eed180..0c083b7cd0 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt @@ -68,8 +68,7 @@ class HornChecker( logger.write(Logger.Level.MAINSTEP, "Proof (model) found\n") val model = solver.model.toMap() SafetyResult.safe( - Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() }) - ) + Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() })) } SolverStatus.UNSAT -> { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt index eeb9b794a4..d10f26e4d1 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/MemoryEvent.kt @@ -52,10 +52,8 @@ open class MemoryEvent(protected val type: MemoryEventType, protected val tag: S throw UnsupportedOperationException("Not memory IO!") } - abstract class MemoryIO( - id: Int, private val `var`: VarDecl<*>, private val localVar: VarDecl<*>, - type: MemoryEventType, tag: String - ) : + abstract class MemoryIO(id: Int, private val `var`: VarDecl<*>, private val localVar: VarDecl<*>, + type: MemoryEventType, tag: String) : MemoryEvent(type, tag, id) { override fun asMemoryIO(): MemoryIO { @@ -88,10 +86,8 @@ open class MemoryEvent(protected val type: MemoryEventType, protected val tag: S } } - class Write( - id: Int, `var`: VarDecl<*>, localVar: VarDecl<*>, private val dependencies: Set>, - tag: String - ) : + class Write(id: Int, `var`: VarDecl<*>, localVar: VarDecl<*>, private val dependencies: Set>, + tag: String) : MemoryIO(id, `var`, localVar, MemoryEventType.WRITE, tag) { override fun asWrite(): Write { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt index 24b877d848..a0257bb216 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/PartialSolver.kt @@ -54,6 +54,5 @@ class PartialSolver( data class CandidateExecutionGraph( val nodes: List, - val knownEvents: Map, ThreeVL> -) { + val knownEvents: Map, ThreeVL>) { } \ No newline at end of file diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt index 6b17827bf2..c3ec804041 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/ItpRefToPtrPrec.kt @@ -30,10 +30,8 @@ class ItpRefToPtrPrec

(private val innerRefToPrec: RefutationToPrec { val newDerefs = refutation[index].dereferences val innerPrec = innerRefToPrec.toPrec(refutation, index).repatch() - return PtrPrec( - innerPrec, newDerefs.flatMap { it.ops }.toSet(), - if (newDerefs.isEmpty()) 0 else refutation.size() - index - ) + return PtrPrec(innerPrec, newDerefs.flatMap { it.ops }.toSet(), + if (newDerefs.isEmpty()) 0 else refutation.size() - index) } override fun join(prec1: PtrPrec

, prec2: PtrPrec

): PtrPrec

{ diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt index 4dee747bb0..015084a889 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAction.kt @@ -61,30 +61,19 @@ abstract class PtrAction(writeTriples: WriteTriples = emptyMap(), val inCnt: Int val postList = ArrayList() for ((deref, type) in stmt.dereferencesWithAccessTypes) { - Preconditions.checkState( - deref.uniquenessIdx.isPresent, - "Incomplete dereferences (missing uniquenessIdx) are not handled properly." - ) + Preconditions.checkState(deref.uniquenessIdx.isPresent, + "Incomplete dereferences (missing uniquenessIdx) are not handled properly.") val expr = deref.getIte(nextWriteTriples) if (type == AccessType.WRITE) { val writeExpr = ExprUtils.simplify(IntExprs.Add(expr, IntExprs.Int(1))) nextWriteTriples.getOrPut(deref.type) { ArrayList() } .add(Triple(lookup[deref]!!.first, lookup[deref]!!.second, deref.uniquenessIdx.get())) - postList.add( - Stmts.Assume( - ExprUtils.simplify( - BoolExprs.And( - listOf( - AbstractExprs.Eq(writeExpr, deref.uniquenessIdx.get()), - ) - ) - ) - ) - ) + postList.add(Stmts.Assume(ExprUtils.simplify(BoolExprs.And(listOf( + AbstractExprs.Eq(writeExpr, deref.uniquenessIdx.get()), + ))))) } else { preList.add( - Stmts.Assume(ExprUtils.simplify(AbstractExprs.Eq(expr, deref.uniquenessIdx.get()))) - ) + Stmts.Assume(ExprUtils.simplify(AbstractExprs.Eq(expr, deref.uniquenessIdx.get())))) } // postList.add(Stmts.Assume(Eq(vargen("value", deref.type).ref, deref))) // debug mode } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt index 881fecb5bb..4eb29ec625 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysis.kt @@ -35,20 +35,16 @@ import hu.bme.mit.theta.core.stmt.Stmt * */ -class PtrAnalysis( - private val innerAnalysis: Analysis, - private val isHavoc: Boolean = false -) : +class PtrAnalysis(private val innerAnalysis: Analysis, + private val isHavoc: Boolean = false) : Analysis, PtrAction, PtrPrec

> { override fun getPartialOrd(): PartialOrd> = innerAnalysis.partialOrd.getPtrPartialOrd() override fun getInitFunc(): InitFunc, PtrPrec

> = innerAnalysis.initFunc.getPtrInitFunc() - override fun getTransFunc(): TransFunc, PtrAction, PtrPrec

> = - innerAnalysis.transFunc.getPtrTransFunc( - isHavoc - ) + override fun getTransFunc(): TransFunc, PtrAction, PtrPrec

> = innerAnalysis.transFunc.getPtrTransFunc( + isHavoc) } fun PartialOrd.getPtrPartialOrd(): PartialOrd> = PartialOrd { state1, state2 -> @@ -60,8 +56,7 @@ fun InitFunc.getPtrInitFunc(): InitFunc TransFunc.getPtrTransFunc( - isHavoc: Boolean = false -): TransFunc, PtrAction, PtrPrec

> = TransFunc { state, action, prec -> + isHavoc: Boolean = false): TransFunc, PtrAction, PtrPrec

> = TransFunc { state, action, prec -> val writeTriples = action.nextWriteTriples() val patchedPrec = prec.innerPrec.patch(writeTriples) val exprAction: ExprAction = if (isHavoc) { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt index e051625334..3cc08a0cf1 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/ptr/PtrUtils.kt @@ -53,8 +53,7 @@ enum class AccessType { val Stmt.dereferencesWithAccessTypes: List, AccessType>> get() = when (this) { is MemoryAssignStmt<*, *, *> -> expr.dereferences.map { Pair(it, AccessType.READ) } + listOf( - Pair(deref, AccessType.WRITE) - ) + deref.ops.flatMap { it.dereferences }.map { Pair(it, AccessType.READ) } + Pair(deref, AccessType.WRITE)) + deref.ops.flatMap { it.dereferences }.map { Pair(it, AccessType.READ) } is AssignStmt<*> -> expr.dereferences.map { Pair(it, AccessType.READ) } is AssumeStmt -> cond.dereferences.map { Pair(it, AccessType.READ) } @@ -84,23 +83,19 @@ fun SequenceStmt.collapse(): Stmt = this } -fun Stmt.uniqueDereferences( - vargen: (String, Type) -> VarDecl<*>, - lookup: MutableMap, Pair, Expr<*>>> -): Stmt { +fun Stmt.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, + lookup: MutableMap, Pair, Expr<*>>>): Stmt { val ret = ArrayList() val newStmt = when (this) { is MemoryAssignStmt<*, *, *> -> { MemoryAssignStmt.create( deref.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second as Dereference<*, *, *>, - expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second - ) + expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) } is AssignStmt<*> -> AssignStmt.of( TypeUtils.cast(varDecl, varDecl.type), - TypeUtils.cast(expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second, varDecl.type) - ) + TypeUtils.cast(expr.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second, varDecl.type)) is AssumeStmt -> AssumeStmt.of(cond.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) is SequenceStmt -> Stmts.SequenceStmt(stmts.map { it.uniqueDereferences(vargen, lookup) }) @@ -114,16 +109,13 @@ fun Stmt.uniqueDereferences( return SequenceStmt.of(ret + newStmt).collapse() } -fun Expr.uniqueDereferences( - vargen: (String, Type) -> VarDecl<*>, - lookup: MutableMap, Pair, Expr<*>>> -): Pair, Expr> = +fun Expr.uniqueDereferences(vargen: (String, Type) -> VarDecl<*>, + lookup: MutableMap, Pair, Expr<*>>>): Pair, Expr> = if (this is Dereference<*, *, T>) { val ret = ArrayList() Preconditions.checkState(this.uniquenessIdx.isEmpty, "Only non-pretransformed dereferences should be here") val arrayExpr = ExprUtils.simplify( - array.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second - ) + array.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) val arrayLaterRef = if (arrayExpr !is LitExpr<*>) { val arrayConst = vargen("a", array.type).ref ret.add(Assume(Eq(arrayConst, arrayExpr))) @@ -132,8 +124,7 @@ fun Expr.uniqueDereferences( arrayExpr } val offsetExpr = ExprUtils.simplify( - offset.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second - ) + offset.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second) val offsetLaterRef = if (offsetExpr !is LitExpr<*>) { val offsetConst = vargen("o", offset.type).ref ret.add(Assume(Eq(offsetConst, offsetExpr))) @@ -149,10 +140,8 @@ fun Expr.uniqueDereferences( Pair(ret, retDeref) } else { val ret = ArrayList() - Pair( - ret, - this.withOps(this.ops.map { it.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second }) - ) + Pair(ret, + this.withOps(this.ops.map { it.uniqueDereferences(vargen, lookup).also { ret.addAll(it.first) }.second })) } object TopCollection : Set> { @@ -179,11 +168,8 @@ enum class PtrTracking { fun Dereference.getIte(writeTriples: WriteTriples): Expr { val list = writeTriples[type] ?: emptyList() return list.fold(Int(0) as Expr) { elze, (arr, off, value) -> - IteExpr.of( - BoolExprs.And( - listOf(Eq(arr, array), Eq(off, offset)) - ), value, elze - ) + IteExpr.of(BoolExprs.And( + listOf(Eq(arr, array), Eq(off, offset))), value, elze) } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt index 95069ed1c1..32c78c9b0e 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/CexMonitor.kt @@ -39,10 +39,8 @@ class CexMonitor constructor( fun checkIfNewCexFound(): Boolean { return if (arg.cexs.anyMatch { cex -> !cexHashStorage.contains(cex) }) { - logger.write( - Logger.Level.VERBOSE, - "Counterexample hash check: new cex found successfully\n" - ) + logger.write(Logger.Level.VERBOSE, + "Counterexample hash check: new cex found successfully\n") true } else { logger.write(Logger.Level.INFO, "Counterexample hash check: NO new cex found\n") @@ -67,8 +65,7 @@ class CexMonitor constructor( when (checkpointName) { "CegarChecker.unsafeARG" -> if (checkIfNewCexFound()) addNewCounterexample() else throwNotSolvable() else -> throw RuntimeException( - "Unknown checkpoint name in CexMonitor execution: $checkpointName" - ) + "Unknown checkpoint name in CexMonitor execution: $checkpointName") } } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt index 7ddfe7adec..0e1faccd73 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/runtimemonitor/MonitorCheckpoint.kt @@ -52,8 +52,7 @@ class MonitorCheckpoint internal constructor(private val name: String) { assert(registeredCheckpoints.contains(checkpointName)) { "Checkpoint name $checkpointName was not registered (add it in MonitorCheckpoint.kt)" } // see checkpointNames above registeredCheckpoints[checkpointName]?.registerMonitor(m) ?: error( - "Checkpoint with name $checkpointName not found." - ) + "Checkpoint with name $checkpointName not found.") } fun execute(name: String) { diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt index f3c1ab15ec..4d7e740082 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiInitFunc.kt @@ -22,7 +22,7 @@ import hu.bme.mit.theta.analysis.State class MultiInitFunc> - ( +( private val createInitialState: (LControl, RControl, DataState) -> MState, private val dataInitFunc: InitFunc, private val extractLeftControlPrec: (LPrec) -> LControlPrec, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt index b48b564c28..68b3c77b27 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiPartialOrd.kt @@ -20,7 +20,7 @@ import hu.bme.mit.theta.analysis.State class MultiPartialOrd> - ( +( private val leftPartOrd: PartialOrd, private val leftCombineStates: (LControl, DataState) -> LState, private val rightPartOrd: PartialOrd, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt index 02021807d9..ffe72c9757 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/MultiTransFunc.kt @@ -24,7 +24,7 @@ class MultiTransFunc, MAction : MultiAction> - ( +( private val defineNextSide: (MState) -> MultiSide, private val createState: (LControl, RControl, DataState, MultiSide) -> MState, private val leftTransFunc: TransFunc, diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt index d090ac8cb4..eea37fb1ce 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiBuilderResult.kt @@ -33,7 +33,7 @@ import hu.bme.mit.theta.analysis.unit.UnitState * the whole IDE. For this reason, a POJO has to be used instead */ private data class MultiBuilderResult, MControlState : MultiState, MAction : MultiAction, MLts : MultiLts> - ( +( val side: MultiAnalysisSide, MultiPrec>, val lts: MLts ) diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt index 6aa4f6614a..d094692eac 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/builder/MultiControlInitFunc.kt @@ -28,7 +28,7 @@ import hu.bme.mit.theta.analysis.unit.UnitState * Serves as a control initial function for a multi analysis if the product is nested and this analysis is going to be a part of a larger product. */ internal class MultiControlInitFunc, MPrec : MultiPrec> - ( +( private val leftControlInitFunc: InitFunc, private val rightControlInitFunc: InitFunc, private val createState: (lState: LControl, rState: RControl) -> MState diff --git a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt index 5156908c26..c1a49e333e 100644 --- a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt +++ b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/BoundedTest.kt @@ -43,8 +43,7 @@ class BoundedTest { } private val biValToAction = { valuation: Valuation?, valuation2: Valuation? -> ExprActionStub( - emptyList() - ) + emptyList()) } init { @@ -77,8 +76,7 @@ class BoundedTest { indSolver = indSolver, valToState = valToState, biValToAction = biValToAction, - logger = ConsoleLogger(Logger.Level.VERBOSE) - ) + logger = ConsoleLogger(Logger.Level.VERBOSE)) val safetyResult: SafetyResult<*, *> = checker.check() Assert.assertTrue(safetyResult.isUnsafe()) } @@ -95,8 +93,7 @@ class BoundedTest { indSolver = indSolver, valToState = valToState, biValToAction = biValToAction, - logger = ConsoleLogger(Logger.Level.VERBOSE) - ) + logger = ConsoleLogger(Logger.Level.VERBOSE)) val safetyResult: SafetyResult<*, *> = checker.check() Assert.assertTrue(safetyResult.isSafe()) } diff --git a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt index 6c2a0a179c..9379846676 100644 --- a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt +++ b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/ptr/PtrAnalysisTest.kt @@ -43,44 +43,31 @@ class PtrAnalysisTest { private val explTop1 = PtrState(ExplState.top(), nextCnt = 1) private val emptyAction = PtrActionStub(listOf(), emptyMap()) - private val readLiteralOnly = PtrActionStub( - listOf(Assume(Eq(Dereference(Int(0), Int(1), Int()), Int(0)))), - emptyMap() - ) - private val writeLiteralOnly = PtrActionStub( - listOf(MemoryAssign(Dereference(Int(0), Int(1), Int()), Int(0))), - emptyMap() - ) + private val readLiteralOnly = PtrActionStub(listOf(Assume(Eq(Dereference(Int(0), Int(1), Int()), Int(0)))), + emptyMap()) + private val writeLiteralOnly = PtrActionStub(listOf(MemoryAssign(Dereference(Int(0), Int(1), Int()), Int(0))), + emptyMap()) private val emptyPrec = PtrPrec(ExplPrec.empty(), emptySet()) @JvmStatic fun testInputs(): Collection { return listOf( - Arguments.of( - explTop0, emptyAction, emptyPrec, - listOf(explTop0) - ), - Arguments.of( - explTop0, readLiteralOnly, emptyPrec, - listOf(explTop1) - ), - Arguments.of( - explTop0, writeLiteralOnly, emptyPrec, + Arguments.of(explTop0, emptyAction, emptyPrec, + listOf(explTop0)), + Arguments.of(explTop0, readLiteralOnly, emptyPrec, + listOf(explTop1)), + Arguments.of(explTop0, writeLiteralOnly, emptyPrec, listOf( - PtrState(ExplState.top(), 1) - ) - ), + PtrState(ExplState.top(), 1))), ) } } @ParameterizedTest @MethodSource("testInputs") - fun transFuncTest( - state: PtrState, action: PtrAction, prec: PtrPrec, - expectedResult: Collection> - ) { + fun transFuncTest(state: PtrState, action: PtrAction, prec: PtrPrec, + expectedResult: Collection>) { val analysis = PtrAnalysis(ExplAnalysis.create(Z3LegacySolverFactory.getInstance().createSolver(), True())) val result = analysis.transFunc.getSuccStates(state, action, prec) diff --git a/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt b/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt index 1f3d2ee7c5..5b7789b350 100644 --- a/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt +++ b/subprojects/common/core/src/main/java/hu/bme/mit/theta/core/ChcUtils.kt @@ -61,10 +61,8 @@ open class Relation(val name: String, vararg paramTypes: Type) { open operator fun invoke(vararg params: Expr<*>) = RelationApp(this, params.toList()) } -data class RelationApp( - val relation: Relation, val params: List>, - val constraints: List> = emptyList() -) { +data class RelationApp(val relation: Relation, val params: List>, + val constraints: List> = emptyList()) { init { checkArgument(params.size == relation.arity) diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt index 665121a5cd..488fe3330b 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/Utils.kt @@ -33,10 +33,8 @@ fun ParserRuleContext.textWithWS(): String { object ThrowingErrorListener : BaseErrorListener() { @Throws(ParseCancellationException::class) - override fun syntaxError( - recognizer: Recognizer<*, *>?, offendingSymbol: Any?, line: Int, - charPositionInLine: Int, msg: String, e: RecognitionException? - ) { + override fun syntaxError(recognizer: Recognizer<*, *>?, offendingSymbol: Any?, line: Int, + charPositionInLine: Int, msg: String, e: RecognitionException?) { throw ParseCancellationException("line $line:$charPositionInLine $msg") } } \ No newline at end of file diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt index adfdcc3f80..f896e6265a 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/expr/ExprParser.kt @@ -118,10 +118,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } private fun pop() { - Preconditions.checkState( - currentScope.enclosingScope().isPresent, - "Enclosing scope is not present." - ) + Preconditions.checkState(currentScope.enclosingScope().isPresent, + "Enclosing scope is not present.") currentScope = currentScope.enclosingScope().get() env.pop() } @@ -129,10 +127,8 @@ class ExpressionWrapper(scope: Scope, content: String) { //// override fun visitFuncLitExpr(ctx: FuncLitExprContext): Expr { return if (ctx.result != null) { - val param = Decls.Param( - ctx.param.name.text, - TypeWrapper(ctx.param.type().textWithWS()).instantiate() - ) + val param = Decls.Param(ctx.param.name.text, + TypeWrapper(ctx.param.type().textWithWS()).instantiate()) push(listOf(param)) val result = ctx.result.accept>(this) as Expr pop() @@ -148,10 +144,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } else { ctx.decls.stream() .map { d: DeclContext -> - Decls.Param( - d.name.getText(), - TypeWrapper(d.ttype.textWithWS()).instantiate() - ) + Decls.Param(d.name.getText(), + TypeWrapper(d.ttype.textWithWS()).instantiate()) }.collect(Collectors.toList()) } } @@ -159,10 +153,8 @@ class ExpressionWrapper(scope: Scope, content: String) { //// override fun visitIteExpr(ctx: IteExprContext): Expr { return if (ctx.cond != null) { - val cond: Expr = TypeUtils.cast( - ctx.cond.accept>(this), - BoolExprs.Bool() - ) + val cond: Expr = TypeUtils.cast(ctx.cond.accept>(this), + BoolExprs.Bool()) val then: Expr<*> = ctx.then.accept>(this) val elze: Expr<*> = ctx.elze.accept>(this) AbstractExprs.Ite(cond, then, elze) @@ -173,14 +165,10 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitIffExpr(ctx: IffExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast( - ctx.leftOp.accept>(this), - BoolExprs.Bool() - ) - val rightOp: Expr = TypeUtils.cast( - ctx.rightOp.accept>(this), - BoolExprs.Bool() - ) + val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), + BoolExprs.Bool()) + val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), + BoolExprs.Bool()) BoolExprs.Iff(leftOp, rightOp) } else { visitChildren(ctx) @@ -189,14 +177,10 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitImplyExpr(ctx: ImplyExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast( - ctx.leftOp.accept>(this), - BoolExprs.Bool() - ) - val rightOp: Expr = TypeUtils.cast( - ctx.rightOp.accept>(this), - BoolExprs.Bool() - ) + val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), + BoolExprs.Bool()) + val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), + BoolExprs.Bool()) BoolExprs.Imply(leftOp, rightOp) } else { visitChildren(ctx) @@ -207,10 +191,8 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.paramDecls != null) { val paramDecls = createParamList(ctx.paramDecls) push(paramDecls) - val op: Expr = TypeUtils.cast( - ctx.op.accept>(this), - BoolExprs.Bool() - ) + val op: Expr = TypeUtils.cast(ctx.op.accept>(this), + BoolExprs.Bool()) pop() BoolExprs.Forall(paramDecls, op) } else { @@ -222,10 +204,8 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.paramDecls != null) { val paramDecls = createParamList(ctx.paramDecls) push(paramDecls) - val op: Expr = TypeUtils.cast( - ctx.op.accept>(this), - BoolExprs.Bool() - ) + val op: Expr = TypeUtils.cast(ctx.op.accept>(this), + BoolExprs.Bool()) pop() BoolExprs.Exists(paramDecls, op) } else { @@ -248,14 +228,10 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitXorExpr(ctx: XorExprContext): Expr { return if (ctx.rightOp != null) { - val leftOp: Expr = TypeUtils.cast( - ctx.leftOp.accept>(this), - BoolExprs.Bool() - ) - val rightOp: Expr = TypeUtils.cast( - ctx.rightOp.accept>(this), - BoolExprs.Bool() - ) + val leftOp: Expr = TypeUtils.cast(ctx.leftOp.accept>(this), + BoolExprs.Bool()) + val rightOp: Expr = TypeUtils.cast(ctx.rightOp.accept>(this), + BoolExprs.Bool()) BoolExprs.Xor(leftOp, rightOp) } else { visitChildren(ctx) @@ -277,10 +253,8 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitNotExpr(ctx: NotExprContext): Expr { return if (ctx.op != null) { - val op: Expr = TypeUtils.cast( - ctx.op.accept>(this), - BoolExprs.Bool() - ) + val op: Expr = TypeUtils.cast(ctx.op.accept>(this), + BoolExprs.Bool()) BoolExprs.Not(op) } else { visitChildren(ctx) @@ -412,10 +386,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createAdditiveExpr( - opsHead: Expr<*>, opsTail: List>, - oper: Token, ctx: AdditiveExprContext - ): Expr { + private fun createAdditiveExpr(opsHead: Expr<*>, opsTail: List>, + oper: Token, ctx: AdditiveExprContext): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -426,24 +398,18 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createAdditiveSubExpr( - leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, - ctx: AdditiveExprContext - ): Expr { + private fun createAdditiveSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, + ctx: AdditiveExprContext): Expr { return when (oper.type) { PLUS -> createAddExpr(leftOp, rightOp) MINUS -> createSubExpr(leftOp, rightOp) BV_ADD -> createBvAddExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) BV_SUB -> createBvSubExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) - FPADD -> FpExprs.Add( - getRoundingMode(ctx.oper.text), - java.util.List.of(TypeUtils.castFp(leftOp), TypeUtils.castFp(rightOp)) - ) + FPADD -> FpExprs.Add(getRoundingMode(ctx.oper.text), + java.util.List.of(TypeUtils.castFp(leftOp), TypeUtils.castFp(rightOp))) - FPSUB -> FpExprs.Sub( - getRoundingMode(ctx.oper.text), TypeUtils.castFp(leftOp), - TypeUtils.castFp(rightOp) - ) + FPSUB -> FpExprs.Sub(getRoundingMode(ctx.oper.text), TypeUtils.castFp(leftOp), + TypeUtils.castFp(rightOp)) else -> throw ParseException(ctx, "Unknown operator '" + oper.text + "'") } @@ -493,10 +459,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createMutliplicativeExpr( - opsHead: Expr<*>, opsTail: List>, - oper: Token, ctx: MultiplicativeExprContext - ): Expr { + private fun createMutliplicativeExpr(opsHead: Expr<*>, opsTail: List>, + oper: Token, ctx: MultiplicativeExprContext): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -507,10 +471,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createMultiplicativeSubExpr( - leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, - ctx: MultiplicativeExprContext - ): Expr { + private fun createMultiplicativeSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, oper: Token, + ctx: MultiplicativeExprContext): Expr { return when (oper.type) { MUL -> createMulExpr(leftOp, rightOp) BV_MUL -> createBvMulExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) @@ -523,15 +485,11 @@ class ExpressionWrapper(scope: Scope, content: String) { BV_UREM -> createBvURemExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) BV_SREM -> createBvSRemExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) FPREM -> FpExprs.Rem(leftOp as Expr, rightOp as Expr) - FPMUL -> FpExprs.Mul( - getRoundingMode(ctx.oper.text), - java.util.List.of(leftOp as Expr, rightOp as Expr) - ) + FPMUL -> FpExprs.Mul(getRoundingMode(ctx.oper.text), + java.util.List.of(leftOp as Expr, rightOp as Expr)) - FPDIV -> FpExprs.Div( - getRoundingMode(ctx.oper.text), leftOp as Expr, - rightOp as Expr - ) + FPDIV -> FpExprs.Div(getRoundingMode(ctx.oper.text), leftOp as Expr, + rightOp as Expr) else -> throw ParseException(ctx, "Unknown operator '" + oper.text + "'") } @@ -605,10 +563,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createConcatExpr( - opsHead: Expr<*>, opsTail: List>, - oper: Token - ): Expr { + private fun createConcatExpr(opsHead: Expr<*>, opsTail: List>, + oper: Token): Expr { return if (opsTail.isEmpty()) { opsHead } else { @@ -619,10 +575,8 @@ class ExpressionWrapper(scope: Scope, content: String) { } } - private fun createConcatSubExpr( - leftOp: Expr<*>, rightOp: Expr<*>, - oper: Token - ): Expr { + private fun createConcatSubExpr(leftOp: Expr<*>, rightOp: Expr<*>, + oper: Token): Expr { return when (oper.type) { BV_CONCAT -> createBvConcatExpr(TypeUtils.castBv(leftOp), TypeUtils.castBv(rightOp)) else -> throw AssertionError() @@ -645,12 +599,10 @@ class ExpressionWrapper(scope: Scope, content: String) { val extendType = BvExprs.BvType(ctx.rightOp.size.getText().toInt()) when (ctx.oper.getType()) { BV_ZERO_EXTEND -> BvExprs.ZExt( - TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType - ) + TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType) BV_SIGN_EXTEND -> BvExprs.SExt( - TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType - ) + TypeUtils.castBv(ctx.leftOp.accept>(this)), extendType) else -> throw AssertionError() } @@ -669,28 +621,20 @@ class ExpressionWrapper(scope: Scope, content: String) { FP_ABS -> FpExprs.Abs(op as Expr) FP_IS_INF -> FpExprs.IsInfinite(op as Expr) FP_IS_NAN -> FpExprs.IsNan(op as Expr) - FPROUNDTOINT -> FpExprs.RoundToIntegral( - getRoundingMode(ctx.oper.text), - op as Expr - ) + FPROUNDTOINT -> FpExprs.RoundToIntegral(getRoundingMode(ctx.oper.text), + op as Expr) FPSQRT -> FpExprs.Sqrt(getRoundingMode(ctx.oper.text), op as Expr) - FPTOFP -> FpExprs.ToFp( - getRoundingMode(ctx.oper.text), op as Expr, - getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText()) - ) - - FPTOBV -> FpExprs.ToBv( - getRoundingMode(ctx.oper.text), op as Expr, - getBvSize(ctx.oper.getText()), isSignedBv(ctx.oper.getText()) - ) - - FP_FROM_BV -> FpExprs.FromBv( - getRoundingMode(ctx.oper.text), + FPTOFP -> FpExprs.ToFp(getRoundingMode(ctx.oper.text), op as Expr, + getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText())) + + FPTOBV -> FpExprs.ToBv(getRoundingMode(ctx.oper.text), op as Expr, + getBvSize(ctx.oper.getText()), isSignedBv(ctx.oper.getText())) + + FP_FROM_BV -> FpExprs.FromBv(getRoundingMode(ctx.oper.text), op as Expr, FpType.of(getExp(ctx.oper.getText()), getSignificand(ctx.oper.getText())), - isSignedFp(ctx.oper.getText()) - ) + isSignedFp(ctx.oper.getText())) FPNEG -> FpExprs.Neg(op as Expr) FPPOS -> FpExprs.Pos(op as Expr) @@ -773,8 +717,7 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.array != null) { ArrayReadExpr.create( ctx.array.accept(this), - ctx.index.accept(this) - ) + ctx.index.accept(this)) } else { visitChildren(ctx) } @@ -785,8 +728,7 @@ class ExpressionWrapper(scope: Scope, content: String) { ArrayWriteExpr.create( ctx.array.accept(this), ctx.index.accept(this), - ctx.elem.accept(this) - ) + ctx.elem.accept(this)) } else { visitChildren(ctx) } @@ -804,10 +746,8 @@ class ExpressionWrapper(scope: Scope, content: String) { return if (ctx.op != null) { val op = ctx.op.accept(this) val bitvec = TypeUtils.castBv(op) - return BvExprs.Extract( - bitvec, Int(ctx.from.getText()), - IntExprs.Int(ctx.until.getText()) - ) + return BvExprs.Extract(bitvec, Int(ctx.from.getText()), + IntExprs.Int(ctx.until.getText())) } else { visitChildren(ctx) } @@ -864,19 +804,14 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitArrLitExpr(ctx: ArrLitExprContext): Expr { Preconditions.checkNotNull(ctx.elseExpr) val indexType = if (ctx.indexExpr.size > 0) ctx.indexExpr[0].accept( - this - ).type else Int() + this).type else Int() val elseElem = ctx.elseExpr.accept(this) val valueType = elseElem.type val elems = ctx.indexExpr.mapIndexed { idx, it -> Tuple2.of(it.accept(this), ctx.valueExpr[idx].accept(this)) } - return ExprUtils.simplify( - ArrayInitExpr.create( - elems, elseElem, - ArrayType.of(indexType, valueType) - ) - ) + return ExprUtils.simplify(ArrayInitExpr.create(elems, elseElem, + ArrayType.of(indexType, valueType))) } override fun visitBvLitExpr(ctx: BvLitExprContext): Expr { @@ -887,8 +822,7 @@ class ExpressionWrapper(scope: Scope, content: String) { decodeBinaryBvContent(content.substring(1)) } else if (content.startsWith("d")) { check( - sizeAndContent.size == 2 - ) { "Decimal value is only parseable if size is given." } + sizeAndContent.size == 2) { "Decimal value is only parseable if size is given." } decodeDecimalBvContent(content.substring(1), sizeAndContent[0].toInt()) } else if (content.startsWith("x")) { decodeHexadecimalBvContent(content.substring(1)) @@ -909,8 +843,7 @@ class ExpressionWrapper(scope: Scope, content: String) { '0' -> value[i] = false '1' -> value[i] = true else -> throw IllegalArgumentException( - "Binary literal can contain only 0 and 1" - ) + "Binary literal can contain only 0 and 1") } } return value @@ -920,8 +853,7 @@ class ExpressionWrapper(scope: Scope, content: String) { var value = BigInteger(lit) Preconditions.checkArgument( value.compareTo( - BigInteger.TWO.pow(size - 1).multiply(BigInteger.valueOf(-1)) - ) >= 0 && + BigInteger.TWO.pow(size - 1).multiply(BigInteger.valueOf(-1))) >= 0 && value.compareTo(BigInteger.TWO.pow(size)) < 0, "Decimal literal is not in range" ) @@ -960,10 +892,8 @@ class ExpressionWrapper(scope: Scope, content: String) { override fun visitIdExpr(ctx: IdExprContext): RefExpr<*> { val optSymbol = currentScope.resolve(ctx.id.getText()) if (optSymbol.isEmpty) { - throw ParseException( - ctx, - "Identifier '" + ctx.id.getText() + "' cannot be resolved" - ) + throw ParseException(ctx, + "Identifier '" + ctx.id.getText() + "' cannot be resolved") } val symbol = optSymbol.get() val decl = env.eval(symbol) as Decl<*> diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt index d11ca4187c..09ea6e8f9d 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/dsl/stmt/StmtParser.kt @@ -108,8 +108,7 @@ class StatementWrapper(val content: String, scope: Scope) { override fun visitMemAssignStmt(ctx: MemAssignStmtContext): Stmt { val derefExpr: Dereference<*, *, *> = ExpressionWrapper(scope, ctx.derefExpr().textWithWS()).instantiate( - env - ) as Dereference<*, *, *> + env) as Dereference<*, *, *> val value = ExpressionWrapper(scope, ctx.value.textWithWS()) val valueE: Expr<*> = value.instantiate(env) return if (derefExpr.type == valueE.type) { diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt index eaad49e3e0..a05598f87e 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapter.kt @@ -26,11 +26,9 @@ import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.algorithm.arg.ARG import java.lang.reflect.Type -class ArgAdapter( - val gsonSupplier: () -> Gson, +class ArgAdapter(val gsonSupplier: () -> Gson, private val partialOrdSupplier: () -> PartialOrd, - private val argTypeSupplier: () -> Type -) : TypeAdapter>() { + private val argTypeSupplier: () -> Type) : TypeAdapter>() { private lateinit var gson: Gson private lateinit var partialOrd: PartialOrd diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt index 05e193a195..f00ff2ac89 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/ArgAdapterHelper.kt @@ -54,14 +54,11 @@ data class ArgAdapterHelper( while (waitSet.isNotEmpty()) { val entry = waitSet.firstOrNull { lut.keys.contains(checkNotNull(edges[it]).source) } check( - entry != null - ) { "Unreachable node(s) present: $waitSet\nedges: $edges\nlut: $lut" } + entry != null) { "Unreachable node(s) present: $waitSet\nedges: $edges\nlut: $lut" } waitSet.remove(entry) val edge = checkNotNull(edges[entry]) - lut[entry] = arg.createSuccNode( - lut[edge.source], edge.action, checkNotNull(nodes[entry]).state, - checkNotNull(nodes[entry]).target - ) + lut[entry] = arg.createSuccNode(lut[edge.source], edge.action, checkNotNull(nodes[entry]).state, + checkNotNull(nodes[entry]).target) .also { n -> if (checkNotNull(nodes[entry]).expanded) n.expanded = true } } coveringEdges.forEach { checkNotNull(lut[it.key]).cover(lut[it.value]) } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt index 271417ea04..6829d577c0 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt @@ -40,10 +40,8 @@ class SafetyResultAdapter( private lateinit var argType: Type private lateinit var traceType: Type - override fun write( - writer: JsonWriter, - value: SafetyResult, Trace> - ) { + override fun write(writer: JsonWriter, + value: SafetyResult, Trace>) { initGson() writer.beginObject() writer.name("arg") @@ -82,10 +80,8 @@ class SafetyResultAdapter( return if (stats.isEmpty) if (safe == true) SafetyResult.safe(arg) else SafetyResult.unsafe(trace, arg) else - if (safe == false) SafetyResult.safe(arg, stats.get()) else SafetyResult.unsafe( - trace, - arg, stats.get() - ) + if (safe == false) SafetyResult.safe(arg, stats.get()) else SafetyResult.unsafe(trace, + arg, stats.get()) } private fun initGson() { diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt index 30031d82e0..a75f2133cb 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/StateAdapters.kt @@ -89,10 +89,8 @@ class PredStateAdapter(val gsonSupplier: () -> Gson, val scope: Scope, val env: check(reader.nextName() == "bottom") if (reader.nextBoolean()) ret = PredState.bottom() check(reader.nextName() == "preds") - val preds = gson.fromJson>>( - reader, - object : TypeToken>>() {}.type - ) + val preds = gson.fromJson>>(reader, + object : TypeToken>>() {}.type) if (ret == null) ret = PredState.of(preds) reader.endObject() return ret!! diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt index 649ec9d72c..0571800b23 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/TraceAdapter.kt @@ -26,10 +26,8 @@ import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.Trace import java.lang.reflect.Type -class TraceAdapter( - val gsonSupplier: () -> Gson, private val stateTypeSupplier: () -> Type, - private val actionType: Type -) : TypeAdapter>() { +class TraceAdapter(val gsonSupplier: () -> Gson, private val stateTypeSupplier: () -> Type, + private val actionType: Type) : TypeAdapter>() { private lateinit var gson: Gson private lateinit var stateType: Type @@ -49,15 +47,11 @@ class TraceAdapter( if (!this::stateType.isInitialized) stateType = stateTypeSupplier() reader.beginObject() check(reader.nextName() == "states") - val stateList: List = gson.fromJson( - reader, - TypeToken.getParameterized(TypeToken.get(List::class.java).type, stateType).type - ) + val stateList: List = gson.fromJson(reader, + TypeToken.getParameterized(TypeToken.get(List::class.java).type, stateType).type) check(reader.nextName() == "actions") - val actionList: List = gson.fromJson( - reader, - TypeToken.getParameterized(TypeToken.get(List::class.java).type, actionType).type - ) + val actionList: List = gson.fromJson(reader, + TypeToken.getParameterized(TypeToken.get(List::class.java).type, actionType).type) reader.endObject() return Trace.of(stateList, actionList) } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt index 2dc571788f..8e0ea55885 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/VarDeclAdapter.kt @@ -29,10 +29,8 @@ import hu.bme.mit.theta.core.decl.Decls.Var import hu.bme.mit.theta.core.decl.VarDecl import hu.bme.mit.theta.core.type.Type -class VarDeclAdapter( - val gsonSupplier: () -> Gson, val scope: MutableScope, val env: Env, - val throwIfNotInScope: Boolean = false -) : TypeAdapter>() { +class VarDeclAdapter(val gsonSupplier: () -> Gson, val scope: MutableScope, val env: Env, + val throwIfNotInScope: Boolean = false) : TypeAdapter>() { private lateinit var gson: Gson diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt index b647fb75c2..ff72c48eb5 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/ExprTest.kt @@ -91,57 +91,36 @@ class ExprTest { arrayOf(fpLit1, "(#b1 #b1010 #b101010)", emptyMap>()), arrayOf(fpLit2, "(#b0 #b1010 #b101010)", emptyMap>()), + arrayOf(ArrayLitExpr.of(listOf(), Int(2), ArrayType.of(Int(), Int())), + "(array (default 2))", emptyMap>()), + arrayOf(ArrayLitExpr.of(listOf(Tuple2.of(Int(0), Int(1))), Int(2), + ArrayType.of(Int(), Int())), "(array (0 1) (default 2))", + emptyMap>()), arrayOf( - ArrayLitExpr.of(listOf(), Int(2), ArrayType.of(Int(), Int())), - "(array (default 2))", emptyMap>() - ), - arrayOf( - ArrayLitExpr.of( - listOf(Tuple2.of(Int(0), Int(1))), Int(2), - ArrayType.of(Int(), Int()) - ), "(array (0 1) (default 2))", - emptyMap>() - ), - arrayOf( - ArrayLitExpr.of( - listOf(Tuple2.of(Int(0), Int(1)), Tuple2.of(Int(1), Int(2))), - Int(3), ArrayType.of(Int(), Int()) - ), "(array (0 1) (1 2) (default 3))", - emptyMap>() - ), + ArrayLitExpr.of(listOf(Tuple2.of(Int(0), Int(1)), Tuple2.of(Int(1), Int(2))), + Int(3), ArrayType.of(Int(), Int())), "(array (0 1) (1 2) (default 3))", + emptyMap>()), arrayOf(RefExpr.of(x), "x", mapOf(Pair(NamedSymbol("x"), x))), - arrayOf( - Ite(True(), Int(1), Int(2)), "(ite true 1 2)", - emptyMap>() - ), + arrayOf(Ite(True(), Int(1), Int(2)), "(ite true 1 2)", + emptyMap>()), arrayOf(Iff(True(), False()), "(iff true false)", emptyMap>()), arrayOf(Imply(True(), False()), "(=> true false)", emptyMap>()), - arrayOf( - Forall(listOf(p), True()), "(forall ((p Int)) true)", - mapOf(Pair(NamedSymbol("p"), p)) - ), - arrayOf( - Exists(listOf(p), True()), "(exists ((p Int)) true)", - mapOf(Pair(NamedSymbol("p"), p)) - ), + arrayOf(Forall(listOf(p), True()), "(forall ((p Int)) true)", + mapOf(Pair(NamedSymbol("p"), p))), + arrayOf(Exists(listOf(p), True()), "(exists ((p Int)) true)", + mapOf(Pair(NamedSymbol("p"), p))), - arrayOf( - Max(fpLit1, fpLit2), "(fpmax (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), - arrayOf( - Min(fpLit1, fpLit2), "(fpmin (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), + arrayOf(Max(fpLit1, fpLit2), "(fpmax (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>()), + arrayOf(Min(fpLit1, fpLit2), "(fpmin (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>()), arrayOf(Or(True(), False()), "(or true false)", emptyMap>()), arrayOf(Xor(True(), False()), "(xor true false)", emptyMap>()), - arrayOf( - And(True(), False(), False()), "(and true false false)", - emptyMap>() - ), + arrayOf(And(True(), False(), False()), "(and true false false)", + emptyMap>()), arrayOf(Not(True()), "(not true)", emptyMap>()), arrayOf(Eq(Int(1), Int(2)), "(= 1 2)", emptyMap>()), @@ -150,142 +129,80 @@ class ExprTest { arrayOf(Gt(Int(1), Int(2)), "(> 1 2)", emptyMap>()), arrayOf(Geq(Int(1), Int(2)), "(>= 1 2)", emptyMap>()), - arrayOf( - BvExprs.ULt(bvLit1, bvLit1), "(bvult #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.ULeq(bvLit1, bvLit1), "(bvule #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.UGt(bvLit1, bvLit1), "(bvugt #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.UGeq(bvLit1, bvLit1), "(bvuge #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.SLt(bvLit1, bvLit1), "(bvslt #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.SLeq(bvLit1, bvLit1), "(bvsle #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.SGt(bvLit1, bvLit1), "(bvsgt #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.SGeq(bvLit1, bvLit1), "(bvsge #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.Or(listOf(bvLit1, bvLit1)), "(bvor #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.Xor(listOf(bvLit1, bvLit1)), "(bvxor #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.And(listOf(bvLit1, bvLit1)), "(bvand #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.ShiftLeft(bvLit1, bvLit1), "(bvshl #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.ArithShiftRight(bvLit1, bvLit1), "(bvashr #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.LogicShiftRight(bvLit1, bvLit1), "(bvlshr #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.RotateLeft(bvLit1, bvLit1), "(bvrol #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.RotateRight(bvLit1, bvLit1), "(bvror #b1010 #b1010)", - emptyMap>() - ), - - arrayOf( - Add(listOf(Int(1), Int(2), Int(3))), "(+ 1 2 3)", - emptyMap>() - ), + arrayOf(BvExprs.ULt(bvLit1, bvLit1), "(bvult #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.ULeq(bvLit1, bvLit1), "(bvule #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.UGt(bvLit1, bvLit1), "(bvugt #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.UGeq(bvLit1, bvLit1), "(bvuge #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.SLt(bvLit1, bvLit1), "(bvslt #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.SLeq(bvLit1, bvLit1), "(bvsle #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.SGt(bvLit1, bvLit1), "(bvsgt #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.SGeq(bvLit1, bvLit1), "(bvsge #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.Or(listOf(bvLit1, bvLit1)), "(bvor #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.Xor(listOf(bvLit1, bvLit1)), "(bvxor #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.And(listOf(bvLit1, bvLit1)), "(bvand #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.ShiftLeft(bvLit1, bvLit1), "(bvshl #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.ArithShiftRight(bvLit1, bvLit1), "(bvashr #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.LogicShiftRight(bvLit1, bvLit1), "(bvlshr #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.RotateLeft(bvLit1, bvLit1), "(bvrol #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.RotateRight(bvLit1, bvLit1), "(bvror #b1010 #b1010)", + emptyMap>()), + + arrayOf(Add(listOf(Int(1), Int(2), Int(3))), "(+ 1 2 3)", + emptyMap>()), arrayOf(Sub(Int(1), Int(2)), "(- 1 2)", emptyMap>()), arrayOf(Add(bvLit1, bvLit1), "(bvadd #b1010 #b1010)", emptyMap>()), arrayOf(Sub(bvLit1, bvLit1), "(bvsub #b1010 #b1010)", emptyMap>()), - arrayOf( - Add(fpLit1, fpLit2), "(fpadd (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), - arrayOf( - Sub(fpLit1, fpLit2), "(fpsub (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), + arrayOf(Add(fpLit1, fpLit2), "(fpadd (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>()), + arrayOf(Sub(fpLit1, fpLit2), "(fpsub (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>()), - arrayOf( - Mul(listOf(Int(1), Int(2), Int(3))), "(* 1 2 3)", - emptyMap>() - ), + arrayOf(Mul(listOf(Int(1), Int(2), Int(3))), "(* 1 2 3)", + emptyMap>()), arrayOf(Div(Int(1), Int(2)), "(div 1 2)", emptyMap>()), arrayOf(Mod(Int(1), Int(2)), "(mod 1 2)", emptyMap>()), arrayOf(Rem(Int(1), Int(2)), "(rem 1 2)", emptyMap>()), arrayOf(Mul(bvLit1, bvLit1), "(bvmul #b1010 #b1010)", emptyMap>()), - arrayOf( - UDiv(bvLit1, bvLit1), "(bvudiv #b1010 #b1010)", - emptyMap>() - ), - arrayOf( - BvExprs.SDiv(bvLit1, bvLit2), "(bvsdiv #b1010 #b0101)", - emptyMap>() - ), - arrayOf( - BvExprs.SMod(bvLit1, bvLit2), "(bvsmod #b1010 #b0101)", - emptyMap>() - ), - arrayOf( - BvExprs.URem(bvLit1, bvLit2), "(bvurem #b1010 #b0101)", - emptyMap>() - ), - arrayOf( - BvExprs.SRem(bvLit1, bvLit2), "(bvsrem #b1010 #b0101)", - emptyMap>() - ), - arrayOf( - Mul(fpLit1, fpLit2), "(fpmul (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), - arrayOf( - FpExprs.Div(FpRoundingMode.RNE, fpLit1, fpLit2), + arrayOf(UDiv(bvLit1, bvLit1), "(bvudiv #b1010 #b1010)", + emptyMap>()), + arrayOf(BvExprs.SDiv(bvLit1, bvLit2), "(bvsdiv #b1010 #b0101)", + emptyMap>()), + arrayOf(BvExprs.SMod(bvLit1, bvLit2), "(bvsmod #b1010 #b0101)", + emptyMap>()), + arrayOf(BvExprs.URem(bvLit1, bvLit2), "(bvurem #b1010 #b0101)", + emptyMap>()), + arrayOf(BvExprs.SRem(bvLit1, bvLit2), "(bvsrem #b1010 #b0101)", + emptyMap>()), + arrayOf(Mul(fpLit1, fpLit2), "(fpmul (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", + emptyMap>()), + arrayOf(FpExprs.Div(FpRoundingMode.RNE, fpLit1, fpLit2), "(fpdiv[rne] (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), - arrayOf( - FpExprs.Rem(fpLit1, fpLit2), + emptyMap>()), + arrayOf(FpExprs.Rem(fpLit1, fpLit2), "(fprem (#b1 #b1010 #b101010) (#b0 #b1010 #b101010))", - emptyMap>() - ), + emptyMap>()), - arrayOf( - Concat(listOf(bvLit1, bvLit2)), "(++ #b1010 #b0101)", - emptyMap>() - ), - arrayOf( - ZExt(bvLit1, BvType(5)), "(bv_zero_extend #b1010 (Bv 5))", - emptyMap>() - ), - arrayOf( - SExt(bvLit1, BvType(5)), "(bv_sign_extend #b1010 (Bv 5))", - emptyMap>() - ), + arrayOf(Concat(listOf(bvLit1, bvLit2)), "(++ #b1010 #b0101)", + emptyMap>()), + arrayOf(ZExt(bvLit1, BvType(5)), "(bv_zero_extend #b1010 (Bv 5))", + emptyMap>()), + arrayOf(SExt(bvLit1, BvType(5)), "(bv_sign_extend #b1010 (Bv 5))", + emptyMap>()), arrayOf(Pos(Int(1)), "(+ 1)", emptyMap>()), arrayOf(Neg(Int(1)), "(- 1)", emptyMap>()), @@ -293,27 +210,17 @@ class ExprTest { arrayOf(Neg(bvLit1), "(bvneg #b1010)", emptyMap>()), arrayOf(Not(bvLit1), "(bvnot #b1010)", emptyMap>()), - arrayOf( - ArrayReadExpr.create( - ArrayLitExpr.of(emptyList(), Int(2), ArrayType.of(Int(), Int())), Int(5) - ), - "(read (array (default 2)) 5)", emptyMap>() - ), - arrayOf( - ArrayWriteExpr.create( - ArrayLitExpr.of( - emptyList(), Int(2), - ArrayType.of(Int(), Int()) - ), Int(5), Int(6) - ), - "(write (array (default 2)) 5 6)", emptyMap>() - ), + arrayOf(ArrayReadExpr.create( + ArrayLitExpr.of(emptyList(), Int(2), ArrayType.of(Int(), Int())), Int(5)), + "(read (array (default 2)) 5)", emptyMap>()), + arrayOf(ArrayWriteExpr.create( + ArrayLitExpr.of(emptyList(), Int(2), + ArrayType.of(Int(), Int())), Int(5), Int(6)), + "(write (array (default 2)) 5 6)", emptyMap>()), arrayOf(Prime(Int(1)), "(prime 1)", emptyMap>()), - arrayOf( - Extract(bvLit1, Int(1), Int(4)), "(extract #b1010 1 4)", - emptyMap>() - ), + arrayOf(Extract(bvLit1, Int(1), Int(4)), "(extract #b1010 1 4)", + emptyMap>()), arrayOf(Dereference(Int(0), Int(1), Int()), "(deref 0 1 Int)", emptyMap>()), ) @@ -333,8 +240,7 @@ class ExprTest { val env = Env() decls.forEach { env.define(it.key, it.value) } val expr = simplify( - ExpressionWrapper(SimpleScope(symbolTable), serialized).instantiate(env) - ) + ExpressionWrapper(SimpleScope(symbolTable), serialized).instantiate(env)) Assert.assertEquals(simplify(memory), expr) } @@ -346,8 +252,7 @@ class ExprTest { val env = Env() decls.forEach { env.define(it.key, it.value) } val expr = simplify( - ExpressionWrapper(SimpleScope(symbolTable), memory.toString()).instantiate(env) - ) + ExpressionWrapper(SimpleScope(symbolTable), memory.toString()).instantiate(env)) Assert.assertEquals(simplify(memory), expr) } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt index 2dc532876e..372e1f796e 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/StmtTest.kt @@ -53,19 +53,13 @@ class StmtTest { val addr = x.hashCode() return listOf( - arrayOf( - Assign(x, Int(1)), "(assign x 1)", - mapOf(Pair(ExprTest.NamedSymbol("x"), x)) - ), - arrayOf( - MemoryAssign(Dereference(Int(addr), Int(0), Int()), Int(1)), + arrayOf(Assign(x, Int(1)), "(assign x 1)", + mapOf(Pair(ExprTest.NamedSymbol("x"), x))), + arrayOf(MemoryAssign(Dereference(Int(addr), Int(0), Int()), Int(1)), "(memassign (deref $addr 0 Int) 1)", - mapOf(Pair(ExprTest.NamedSymbol("x"), x)) - ), - arrayOf( - Assume(Eq(x.ref, Int(1))), "(assume (= x 1))", - mapOf(Pair(ExprTest.NamedSymbol("x"), x)) - ), + mapOf(Pair(ExprTest.NamedSymbol("x"), x))), + arrayOf(Assume(Eq(x.ref, Int(1))), "(assume (= x 1))", + mapOf(Pair(ExprTest.NamedSymbol("x"), x))), arrayOf(Havoc(x), "(havoc x)", mapOf(Pair(ExprTest.NamedSymbol("x"), x))), ) } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt index 8745fef7c3..a94dfbf86d 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/dsl/TypeTest.kt @@ -52,10 +52,8 @@ class TypeTest { arrayOf(BvType(32), "(Bv 32)"), arrayOf(FpType(12, 45), "(Fp 12 45)"), - arrayOf( - Func(Int(), ArrayExprs.Array(Int(), Rat())), - "(Func Int (Array ([Int] -> Rat)))" - ), + arrayOf(Func(Int(), ArrayExprs.Array(Int(), Rat())), + "(Func Int (Array ([Int] -> Rat)))"), ) } } diff --git a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt index c4d39653a0..cb6ca93071 100644 --- a/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt +++ b/subprojects/common/grammar/src/test/java/hu/bme/mit/theta/grammar/gson/TestGson.kt @@ -101,18 +101,12 @@ class TestGson { private fun getExplBuilder(gsonSuppl: () -> Gson): GsonBuilder { val gsonBuilder = GsonBuilder() - gsonBuilder.registerTypeHierarchyAdapter( - ARG::class.java, - ArgAdapter(gsonSuppl, { ExplOrd.getInstance() }, { explArgAdapterHelper() }) - ) - gsonBuilder.registerTypeHierarchyAdapter( - Trace::class.java, - TraceAdapter(gsonSuppl, { ExplState::class.java }, SimpleStmtAction::class.java) - ) - gsonBuilder.registerTypeHierarchyAdapter( - SafetyResult::class.java, - SafetyResultAdapter(gsonSuppl, { explArgHelper() }, { explTraceHelper() }) - ) + gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, + ArgAdapter(gsonSuppl, { ExplOrd.getInstance() }, { explArgAdapterHelper() })) + gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, + TraceAdapter(gsonSuppl, { ExplState::class.java }, SimpleStmtAction::class.java)) + gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, + SafetyResultAdapter(gsonSuppl, { explArgHelper() }, { explTraceHelper() })) return gsonBuilder } @@ -120,18 +114,12 @@ class TestGson { private fun getPredBuilder(gsonSuppl: () -> Gson): GsonBuilder { val gsonBuilder = GsonBuilder() - gsonBuilder.registerTypeHierarchyAdapter( - ARG::class.java, - ArgAdapter(gsonSuppl, { PartialOrd { a, b -> true } }, { predArgAdapterHelper() }) - ) - gsonBuilder.registerTypeHierarchyAdapter( - Trace::class.java, - TraceAdapter(gsonSuppl, { PredState::class.java }, SimpleStmtAction::class.java) - ) - gsonBuilder.registerTypeHierarchyAdapter( - SafetyResult::class.java, - SafetyResultAdapter(gsonSuppl, { predArgHelper() }, { predTraceHelper() }) - ) + gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, + ArgAdapter(gsonSuppl, { PartialOrd { a, b -> true } }, { predArgAdapterHelper() })) + gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, + TraceAdapter(gsonSuppl, { PredState::class.java }, SimpleStmtAction::class.java)) + gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, + SafetyResultAdapter(gsonSuppl, { predArgHelper() }, { predTraceHelper() })) return gsonBuilder } @@ -145,10 +133,8 @@ class TestGson { val env = Env() env.define(symbol, x) - gsonBuilder.registerTypeHierarchyAdapter( - VarDecl::class.java, - VarDeclAdapter(gsonSuppl, scope, env, false) - ) + gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, + VarDeclAdapter(gsonSuppl, scope, env, false)) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -158,10 +144,8 @@ class TestGson { gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) - gsonBuilder.registerTypeHierarchyAdapter( - PredState::class.java, - PredStateAdapter(gsonSuppl, scope, env) - ) + gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, + PredStateAdapter(gsonSuppl, scope, env)) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter(gsonSuppl)) gsonBuilder.registerTypeHierarchyAdapter(Triple::class.java, TripleAdapter(gsonSuppl)) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter(gsonSuppl)) @@ -210,10 +194,8 @@ class TestGson { gson = getGson(getExplBuilder { gson }) { gson } val trace = Trace.of( - listOf( - ExplState.of(ImmutableValuation.builder().put(x, Int(1)).build()), - ExplState.of(ImmutableValuation.builder().put(x, Int(2)).build()) - ), + listOf(ExplState.of(ImmutableValuation.builder().put(x, Int(1)).build()), + ExplState.of(ImmutableValuation.builder().put(x, Int(2)).build())), listOf(SimpleStmtAction(SkipStmt.getInstance())) ) diff --git a/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt b/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt index 408190e912..ce30555dea 100644 --- a/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt +++ b/subprojects/common/multi-tests/src/test/kotlin/multi/MultiNondetDiningPhilosophersTest.kt @@ -73,28 +73,20 @@ class MultiNondetDiningPhilosophersTest { val phil3cfa = phil3rawCfa.copyWithReplacingVars(variables.associateBy { it.name }) val phil4cfa = phil4rawCfa.copyWithReplacingVars(variables.associateBy { it.name }) - val cfa1ConfigBuilder = CfaConfigBuilder( - CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance() - ) + val cfa1ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance()) cfa1ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa1ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil1cfa) - val cfa2ConfigBuilder = CfaConfigBuilder( - CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance() - ) + val cfa2ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance()) cfa2ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa2ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil2cfa) - val cfa3ConfigBuilder = CfaConfigBuilder( - CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance() - ) + val cfa3ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance()) cfa3ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa3ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil3cfa) - val cfa4ConfigBuilder = CfaConfigBuilder( - CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, - Z3LegacySolverFactory.getInstance() - ) + val cfa4ConfigBuilder = CfaConfigBuilder(CfaConfigBuilder.Domain.EXPL, CfaConfigBuilder.Refinement.SEQ_ITP, + Z3LegacySolverFactory.getInstance()) cfa4ConfigBuilder.encoding(CfaConfigBuilder.Encoding.LBE) val cfa4ExplBuilder = cfa1ConfigBuilder.ExplStrategy(phil4cfa) @@ -118,15 +110,13 @@ class MultiNondetDiningPhilosophersTest { var prop: Expr = True() variables.forEach { prop = And(prop, Eq(it.ref, True())) } val dataPredicate = ExplStatePredicate(prop, solver) - val multiConfigBuilder = StmtMultiConfigBuilder.ItpStmtMultiConfigBuilder( - totalProduct, prop, + val multiConfigBuilder = StmtMultiConfigBuilder.ItpStmtMultiConfigBuilder(totalProduct, prop, MultiStatePredicate(dataPredicate), RefToMultiPrec(cfaRefToPrec, cfaRefToPrec, ItpRefToExplPrec()), RefToMultiPrec(cfaRefToPrec, cfaRefToPrec, ItpRefToExplPrec()), ItpRefToExplPrec(), MultiPrec(cfaInitPrec, cfaInitPrec, dataInitPrec), MultiPrec(cfaInitPrec, cfaInitPrec, dataInitPrec), dataInitPrec, Z3LegacySolverFactory.getInstance(), - logger - ) + logger) val result = multiConfigBuilder.build().check() Assertions.assertTrue(result.isUnsafe) diff --git a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt index 1f8d894b79..6be63aab98 100644 --- a/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt +++ b/subprojects/frontends/c-frontend/src/main/java/hu/bme/mit/theta/frontend/CStatistics.kt @@ -50,10 +50,8 @@ fun CProgram.getStatistics(): CStatistics { fun CFunction.collectStatistics(): Triple { val statisticsCollectorVisitor = StatisticsCollectorVisitor() this.compound?.accept(statisticsCollectorVisitor, Unit) - return Triple( - statisticsCollectorVisitor.loopNumber, statisticsCollectorVisitor.deepestLoop, - statisticsCollectorVisitor.linear - ) + return Triple(statisticsCollectorVisitor.loopNumber, statisticsCollectorVisitor.deepestLoop, + statisticsCollectorVisitor.linear) } fun Expr<*>.isNonLinear(): Boolean { diff --git a/subprojects/frontends/llvm/build.gradle.kts b/subprojects/frontends/llvm/build.gradle.kts index 812b35248b..2d93c23af0 100644 --- a/subprojects/frontends/llvm/build.gradle.kts +++ b/subprojects/frontends/llvm/build.gradle.kts @@ -104,10 +104,8 @@ fun llvmConfigFlags(vararg args: String): Array { fun jniConfigFlags(): Array { if (!taskEnabled) return arrayOf() - val jdkHomeArr = runCommandForOutput( - "bash", "-c", - "dirname \$(cd \$(dirname \$(readlink -f \$(which javac) || which javac)); pwd -P)" - ) + val jdkHomeArr = runCommandForOutput("bash", "-c", + "dirname \$(cd \$(dirname \$(readlink -f \$(which javac) || which javac)); pwd -P)") check(jdkHomeArr.size == 1) val jdkHome = File(jdkHomeArr[0]) check(jdkHome.exists()) @@ -122,14 +120,11 @@ fun jniConfigFlags(): Array { library { targetMachines.add(machines.linux.x86_64) tasks.withType(CppCompile::class) { - compilerArgs.addAll( - listOf( - "-Wall", - "-fpic", - *jniConfigFlags(), - *llvmConfigFlags("--cxxflags") - ) - ) + compilerArgs.addAll(listOf( + "-Wall", + "-fpic", + *jniConfigFlags(), + *llvmConfigFlags("--cxxflags"))) if (!taskEnabled) { println("CppCompile is enabled: $taskEnabled") enabled = false @@ -137,13 +132,10 @@ library { } tasks.withType(LinkSharedLibrary::class) { - linkerArgs.addAll( - listOf( - "-rdynamic", - *llvmConfigFlags("--cxxflags", "--ldflags", "--libs", "core", "bitreader"), - "-ldl" - ) - ) + linkerArgs.addAll(listOf( + "-rdynamic", + *llvmConfigFlags("--cxxflags", "--ldflags", "--libs", "core", "bitreader"), + "-ldl")) if (!taskEnabled) { println("LinkSharedLibrary is enabled: $taskEnabled") enabled = false diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt index 1869904e1e..facf177953 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/DefaultGraphPatternCompiler.kt @@ -110,10 +110,8 @@ abstract class DefaultGraphPatternCompiler : GraphPatternCompiler { override fun compile(pattern: BasicEventSet): T? = null override fun compile(pattern: BasicRelation): T? = null - override fun getCompleteGraph( - mcm: Set, - model: Valuation - ): Pair, Map, ThreeVL>> { + override fun getCompleteGraph(mcm: Set, + model: Valuation): Pair, Map, ThreeVL>> { error("Not implemented") } } \ No newline at end of file diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt index fa24ce82cc..0490c9f006 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/GraphPatternCompiler.kt @@ -59,8 +59,6 @@ interface GraphPatternCompiler { fun compile(pattern: UnionNode): T2 fun compile(pattern: BasicEventSet): T2 fun compile(pattern: BasicRelation): T2 - fun getCompleteGraph( - namedPatterns: Set, - model: Valuation - ): Pair, Map, ThreeVL>> + fun getCompleteGraph(namedPatterns: Set, + model: Valuation): Pair, Map, ThreeVL>> } \ No newline at end of file diff --git a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt index d6355f1d95..4102e138ff 100644 --- a/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt +++ b/subprojects/solver/graph-solver/src/main/java/hu/bme/mit/theta/graphsolver/compilers/pattern2expr/Pattern2ExprCompiler.kt @@ -48,10 +48,8 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map, - model: Valuation - ): Pair, Map, ThreeVL>> { + override fun getCompleteGraph(namedPatterns: Set, + model: Valuation): Pair, Map, ThreeVL>> { val ret = LinkedHashMap, ThreeVL>() ret.putAll(facts) ret.putAll(namedLookup.map { n -> @@ -202,8 +200,7 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map val const = if (pattern.patternName != null) { val const = namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] ?: Const( - "RTC_" + uuid + "_" + a + "_" + b, Bool() - ) + "RTC_" + uuid + "_" + a + "_" + b, Bool()) namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] = const const } else { @@ -266,8 +263,7 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map val const = if (pattern.patternName != null) { val const = namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] ?: Const( - "TC_" + uuid + "_" + a + "_" + b, Bool() - ) + "TC_" + uuid + "_" + a + "_" + b, Bool()) namedLookup[Pair(pattern.patternName!!, Tuple2.of(a, b))] = const const } else { @@ -318,8 +314,7 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map> { return events.associate { a -> - Pair( - Tuple1.of(a), + Pair(Tuple1.of(a), when (facts[Pair(pattern.name, Tuple1.of(a))]) { ThreeVL.FALSE -> False() ThreeVL.TRUE -> True() @@ -328,16 +323,14 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map> { return events.map { a -> events.map { b -> - Pair( - Tuple2.of(a, b), + Pair(Tuple2.of(a, b), when (facts[Pair(pattern.name, Tuple2.of(a, b))]) { ThreeVL.FALSE -> False() ThreeVL.TRUE -> True() @@ -346,8 +339,7 @@ class Pattern2ExprCompiler : GraphPatternCompiler, Map { companion object { - private val smallLine: Pair, Map, ThreeVL>> = Pair( - listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), - ) - ) + private val smallLine: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), + )) - private val smallCycle: Pair, Map, ThreeVL>> = Pair( - listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), - ) - ) + private val smallCycle: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.FALSE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.FALSE), + )) - private val smallFull: Pair, Map, ThreeVL>> = Pair( - listOf(1, 2, 3), mapOf( - Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.TRUE), - Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.TRUE), - Pair(Pair("W", Tuple1.of(1)), ThreeVL.TRUE), - Pair(Pair("R", Tuple1.of(2)), ThreeVL.TRUE), - Pair(Pair("F", Tuple1.of(3)), ThreeVL.TRUE), - ) - ) + private val smallFull: Pair, Map, ThreeVL>> = Pair(listOf(1, 2, 3), mapOf( + Pair(Pair("po", Tuple2.of(1, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(1, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(2, 3)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 1)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 2)), ThreeVL.TRUE), + Pair(Pair("po", Tuple2.of(3, 3)), ThreeVL.TRUE), + Pair(Pair("W", Tuple1.of(1)), ThreeVL.TRUE), + Pair(Pair("R", Tuple1.of(2)), ThreeVL.TRUE), + Pair(Pair("F", Tuple1.of(3)), ThreeVL.TRUE), + )) @Parameterized.Parameters @JvmStatic @@ -108,8 +102,7 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -118,8 +111,7 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -128,8 +120,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -138,8 +129,7 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -148,8 +138,7 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -158,8 +147,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -168,8 +156,7 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -178,8 +165,7 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -188,8 +174,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -198,8 +183,7 @@ class GraphSolverTest { smallLine.first, smallLine.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -208,8 +192,7 @@ class GraphSolverTest { smallCycle.first, smallCycle.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -218,8 +201,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -228,8 +210,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -238,8 +219,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), arrayOf( @@ -248,8 +228,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -258,8 +237,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -268,8 +246,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -278,8 +255,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -288,8 +264,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -298,8 +273,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -308,8 +282,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -318,8 +291,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -328,8 +300,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -338,8 +309,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -348,8 +318,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -358,8 +327,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -368,8 +336,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), true ), arrayOf( @@ -378,8 +345,7 @@ class GraphSolverTest { smallFull.first, smallFull.second, SATGraphSolver( - Z3LegacySolverFactory.getInstance().createSolver() - ), + Z3LegacySolverFactory.getInstance().createSolver()), false ), ) diff --git a/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt b/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt index e1c2533a6d..9383d479b8 100644 --- a/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt +++ b/subprojects/solver/solver-smtlib/src/test/java/hu/bme/mit/theta/solver/smtlib/GenericSmtLibHornSolverTest.kt @@ -126,11 +126,8 @@ class GenericSmtLibHornSolverTest { App( App( model.get(init.constDecl) as FuncLitExpr>, - p0.ref - ), - p1.ref - ) - ) + p0.ref), + p1.ref)) checkerSolver.add(Lt(p1.ref, Int(0))) Assertions.assertTrue(checkerSolver.check().isUnsat) diff --git a/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt b/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt index eafd44ec12..859165d9cf 100644 --- a/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt +++ b/subprojects/solver/solver-z3/src/test/java/hu/bme/mit/theta/solver/z3/Z3HornSolverTest.kt @@ -85,11 +85,8 @@ class Z3HornSolverTest { App( App( model.get(init.constDecl) as FuncLitExpr>, - p0.ref - ), - p1.ref - ) - ) + p0.ref), + p1.ref)) checkerSolver.add(Lt(p1.ref, Int(0))) Assertions.assertTrue(checkerSolver.check().isUnsat) diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt index a015c6ce1d..d82a92fa4a 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/FrontendXcfaBuilder.kt @@ -54,20 +54,16 @@ import org.abego.treelayout.internal.util.Contract.checkState import java.math.BigInteger import java.util.stream.Collectors -class FrontendXcfaBuilder( - val parseContext: ParseContext, val checkOverflow: Boolean = false, - val uniqueWarningLogger: Logger -) : +class FrontendXcfaBuilder(val parseContext: ParseContext, val checkOverflow: Boolean = false, + val uniqueWarningLogger: Logger) : CStatementVisitorBase() { private val locationLut: MutableMap = LinkedHashMap() private var ptrCnt = 1 // counts up, uses 3k+1 get() = field.also { field += 3 } - private fun getLoc( - builder: XcfaProcedureBuilder, name: String?, - metadata: MetaData - ): XcfaLocation { + private fun getLoc(builder: XcfaProcedureBuilder, name: String?, + metadata: MetaData): XcfaLocation { if (name == null) return getAnonymousLoc(builder, metadata = metadata) locationLut.putIfAbsent(name, XcfaLocation(name, metadata = metadata)) val location = locationLut[name] @@ -104,64 +100,40 @@ class FrontendXcfaBuilder( } builder.addVar(XcfaGlobalVar(globalDeclaration.get2(), type.nullValue)) if (type is CArray) { - initStmtList.add( - StmtLabel( - Stmts.Assign( - cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type) - ) - ) - ) + initStmtList.add(StmtLabel( + Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.getValue("$ptrCnt"), globalDeclaration.get2().type)) + )) } else { if (globalDeclaration.get1().initExpr != null && globalDeclaration.get1().initExpr.expression !is UnsupportedInitializer) { - initStmtList.add( - StmtLabel( - Stmts.Assign( - cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast( - type.castTo(globalDeclaration.get1().initExpr.expression), - globalDeclaration.get2().type - ) - ) - ) - ) + initStmtList.add(StmtLabel( + Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.castTo(globalDeclaration.get1().initExpr.expression), + globalDeclaration.get2().type)) + )) } else { - initStmtList.add( - StmtLabel( - Stmts.Assign( - cast(globalDeclaration.get2(), globalDeclaration.get2().type), - cast(type.nullValue, globalDeclaration.get2().type) - ) - ) - ) + initStmtList.add(StmtLabel( + Stmts.Assign(cast(globalDeclaration.get2(), globalDeclaration.get2().type), + cast(type.nullValue, globalDeclaration.get2().type)) + )) } } if (globalDeclaration.get1().arrayDimensions.size == 1) { - val bounds = ExprUtils.simplify( - CComplexType.getUnsignedLong(parseContext) - .castTo(globalDeclaration.get1().arrayDimensions[0].expression) - ) - checkState( - bounds is IntLitExpr || bounds is BvLitExpr, - "Only IntLit and BvLit expression expected here." - ) - val literalValue = - if (bounds is IntLitExpr) bounds.value.toLong() else BvUtils.neutralBvLitExprToBigInteger( - bounds as BvLitExpr - ).toLong() + val bounds = ExprUtils.simplify(CComplexType.getUnsignedLong(parseContext) + .castTo(globalDeclaration.get1().arrayDimensions[0].expression)) + checkState(bounds is IntLitExpr || bounds is BvLitExpr, + "Only IntLit and BvLit expression expected here.") + val literalValue = if (bounds is IntLitExpr) bounds.value.toLong() else BvUtils.neutralBvLitExprToBigInteger( + bounds as BvLitExpr).toLong() val literalToExpr = { x: Long -> if (bounds is IntLitExpr) IntLitExpr.of( - BigInteger.valueOf(x) - ) else BvUtils.bigIntegerToNeutralBvLitExpr( - BigInteger.valueOf(x), - (bounds as BvLitExpr).type.size - ) + BigInteger.valueOf(x)) else BvUtils.bigIntegerToNeutralBvLitExpr(BigInteger.valueOf(x), + (bounds as BvLitExpr).type.size) } - val initExprs: Map> = - (globalDeclaration.get1()?.initExpr as? CInitializerList)?.statements?.mapIndexed { i, it -> - Pair(i, it.get2().expression) - }?.toMap() ?: emptyMap() + val initExprs: Map> = (globalDeclaration.get1()?.initExpr as? CInitializerList)?.statements?.mapIndexed { i, it -> + Pair(i, it.get2().expression) + }?.toMap() ?: emptyMap() for (i in 0 until literalValue) { checkState(globalDeclaration.get1().actualType is CArray, "Only arrays are expected here") val embeddedType = (globalDeclaration.get1().actualType as CArray).embeddedType @@ -183,10 +155,8 @@ class FrontendXcfaBuilder( return builder } - private fun handleFunction( - function: CFunction, param: List, - xcfaBuilder: XcfaBuilder - ): XcfaProcedureBuilder { + private fun handleFunction(function: CFunction, param: List, + xcfaBuilder: XcfaBuilder): XcfaProcedureBuilder { locationLut.clear() val flatVariables = function.flatVariables val funcDecl = function.funcDecl @@ -213,8 +183,7 @@ class FrontendXcfaBuilder( for (functionParam in funcDecl.functionParams) { Preconditions.checkState( functionParam.actualType is CVoid || functionParam.varDecls.size > 0, - "Function param should have an associated variable!" - ) + "Function param should have an associated variable!") for (varDecl in functionParam.varDecls) { if (varDecl != null) builder.addParam(varDecl, ParamDirection.IN) } @@ -224,14 +193,10 @@ class FrontendXcfaBuilder( builder.addVar(flatVariable) val type = CComplexType.getType(flatVariable.ref, parseContext) if ((type is CArray || type is CStruct) && builder.getParams().none { it.first == flatVariable }) { - initStmtList.add( - StmtLabel( - Stmts.Assign( - cast(flatVariable, flatVariable.type), - cast(type.getValue("$ptrCnt"), flatVariable.type) - ) - ) - ) + initStmtList.add(StmtLabel( + Stmts.Assign(cast(flatVariable, flatVariable.type), + cast(type.getValue("$ptrCnt"), flatVariable.type)) + )) } } builder.createInitLoc(getMetadata(function)) @@ -247,10 +212,8 @@ class FrontendXcfaBuilder( val endinit = getAnonymousLoc(builder, getMetadata(function)) builder.addLoc(endinit) - val initEdge = XcfaEdge( - init, endinit, SequenceLabel(initStmtList), - metadata = getMetadata(function) - ) + val initEdge = XcfaEdge(init, endinit, SequenceLabel(initStmtList), + metadata = getMetadata(function)) builder.addEdge(initEdge) init = endinit builder.createFinalLoc(getMetadata(function)) @@ -294,13 +257,10 @@ class FrontendXcfaBuilder( } is RefExpr<*> -> { - StmtLabel( - Stmts.Assign( - cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), - cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type) - ), - metadata = getMetadata(statement) - ) + StmtLabel(Stmts.Assign( + cast(lValue.decl as VarDecl<*>, (lValue.decl as VarDecl<*>).type), + cast(CComplexType.getType(lValue, parseContext).castTo(rExpression), lValue.type)), + metadata = getMetadata(statement)) } else -> { @@ -321,23 +281,17 @@ class FrontendXcfaBuilder( xcfaEdge = XcfaEdge(initLoc, middleLoc1, label, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge( - middleLoc1, location, + xcfaEdge = XcfaEdge(middleLoc1, location, StmtLabel(type.limit(lhs.ref), metadata = getMetadata(statement)), - metadata = getMetadata(statement) - ) + metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge( - middleLoc1, middleLoc2, + xcfaEdge = XcfaEdge(middleLoc1, middleLoc2, StmtLabel(Assume(Not(type.limit(lhs.ref).cond)), metadata = getMetadata(statement)), - metadata = getMetadata(statement) - ) + metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - xcfaEdge = XcfaEdge( - middleLoc2, location, + xcfaEdge = XcfaEdge(middleLoc2, location, InvokeLabel("overflow", listOf(), metadata = getMetadata(statement)), - metadata = getMetadata(statement) - ) + metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } return location @@ -355,13 +309,11 @@ class FrontendXcfaBuilder( builder.addEdge(xcfaEdge) val location = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(location) - xcfaEdge = XcfaEdge( - initLoc, location, StmtLabel( - statement.assumeStmt, - choiceType = ChoiceType.MAIN_PATH, - metadata = getMetadata(statement) - ), metadata = getMetadata(statement) - ) + xcfaEdge = XcfaEdge(initLoc, location, StmtLabel( + statement.assumeStmt, + choiceType = ChoiceType.MAIN_PATH, + metadata = getMetadata(statement) + ), metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) return location } @@ -378,10 +330,8 @@ class FrontendXcfaBuilder( builder.addEdge(edge) check(breakLoc != null) edge = XcfaEdge(initLoc, breakLoc, metadata = getMetadata(statement)) - val unreachableLoc = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), - metadata = getMetadata(statement) - ) + val unreachableLoc = XcfaLocation("Unreachable" + XcfaLocation.uniqueCounter(), + metadata = getMetadata(statement)) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -405,10 +355,8 @@ class FrontendXcfaBuilder( builder.addVar(ret) params.add(ret.ref) for (cStatement in myParams) { - initLoc = cStatement.accept( - this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) - ) + initLoc = cStatement.accept(this, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) } params.addAll(myParams.stream().map { obj: CStatement -> obj.expression } .collect(Collectors.toList())) @@ -440,20 +388,14 @@ class FrontendXcfaBuilder( val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + if (preStatements != null) lastLoc = preStatements.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) for (cStatement in statement.getcStatementList()) { - if (cStatement != null) lastLoc = cStatement.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + if (cStatement != null) lastLoc = cStatement.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } - if (postStatements != null) lastLoc = postStatements.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + if (postStatements != null) lastLoc = postStatements.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) return lastLoc } @@ -470,8 +412,7 @@ class FrontendXcfaBuilder( check(continueLoc != null) edge = XcfaEdge(initLoc, continueLoc, metadata = getMetadata(statement)) val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement) - ) + "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -506,40 +447,26 @@ class FrontendXcfaBuilder( builder.addLoc(initLoc) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastBody = body.accept( - this, - ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc) - ) + val lastBody = body.accept(this, + ParamPack(builder, initLoc, endLoc, innerEndLoc, returnLoc)) xcfaEdge = XcfaEdge(lastBody, innerEndLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastPre = buildWithoutPostStatement( - guard, - ParamPack(builder, innerEndLoc, null, null, returnLoc) - ) - val assume = StmtLabel( - Stmts.Assume( - AbstractExprs.Neq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue) - ), - choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) - ) + val lastPre = buildWithoutPostStatement(guard, + ParamPack(builder, innerEndLoc, null, null, returnLoc)) + val assume = StmtLabel(Stmts.Assume( + AbstractExprs.Neq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), + choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard)) xcfaEdge = XcfaEdge(lastPre, innerInnerGuard, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val assume1 = StmtLabel( - Stmts.Assume( - AbstractExprs.Eq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue) - ), - choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard) - ) + val assume1 = StmtLabel(Stmts.Assume( + AbstractExprs.Eq(guard.expression, CComplexType.getType(guard.expression, parseContext).nullValue)), + choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard)) xcfaEdge = XcfaEdge(lastPre, outerInnerGuard, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val outerLastGuard = buildPostStatement( - guard, - ParamPack(builder, outerInnerGuard, null, null, null) - ) - val innerLastGuard = buildPostStatement( - guard, - ParamPack(builder, innerInnerGuard, null, null, null) - ) + val outerLastGuard = buildPostStatement(guard, + ParamPack(builder, outerInnerGuard, null, null, null)) + val innerLastGuard = buildPostStatement(guard, + ParamPack(builder, innerInnerGuard, null, null, null)) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) xcfaEdge = XcfaEdge(innerLastGuard, initLoc, metadata = getMetadata(statement)) @@ -578,21 +505,13 @@ class FrontendXcfaBuilder( builder.addLoc(startIncrement) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastInit = if (init == null) initLoc else init.accept( - this, - ParamPack(builder, initLoc, null, null, returnLoc) - ) - val lastTest = if (guard == null) lastInit else buildWithoutPostStatement( - guard, - ParamPack(builder, lastInit!!, null, null, returnLoc) - ) + val lastInit = if (init == null) initLoc else init.accept(this, + ParamPack(builder, initLoc, null, null, returnLoc)) + val lastTest = if (guard == null) lastInit else buildWithoutPostStatement(guard, + ParamPack(builder, lastInit!!, null, null, returnLoc)) val assume = StmtLabel( - Stmts.Assume( - if (guard == null) True() else AbstractExprs.Neq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(if (guard == null) True() else AbstractExprs.Neq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.MAIN_PATH, metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) ) @@ -600,42 +519,30 @@ class FrontendXcfaBuilder( xcfaEdge = XcfaEdge(lastTest, endInit, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume( - if (guard == null) False() else AbstractExprs.Eq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(if (guard == null) False() else AbstractExprs.Eq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = if (guard == null) getMetadata(statement) else getMetadata(guard) ) xcfaEdge = XcfaEdge(lastTest, outerLastTest, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val innerLastGuard = if (guard == null) endInit else buildPostStatement( - guard, - ParamPack(builder, endInit, endLoc, startIncrement, returnLoc) - ) - val lastBody = if (body == null) innerLastGuard else body.accept( - this, - ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc) - ) + val innerLastGuard = if (guard == null) endInit else buildPostStatement(guard, + ParamPack(builder, endInit, endLoc, startIncrement, returnLoc)) + val lastBody = if (body == null) innerLastGuard else body.accept(this, + ParamPack(builder, innerLastGuard, endLoc, startIncrement, returnLoc)) xcfaEdge = XcfaEdge(lastBody, startIncrement, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) if (increment != null) { - val lastIncrement = increment.accept( - this, - ParamPack(builder, startIncrement, null, null, returnLoc) - ) + val lastIncrement = increment.accept(this, + ParamPack(builder, startIncrement, null, null, returnLoc)) xcfaEdge = XcfaEdge(lastIncrement, lastInit, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else { xcfaEdge = XcfaEdge(startIncrement, lastInit, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - val outerLastGuard = if (guard == null) outerLastTest else buildPostStatement( - guard, - ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc) - ) + val outerLastGuard = if (guard == null) outerLastTest else buildPostStatement(guard, + ParamPack(builder, outerLastTest, endLoc, startIncrement, returnLoc)) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) return endLoc @@ -651,14 +558,11 @@ class FrontendXcfaBuilder( builder.addLoc(initLoc) var edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) - edge = XcfaEdge( - initLoc, - getLoc(builder, statement.label, metadata = getMetadata(statement)) - ) + edge = XcfaEdge(initLoc, + getLoc(builder, statement.label, metadata = getMetadata(statement))) builder.addLoc(getLoc(builder, statement.label, metadata = getMetadata(statement))) val unreachableLoc: XcfaLocation = XcfaLocation( - "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement) - ) + "Unreachable" + XcfaLocation.uniqueCounter(), metadata = getMetadata(statement)) builder.addLoc(unreachableLoc) builder.addEdge(edge) return unreachableLoc @@ -683,51 +587,33 @@ class FrontendXcfaBuilder( builder.addLoc(initLoc) var xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val endGuard = buildWithoutPostStatement( - guard, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) - ) + val endGuard = buildWithoutPostStatement(guard, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) val assume = StmtLabel( - Stmts.Assume( - AbstractExprs.Neq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(AbstractExprs.Neq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(endGuard, mainBranch, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume( - AbstractExprs.Eq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(AbstractExprs.Eq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(endGuard, elseBranch, assume1, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val mainAfterGuard = buildPostStatement( - guard, - ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc) - ) - val mainEnd = body.accept( - this, - ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc) - ) + val mainAfterGuard = buildPostStatement(guard, + ParamPack(builder, mainBranch, breakLoc, continueLoc, returnLoc)) + val mainEnd = body.accept(this, + ParamPack(builder, mainAfterGuard, breakLoc, continueLoc, returnLoc)) if (elseStatement != null) { - val elseAfterGuard = buildPostStatement( - guard, - ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc) - ) - val elseEnd = elseStatement.accept( - this, - ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc) - ) + val elseAfterGuard = buildPostStatement(guard, + ParamPack(builder, elseBranch, breakLoc, continueLoc, returnLoc)) + val elseEnd = elseStatement.accept(this, + ParamPack(builder, elseAfterGuard, breakLoc, continueLoc, returnLoc)) xcfaEdge = XcfaEdge(elseEnd, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else { @@ -763,24 +649,16 @@ class FrontendXcfaBuilder( builder.addLoc(initLoc) val xcfaEdge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val endExpr = expr?.accept( - this, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) - ) ?: initLoc + val endExpr = expr?.accept(this, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) ?: initLoc val endLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(endLoc) val key: VarDecl<*> = builder.getParams()[0].first check(returnLoc != null) val type = CComplexType.getType(key.ref, parseContext) - val edge = XcfaEdge( - endExpr, returnLoc, StmtLabel( - Stmts.Assign( - cast(key, key.type), - cast(type.castTo(expr?.expression ?: type.nullValue), key.type) - ), - metadata = getMetadata(statement) - ), metadata = getMetadata(statement) - ) + val edge = XcfaEdge(endExpr, returnLoc, StmtLabel(Stmts.Assign(cast(key, key.type), + cast(type.castTo(expr?.expression ?: type.nullValue), key.type)), + metadata = getMetadata(statement)), metadata = getMetadata(statement)) builder.addEdge(edge) return endLoc } @@ -799,18 +677,14 @@ class FrontendXcfaBuilder( builder.addLoc(endLoc) val edge: XcfaEdge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) - val endInit = buildWithoutPostStatement( - testValue, - ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc) - ) + val endInit = buildWithoutPostStatement(testValue, + ParamPack(builder, initLoc, breakLoc, continueLoc, returnLoc)) Preconditions.checkState(body is CCompound, "Switch body has to be a CompoundStatement!") var defaultExpr: Expr? = True() for (cStatement in (body as CCompound).getcStatementList()) { if (cStatement is CCase) { - defaultExpr = BoolExprs.And( - defaultExpr, - AbstractExprs.Neq(testValue.expression, cStatement.expr.expression) - ) + defaultExpr = BoolExprs.And(defaultExpr, + AbstractExprs.Neq(testValue.expression, cStatement.expr.expression)) } } var lastLocation: XcfaLocation? = null @@ -823,24 +697,19 @@ class FrontendXcfaBuilder( builder.addEdge(xcfaEdge) } if (cStatement is CCase) { - val afterGuard = buildPostStatement( - testValue, - ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc) - ) + val afterGuard = buildPostStatement(testValue, + ParamPack(builder, checkNotNull(endInit), breakLoc, continueLoc, returnLoc)) val assume = StmtLabel( Stmts.Assume( - AbstractExprs.Eq(testValue.expression, cStatement.expr.expression) - ), + AbstractExprs.Eq(testValue.expression, cStatement.expr.expression)), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(testValue) ) xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } else if (cStatement is CDefault) { - val afterGuard = buildPostStatement( - testValue, - ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc) - ) + val afterGuard = buildPostStatement(testValue, + ParamPack(builder, endInit!!, breakLoc, continueLoc, returnLoc)) val assume = StmtLabel( Stmts.Assume(defaultExpr), choiceType = ChoiceType.MAIN_PATH, // TODO: is this what validators expect? @@ -849,16 +718,12 @@ class FrontendXcfaBuilder( xcfaEdge = XcfaEdge(afterGuard, location, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - lastLocation = cStatement.accept( - this, - ParamPack(builder, location, endLoc, continueLoc, returnLoc) - ) + lastLocation = cStatement.accept(this, + ParamPack(builder, location, endLoc, continueLoc, returnLoc)) } if (lastLocation != null) { - val xcfaEdge: XcfaEdge = XcfaEdge( - lastLocation, endLoc, - metadata = getMetadata(statement) - ) + val xcfaEdge: XcfaEdge = XcfaEdge(lastLocation, endLoc, + metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } return endLoc @@ -884,66 +749,46 @@ class FrontendXcfaBuilder( for (i in 0 until if (UNROLL_COUNT == 0) 1 else UNROLL_COUNT) { val innerLoop = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(innerLoop) - val testEndLoc = buildWithoutPostStatement( - guard, - ParamPack(builder, initLoc, null, null, returnLoc) - ) + val testEndLoc = buildWithoutPostStatement(guard, + ParamPack(builder, initLoc, null, null, returnLoc)) if (UNROLL_COUNT > 0) { initLoc = getAnonymousLoc(builder, metadata = getMetadata(statement)) builder.addLoc(initLoc) } val assume = StmtLabel( - Stmts.Assume( - AbstractExprs.Neq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(AbstractExprs.Neq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.MAIN_PATH, metadata = getMetadata(guard) ) xcfaEdge = XcfaEdge(testEndLoc, innerLoop, assume, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) val assume1 = StmtLabel( - Stmts.Assume( - AbstractExprs.Eq( - guard.expression, - CComplexType.getType(guard.expression, parseContext).nullValue - ) - ), + Stmts.Assume(AbstractExprs.Eq(guard.expression, + CComplexType.getType(guard.expression, parseContext).nullValue)), choiceType = ChoiceType.ALTERNATIVE_PATH, metadata = getMetadata(statement) ) - xcfaEdge = XcfaEdge( - testEndLoc, outerBeforeGuard, assume1, - metadata = getMetadata(statement) - ) + xcfaEdge = XcfaEdge(testEndLoc, outerBeforeGuard, assume1, + metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) - val lastGuard = buildPostStatement( - guard, - ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc) - ) - val lastBody = body.accept( - this, - ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc) - ) + val lastGuard = buildPostStatement(guard, + ParamPack(builder, innerLoop, endLoc, initLoc, returnLoc)) + val lastBody = body.accept(this, + ParamPack(builder, lastGuard, endLoc, initLoc, returnLoc)) xcfaEdge = XcfaEdge(lastBody, initLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) } - val outerLastGuard = buildPostStatement( - guard, - ParamPack(builder, outerBeforeGuard, null, null, null) - ) + val outerLastGuard = buildPostStatement(guard, + ParamPack(builder, outerBeforeGuard, null, null, null)) xcfaEdge = XcfaEdge(outerLastGuard, endLoc, metadata = getMetadata(statement)) builder.addEdge(xcfaEdge) return endLoc } private fun buildWithoutPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState( - cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!" - ) + Preconditions.checkState(cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!") val statement = cStatement as CCompound val builder: XcfaProcedureBuilder = param.builder var lastLoc = param.lastLoc @@ -958,38 +803,28 @@ class FrontendXcfaBuilder( val edge = XcfaEdge(lastLoc, initLoc, metadata = getMetadata(statement)) builder.addEdge(edge) lastLoc = initLoc - if (preStatements != null) lastLoc = preStatements.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + if (preStatements != null) lastLoc = preStatements.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) for (i in 0 until cStatementList.size - 1) { val stmt = cStatementList[i] - if (stmt != null) lastLoc = stmt.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + if (stmt != null) lastLoc = stmt.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } if (cStatementList.size == 0) return lastLoc val lastStatement = cStatementList[cStatementList.size - 1] lastLoc = if (postStatements == null) { - buildWithoutPostStatement( - lastStatement, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + buildWithoutPostStatement(lastStatement, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } else { - lastStatement.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + lastStatement.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) } return lastLoc } private fun buildPostStatement(cStatement: CStatement, param: ParamPack): XcfaLocation { - Preconditions.checkState( - cStatement is CCompound, - "Currently only CCompounds have pre- and post statements!" - ) + Preconditions.checkState(cStatement is CCompound, + "Currently only CCompounds have pre- and post statements!") val statement = cStatement as CCompound val builder: XcfaProcedureBuilder = param.builder var lastLoc = param.lastLoc @@ -999,20 +834,15 @@ class FrontendXcfaBuilder( val preStatements = statement.preStatements val postStatements = statement.postStatements val cStatementList = statement.getcStatementList() - lastLoc = if (postStatements != null) postStatements.accept( - this, - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) else buildPostStatement( + lastLoc = if (postStatements != null) postStatements.accept(this, + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) else buildPostStatement( cStatementList[cStatementList.size - 1], - ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc) - ) + ParamPack(builder, lastLoc, breakLoc, continueLoc, returnLoc)) return lastLoc } - class ParamPack( - builder: XcfaProcedureBuilder, lastLoc: XcfaLocation, breakLoc: XcfaLocation?, - continueLoc: XcfaLocation?, returnLoc: XcfaLocation? - ) { + class ParamPack(builder: XcfaProcedureBuilder, lastLoc: XcfaLocation, breakLoc: XcfaLocation?, + continueLoc: XcfaLocation?, returnLoc: XcfaLocation?) { val builder: XcfaProcedureBuilder val lastLoc: XcfaLocation diff --git a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt index d1faac52da..40d06bd9c1 100644 --- a/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt +++ b/subprojects/xcfa/c2xcfa/src/main/java/hu/bme/mit/theta/c2xcfa/Utils.kt @@ -30,10 +30,8 @@ import org.antlr.v4.runtime.CharStreams import org.antlr.v4.runtime.CommonTokenStream import java.io.InputStream -fun getXcfaFromC( - stream: InputStream, parseContext: ParseContext, collectStatistics: Boolean, - checkOverflow: Boolean, warningLogger: Logger -): Triple?> { +fun getXcfaFromC(stream: InputStream, parseContext: ParseContext, collectStatistics: Boolean, + checkOverflow: Boolean, warningLogger: Logger): Triple?> { val input = CharStreams.fromStream(stream) val lexer = CLexer(input) val tokens = CommonTokenStream(lexer) diff --git a/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt b/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt index 861ba376b5..6fc85e623d 100644 --- a/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt +++ b/subprojects/xcfa/cat/src/main/java/hu/bme/mit/theta/cat/dsl/CatVisitor.kt @@ -238,8 +238,7 @@ class CatVisitor(file: File) : CatBaseVisitor() { override fun visitExprComplement(ctx: ExprComplementContext): GraphPattern { val rel = ctx.e.accept(this) return if (rel is EdgePattern) Complement(rel) else if (rel is NodePattern) ComplementNode(rel) else error( - "Mismatched types" - ) + "Mismatched types") } override fun visitExprInverse(ctx: ExprInverseContext): GraphPattern { diff --git a/subprojects/xcfa/llvm2xcfa/build.gradle.kts b/subprojects/xcfa/llvm2xcfa/build.gradle.kts index 874d563124..1888b50a11 100644 --- a/subprojects/xcfa/llvm2xcfa/build.gradle.kts +++ b/subprojects/xcfa/llvm2xcfa/build.gradle.kts @@ -36,9 +36,7 @@ tasks.test { } val linkTask = task.first() dependsOn(linkTask) - systemProperty( - "java.library.path", - linkTask.linkedFile.get().asFile.parent + ":/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib" - ) + systemProperty("java.library.path", + linkTask.linkedFile.get().asFile.parent + ":/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib") } } diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt index 4f9bbd7bee..cf5d298dab 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/Utils.kt @@ -52,8 +52,7 @@ private fun S.getState(varLookup: Map, VarDecl<*>>): is PredState -> PredState.of(preds.map { p -> p.changeVars(varLookup) }) is PtrState<*> -> PtrState(innerState.getState(varLookup)) else -> throw NotImplementedError( - "Generalizing variable instances is not implemented for data states that are not explicit or predicate." - ) + "Generalizing variable instances is not implemented for data states that are not explicit or predicate.") } as S class LazyDelegate(val getProperty: T.() -> P) { diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt index 0e2d35e29c..d17f15fda1 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt @@ -122,14 +122,13 @@ class XcfaAbstractor( companion object { fun builder( - argBuilder: ArgBuilder - ): BasicAbstractor.Builder { + argBuilder: ArgBuilder): BasicAbstractor.Builder { return Builder(argBuilder) } } - class Builder(argBuilder: ArgBuilder) : - BasicAbstractor.Builder(argBuilder) { + class Builder(argBuilder: ArgBuilder) + : BasicAbstractor.Builder(argBuilder) { override fun build(): BasicAbstractor { return XcfaAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt index 798886422e..82a8e65178 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAction.kt @@ -24,10 +24,8 @@ import hu.bme.mit.theta.xcfa.passes.flatten data class XcfaAction @JvmOverloads -constructor( - val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTriples = emptyMap(), - private val nextCnt: Int = 0 -) : +constructor(val pid: Int, val edge: XcfaEdge, private val lastWrites: WriteTriples = emptyMap(), + private val nextCnt: Int = 0) : PtrAction(lastWrites, nextCnt) { val source: XcfaLocation = edge.source @@ -35,14 +33,12 @@ constructor( val label: XcfaLabel = edge.label private val stmts: List = label.toStmt().flatten() - constructor( - pid: Int, + constructor(pid: Int, source: XcfaLocation, target: XcfaLocation, label: XcfaLabel = NopLabel, lastWrites: WriteTriples = emptyMap(), - nextCnt: Int = 0 - ) : + nextCnt: Int = 0) : this(pid, XcfaEdge(source, target, label), lastWrites, nextCnt) override val stmtList: List diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt index d630b6ac06..64bd2e3d62 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt @@ -60,8 +60,7 @@ open class XcfaAnalysis( ) : Analysis>, XcfaAction, XcfaPrec

> { init { - ConeOfInfluence.coreTransFunc = - transFunc as TransFunc>, XcfaAction, XcfaPrec> + ConeOfInfluence.coreTransFunc = transFunc as TransFunc>, XcfaAction, XcfaPrec> coreTransFunc = ConeOfInfluence.transFunc as TransFunc>, XcfaAction, XcfaPrec

> } @@ -75,28 +74,14 @@ private var tempCnt: Int = 0 fun getCoreXcfaLts() = LTS>, XcfaAction> { s -> s.processes.map { proc -> if (proc.value.locs.peek().final) { - listOf( - XcfaAction( - proc.key, - XcfaEdge( - proc.value.locs.peek(), proc.value.locs.peek(), SequenceLabel( - listOf( - proc.value.paramStmts.peek().second, - ReturnLabel(proc.value.returnStmts.peek()), - ) - ) - ), nextCnt = s.sGlobal.nextCnt - ) - ) + listOf(XcfaAction(proc.key, + XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), SequenceLabel(listOf( + proc.value.paramStmts.peek().second, + ReturnLabel(proc.value.returnStmts.peek()), + ))), nextCnt = s.sGlobal.nextCnt)) } else if (!proc.value.paramsInitialized) { - listOf( - XcfaAction( - proc.key, XcfaEdge( - proc.value.locs.peek(), proc.value.locs.peek(), - proc.value.paramStmts.peek().first - ), nextCnt = s.sGlobal.nextCnt - ) - ) + listOf(XcfaAction(proc.key, XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), + proc.value.paramStmts.peek().first), nextCnt = s.sGlobal.nextCnt)) } else { proc.value.locs.peek().outgoingEdges.map { edge -> val newLabel = edge.label.changeVars(proc.value.varLookup.peek()) @@ -110,21 +95,15 @@ fun getCoreXcfaLts() = LTS>, XcfaAction> { SequenceLabel(listOf(procedure.params.withIndex() .filter { it.value.second != ParamDirection.OUT }.map { iVal -> val originalVar = iVal.value.first - val tempVar = Var( - "tmp${tempCnt++}_" + originalVar.name, - originalVar.type - ) + val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, + originalVar.type) lookup[originalVar] = tempVar StmtLabel( Stmts.Assign( TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type) - ), - metadata = label.metadata - ) - }, listOf(label.copy(tempLookup = lookup)) - ).flatten() - ) + TypeUtils.cast(label.params[iVal.index], tempVar.type)), + metadata = label.metadata) + }, listOf(label.copy(tempLookup = lookup))).flatten()) } else if (label is StartLabel) { val procedure = s.xcfa?.procedures?.find { proc -> proc.name == label.name } ?: error("No such method ${label.name}.") @@ -132,28 +111,22 @@ fun getCoreXcfaLts() = LTS>, XcfaAction> { SequenceLabel(listOf(procedure.params.withIndex() .filter { it.value.second != ParamDirection.OUT }.mapNotNull { iVal -> val originalVar = iVal.value.first - val tempVar = Var( - "tmp${tempCnt++}_" + originalVar.name, - originalVar.type - ) + val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, + originalVar.type) lookup[originalVar] = tempVar val trial = Try.attempt { StmtLabel( Stmts.Assign( TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type) - ), - metadata = label.metadata - ) + TypeUtils.cast(label.params[iVal.index], tempVar.type)), + metadata = label.metadata) } if (trial.isSuccess) { trial.asSuccess().value } else { null } - }, listOf(label.copy(tempLookup = lookup)) - ).flatten() - ) + }, listOf(label.copy(tempLookup = lookup))).flatten()) } else label }) XcfaAction(proc.key, edge.withLabel(newNewLabel), nextCnt = s.sGlobal.nextCnt) @@ -179,8 +152,7 @@ enum class ErrorDetection { } fun getXcfaErrorPredicate( - errorDetection: ErrorDetection -): Predicate>> = when (errorDetection) { + errorDetection: ErrorDetection): Predicate>> = when (errorDetection) { ErrorDetection.ERROR_LOCATION -> Predicate>> { s -> s.processes.any { it.value.locs.peek().error } } @@ -213,14 +185,11 @@ fun getXcfaErrorPredicate( fun getPartialOrder(partialOrd: PartialOrd>) = PartialOrd>> { s1, s2 -> s1.processes == s2.processes && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes && partialOrd.isLeq( - s1.sGlobal, s2.sGlobal - ) + s1.sGlobal, s2.sGlobal) } -private fun stackIsLeq( - s1: XcfaState>, - s2: XcfaState> -) = s2.processes.keys.all { pid -> +private fun stackIsLeq(s1: XcfaState>, + s2: XcfaState>) = s2.processes.keys.all { pid -> s1.processes[pid]?.let { ps1 -> val ps2 = s2.processes.getValue(pid) ps1.locs.peek() == ps2.locs.peek() && ps1.paramsInitialized && ps2.paramsInitialized @@ -229,18 +198,15 @@ private fun stackIsLeq( fun getStackPartialOrder(partialOrd: PartialOrd>) = PartialOrd>> { s1, s2 -> - s1.processes.size == s2.processes.size && stackIsLeq( - s1, - s2 - ) && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes + s1.processes.size == s2.processes.size && stackIsLeq(s1, + s2) && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes && partialOrd.isLeq(s1.withGeneralizedVars(), s2.withGeneralizedVars()) } private fun >, P : XcfaPrec> getXcfaArgBuilder( analysis: Analysis, lts: LTS>, XcfaAction>, - errorDetection: ErrorDetection -) + errorDetection: ErrorDetection) : ArgBuilder = ArgBuilder.create( lts, @@ -267,19 +233,13 @@ fun >, P : XcfaPrec> getXcfa /// EXPL -private fun getExplXcfaInitFunc( - xcfa: XCFA, - solver: Solver -): (XcfaPrec>) -> List>> { +private fun getExplXcfaInitFunc(xcfa: XCFA, + solver: Solver): (XcfaPrec>) -> List>> { val processInitState = xcfa.initProcedures.mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair( - i, XcfaProcessState( - initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))) - ) - ) + Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) }.toMap() return { p -> ExplInitFunc.create(solver, True()).getPtrInitFunc().getInitStates(p.p) @@ -288,28 +248,19 @@ private fun getExplXcfaInitFunc( } private fun getExplXcfaTransFunc(solver: Solver, maxEnum: Int, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { - val explTransFunc = (ExplStmtTransFunc.create( - solver, - maxEnum - ) as TransFunc).getPtrTransFunc(isHavoc) + (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { + val explTransFunc = (ExplStmtTransFunc.create(solver, + maxEnum) as TransFunc).getPtrTransFunc(isHavoc) return { s, a, p -> val (newSt, newAct) = s.apply(a) - explTransFunc.getSuccStates( - newSt.sGlobal, newAct, p.p.addVars( - listOf( - s.processes.map { it.value.varLookup }.flatten(), - listOf(getTempLookup(a.label)) - ).flatten() - ) - ).map { newSt.withState(it) } + explTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( + listOf(s.processes.map { it.value.varLookup }.flatten(), + listOf(getTempLookup(a.label))).flatten())).map { newSt.withState(it) } } } -class ExplXcfaAnalysis( - xcfa: XCFA, solver: Solver, maxEnum: Int, - partialOrd: PartialOrd>>, isHavoc: Boolean -) : +class ExplXcfaAnalysis(xcfa: XCFA, solver: Solver, maxEnum: Int, + partialOrd: PartialOrd>>, isHavoc: Boolean) : XcfaAnalysis>( corePartialOrd = partialOrd, coreInitFunc = getExplXcfaInitFunc(xcfa, solver), @@ -318,19 +269,13 @@ class ExplXcfaAnalysis( /// PRED -private fun getPredXcfaInitFunc( - xcfa: XCFA, - predAbstractor: PredAbstractor -): (XcfaPrec>) -> List>> { +private fun getPredXcfaInitFunc(xcfa: XCFA, + predAbstractor: PredAbstractor): (XcfaPrec>) -> List>> { val processInitState = xcfa.initProcedures.mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair( - i, XcfaProcessState( - initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))) - ) - ) + Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) }.toMap() return { p -> PredInitFunc.create(predAbstractor, True()).getPtrInitFunc().getInitStates(p.p) @@ -339,10 +284,9 @@ private fun getPredXcfaInitFunc( } private fun getPredXcfaTransFunc(predAbstractor: PredAbstractors.PredAbstractor, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { + (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { val predTransFunc = (PredTransFunc.create( - predAbstractor - ) as TransFunc).getPtrTransFunc(isHavoc) + predAbstractor) as TransFunc).getPtrTransFunc(isHavoc) return { s, a, p -> val (newSt, newAct) = s.apply(a) predTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( @@ -351,10 +295,8 @@ private fun getPredXcfaTransFunc(predAbstractor: PredAbstractors.PredAbstractor, } } -class PredXcfaAnalysis( - xcfa: XCFA, solver: Solver, predAbstractor: PredAbstractor, - partialOrd: PartialOrd>>, isHavoc: Boolean -) : +class PredXcfaAnalysis(xcfa: XCFA, solver: Solver, predAbstractor: PredAbstractor, + partialOrd: PartialOrd>>, isHavoc: Boolean) : XcfaAnalysis>( corePartialOrd = partialOrd, coreInitFunc = getPredXcfaInitFunc(xcfa, predAbstractor), diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt index 40cea2bc74..64e8984d4d 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaPrecRefiner.kt @@ -37,10 +37,8 @@ class XcfaPrecRefiner(refToPrec: Refuta private val refToPrec: RefutationToPrec, R> = Preconditions.checkNotNull(refToPrec) - override fun refine( - prec: XcfaPrec>, trace: Trace, XcfaAction>, - refutation: R - ): XcfaPrec> { + override fun refine(prec: XcfaPrec>, trace: Trace, XcfaAction>, + refutation: R): XcfaPrec> { Preconditions.checkNotNull(trace) Preconditions.checkNotNull(prec) Preconditions.checkNotNull(refutation) @@ -50,8 +48,7 @@ class XcfaPrecRefiner(refToPrec: Refuta it.foldVarLookup().map { Pair(it.value, it.key) } }.flatten().toMap() val reverseTempLookup = if (i > 0) getTempLookup( - trace.actions[i - 1].edge.label - ).entries.associateBy( + trace.actions[i - 1].edge.label).entries.associateBy( { it.value }) { it.key } else emptyMap() val precFromRef = refToPrec.toPrec(refutation, i).changeVars(reverseVarLookup + reverseTempLookup) runningPrec = refToPrec.join(runningPrec, precFromRef) @@ -86,12 +83,10 @@ fun

P.addVars(lookups: Collection, VarDecl<*>>>): P = else when (this) { is ExplPrec -> ExplPrec.of( - vars.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten() - ) as P + vars.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten()) as P is PredPrec -> PredPrec.of( - preds.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten() - ) as P + preds.map { lookups.map { lookup -> it.changeVars(lookup) } }.flatten()) as P is PtrPrec<*> -> PtrPrec(innerPrec.addVars(lookups)) as P diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt index 878e2a3964..ad0a385e5d 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt @@ -72,20 +72,15 @@ class XcfaSingleExprTraceRefiner, states: List, actions: List): Triple, List, List>, a: A -> + Triple(Pair(emptyMap(), 0), listOf(rawTrace.getState(0)), + listOf())) { i: Int, (wTripleCnt: Pair, states: List, actions: List): Triple, List, List>, a: A -> val (wTriple, cnt) = wTripleCnt val newA = (a as XcfaAction).withLastWrites(wTriple, cnt) val newState = (rawTrace.getState(i + 1) as XcfaState>).let { it.withState(PtrState(it.sGlobal.innerState.patch(newA.nextWriteTriples()))) } - Triple( - Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), states + (newState as S), - actions + (newA as A) - ) + Triple(Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), states + (newState as S), + actions + (newA as A)) } val traceToConcretize = Trace.of(states, actions) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt index c75bcefd8e..0054be37f2 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaState.kt @@ -52,10 +52,8 @@ data class XcfaState @JvmOverloads constructor( fun apply(a: XcfaAction): Pair, XcfaAction> { val changes: MutableList<(XcfaState) -> XcfaState> = ArrayList() - if (mutexes[""] != null && mutexes[""] != a.pid) return Pair( - copy(bottom = true), - a.withLabel(SequenceLabel(listOf(NopLabel))) - ) + if (mutexes[""] != null && mutexes[""] != a.pid) return Pair(copy(bottom = true), + a.withLabel(SequenceLabel(listOf(NopLabel)))) val processState = processes[a.pid] checkNotNull(processState) @@ -103,19 +101,12 @@ data class XcfaState @JvmOverloads constructor( is InvokeLabel -> { val proc = xcfa?.procedures?.find { proc -> proc.name == it.name } ?: error( - "No such method ${it.name}." - ) + "No such method ${it.name}.") val returnStmt = SequenceLabel( proc.params.withIndex().filter { it.value.second != ParamDirection.IN }.map { iVal -> - StmtLabel( - Assign( - cast( - (it.params[iVal.index] as RefExpr<*>).decl as VarDecl<*>, - iVal.value.first.type - ), cast(iVal.value.first.ref, iVal.value.first.type) - ), - metadata = it.metadata - ) + StmtLabel(Assign(cast((it.params[iVal.index] as RefExpr<*>).decl as VarDecl<*>, + iVal.value.first.type), cast(iVal.value.first.ref, iVal.value.first.type)), + metadata = it.metadata) }) changes.add { state -> state.invokeFunction(a.pid, proc, returnStmt, proc.params.toMap(), it.tempLookup) @@ -170,34 +161,20 @@ data class XcfaState @JvmOverloads constructor( val pid = pidCnt++ val lookup = XcfaProcessState.createLookup(procedure, "T$pid", "") newThreadLookup[startLabel.pidVar] = pid - newProcesses[pid] = XcfaProcessState( - LinkedList(listOf(procedure.initLoc)), prefix = "T$pid", + newProcesses[pid] = XcfaProcessState(LinkedList(listOf(procedure.initLoc)), prefix = "T$pid", varLookup = LinkedList(listOf(lookup)), returnStmts = LinkedList(listOf(returnStmt)), - paramStmts = LinkedList( - listOf( - Pair( - /* init */ - SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { - StmtLabel( - Assign( - cast(it.key.changeVars(lookup), it.key.type), - cast(it.key.changeVars(tempLookup).ref, it.key.type) - ) - ) - }), - /* deinit */ - SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { - StmtLabel( - Assign( - cast(it.key.changeVars(tempLookup), it.key.type), - cast(it.key.changeVars(lookup).ref, it.key.type) - ) - ) - }), - ) - ) - ) - ) + paramStmts = LinkedList(listOf(Pair( + /* init */ + SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { + StmtLabel(Assign(cast(it.key.changeVars(lookup), it.key.type), + cast(it.key.changeVars(tempLookup).ref, it.key.type))) + }), + /* deinit */ + SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { + StmtLabel(Assign(cast(it.key.changeVars(tempLookup), it.key.type), + cast(it.key.changeVars(lookup).ref, it.key.type))) + }), + )))) val newMutexes = LinkedHashMap(mutexes) newMutexes["$pid"] = pid @@ -212,10 +189,8 @@ data class XcfaState @JvmOverloads constructor( return copy(processes = newProcesses, mutexes = newMutexes) } - private fun invokeFunction( - pid: Int, proc: XcfaProcedure, returnStmt: XcfaLabel, - paramList: Map, ParamDirection>, tempLookup: Map, VarDecl<*>> - ): XcfaState { + private fun invokeFunction(pid: Int, proc: XcfaProcedure, returnStmt: XcfaLabel, + paramList: Map, ParamDirection>, tempLookup: Map, VarDecl<*>>): XcfaState { val newProcesses: MutableMap = LinkedHashMap(processes) newProcesses[pid] = checkNotNull(processes[pid]?.enterFunction(proc, returnStmt, paramList, tempLookup)) return copy(processes = newProcesses) @@ -255,12 +230,10 @@ data class XcfaState @JvmOverloads constructor( } } -data class XcfaProcessState( - val locs: LinkedList, val varLookup: LinkedList, VarDecl<*>>>, +data class XcfaProcessState(val locs: LinkedList, val varLookup: LinkedList, VarDecl<*>>>, val returnStmts: LinkedList = LinkedList(listOf(NopLabel)), val paramStmts: LinkedList> = LinkedList(listOf(Pair(NopLabel, NopLabel))), - val paramsInitialized: Boolean = false, val prefix: String = "" -) { + val paramsInitialized: Boolean = false, val prefix: String = "") { internal var popped: XcfaLocation? = null // stores if the stack was popped due to abstract stack covering @@ -277,10 +250,8 @@ data class XcfaProcessState( else -> "${locs.peek()!!} [${locs.size}], initilized=$paramsInitialized" } - fun enterFunction( - xcfaProcedure: XcfaProcedure, returnStmt: XcfaLabel, paramList: Map, ParamDirection>, - tempLookup: Map, VarDecl<*>> - ): XcfaProcessState { + fun enterFunction(xcfaProcedure: XcfaProcedure, returnStmt: XcfaLabel, paramList: Map, ParamDirection>, + tempLookup: Map, VarDecl<*>>): XcfaProcessState { val deque: LinkedList = LinkedList(locs) val varLookup: LinkedList, VarDecl<*>>> = LinkedList(varLookup) val returnStmts: LinkedList = LinkedList(returnStmts) @@ -289,32 +260,20 @@ data class XcfaProcessState( val lookup = createLookup(xcfaProcedure, prefix, "P${procCnt++}") varLookup.push(lookup) returnStmts.push(returnStmt) - paramStmts.push( - Pair( - /* init */ - SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { - StmtLabel( - Assign( - cast(it.key.changeVars(lookup), it.key.type), - cast(it.key.changeVars(tempLookup).ref, it.key.type) - ) - ) - }), - /* deinit */ - SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { - StmtLabel( - Assign( - cast(it.key.changeVars(tempLookup), it.key.type), - cast(it.key.changeVars(lookup).ref, it.key.type) - ) - ) - }), - ) - ) - return copy( - locs = deque, varLookup = varLookup, returnStmts = returnStmts, paramStmts = paramStmts, - paramsInitialized = false - ) + paramStmts.push(Pair( + /* init */ + SequenceLabel(paramList.filter { it.value != ParamDirection.OUT }.map { + StmtLabel(Assign(cast(it.key.changeVars(lookup), it.key.type), + cast(it.key.changeVars(tempLookup).ref, it.key.type))) + }), + /* deinit */ + SequenceLabel(paramList.filter { it.value != ParamDirection.IN }.map { + StmtLabel(Assign(cast(it.key.changeVars(tempLookup), it.key.type), + cast(it.key.changeVars(lookup).ref, it.key.type))) + }), + )) + return copy(locs = deque, varLookup = varLookup, returnStmts = returnStmts, paramStmts = paramStmts, + paramsInitialized = false) } fun exitFunction(): XcfaProcessState { @@ -349,10 +308,8 @@ data class XcfaProcessState( companion object { - fun createLookup( - proc: XcfaProcedure, threadPrefix: String, - procPrefix: String - ): Map, VarDecl<*>> = listOf(proc.params.map { it.first }, proc.vars).flatten() + fun createLookup(proc: XcfaProcedure, threadPrefix: String, + procPrefix: String): Map, VarDecl<*>> = listOf(proc.params.map { it.first }, proc.vars).flatten() .associateWith { val sj = StringJoiner("::") if (threadPrefix != "") sj.add(threadPrefix) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt index 7b22edcdea..30d7147c72 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateAdapter.kt @@ -61,14 +61,12 @@ class XcfaStateAdapter(val gsonSupplier: () -> Gson, val stateTypeSupplier: () - val bottom: Boolean = gson.fromJson(reader, Boolean::class.java) reader.endObject() - return XcfaState( - xcfa = null, + return XcfaState(xcfa = null, processes = processes, sGlobal = sGlobal, mutexes = mutexes, threadLookup = threadLookup, - bottom = bottom - ) + bottom = bottom) } private fun initGson() { diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt index 882ecae465..d91174ed82 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaToMonolithicExpr.kt @@ -52,16 +52,12 @@ fun XCFA.toMonolithicExpr(): MonolithicExpr { } val locVar = Decls.Var("__loc_", IntExprs.Int()) val tranList = proc.edges.map { (source, target, label): XcfaEdge -> - SequenceStmt.of( - listOf( - AssumeStmt.of(Eq(locVar.ref, IntExprs.Int(map[source]!!))), - label.toStmt(), - AssignStmt.of( - locVar, - IntExprs.Int(map[target]!!) - ) - ) - ) + SequenceStmt.of(listOf( + AssumeStmt.of(Eq(locVar.ref, IntExprs.Int(map[source]!!))), + label.toStmt(), + AssignStmt.of(locVar, + IntExprs.Int(map[target]!!)) + )) }.toList() val trans = NonDetStmt.of(tranList) val transUnfold = StmtUtils.toExpr(trans, VarIndexingFactory.indexing(0)) @@ -99,24 +95,16 @@ fun XCFA.valToState(val1: Valuation): XcfaState> { } return XcfaState( xcfa = this, - processes = mapOf( - Pair( - 0, XcfaProcessState( - locs = LinkedList( - listOf(map[(valMap[valMap.keys.first { it.name == "__loc_" }] as IntLitExpr).value.toInt()]) - ), - varLookup = LinkedList(), - ) - ) - ), + processes = mapOf(Pair(0, XcfaProcessState( + locs = LinkedList( + listOf(map[(valMap[valMap.keys.first { it.name == "__loc_" }] as IntLitExpr).value.toInt()])), + varLookup = LinkedList(), + ))), PtrState(ExplState.of( ImmutableValuation.from( val1.toMap() .filter { it.key.name != "__loc_" && !it.key.name.startsWith("__temp_") } - .map { Pair(Decls.Var("_" + "_" + it.key.name, it.key.type), it.value) }.toMap() - ) - ) - ), + .map { Pair(Decls.Var("_" + "_" + it.key.name, it.key.type), it.value) }.toMap()))), mutexes = emptyMap(), threadLookup = emptyMap(), bottom = false diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt index 6560d5ea82..0500b5d88b 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/coi/XcfaCoiMultiThread.kt @@ -90,10 +90,8 @@ class XcfaCoiMultiThread(xcfa: XCFA) : XcfaCoi(xcfa) { } } - private fun isObserved( - action: A, procedures: MutableList, - multipleProcedures: Set - ): Boolean { + private fun isObserved(action: A, procedures: MutableList, + multipleProcedures: Set): Boolean { val toVisit = edgeToProcedure.keys.filter { it.source == action.edge.source && it.target == action.edge.target }.toMutableList() diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt index 69c695ca39..6ffa9bc1fb 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt @@ -74,16 +74,14 @@ class XcfaOcChecker(xcfa: XCFA, decisionProcedure: OcDecisionProcedureType, priv private val rfs = mutableMapOf, MutableSet>() override fun check( - prec: XcfaPrec? - ): SafetyResult>, XcfaAction>> = let { + prec: XcfaPrec?): SafetyResult>, XcfaAction>> = let { if (xcfa.initProcedures.size > 1) error("Multiple entry points are not supported by OC checker.") logger.write(Logger.Level.MAINSTEP, "Adding constraints...\n") xcfa.initProcedures.forEach { processThread(Thread(it.first)) } addCrossThreadRelations() if (!addToSolver()) return@let SafetyResult.safe>, XcfaAction>>( - EmptyWitness.getInstance() - ) // no violations in the model + EmptyWitness.getInstance()) // no violations in the model logger.write(Logger.Level.MAINSTEP, "Start checking...\n") val status = ocChecker.check(events, pos, rfs) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt index ad96ab9606..05ff67fc9e 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcTraceExtractor.kt @@ -75,10 +75,8 @@ internal class XcfaOcTraceExtractor( val nextEdge = eventTrace.getOrNull(index + 1)?.edge if (nextEdge != lastEdge) { - extend( - stateList.last(), event.pid, lastEdge.source, - explState.innerState - )?.let { (midActions, midStates) -> + extend(stateList.last(), event.pid, lastEdge.source, + explState.innerState)?.let { (midActions, midStates) -> actionList.addAll(midActions) stateList.addAll(midStates) } @@ -88,9 +86,9 @@ internal class XcfaOcTraceExtractor( stateList.add(state.copy(processes = state.processes.toMutableMap().apply { put( event.pid, XcfaProcessState( - locs = LinkedList(listOf(lastEdge.target)), - varLookup = LinkedList(emptyList()) - ) + locs = LinkedList(listOf(lastEdge.target)), + varLookup = LinkedList(emptyList()) + ) ) }, sGlobal = explState, mutexes = state.mutexes.update(lastEdge, event.pid))) lastEdge = nextEdge ?: break @@ -98,10 +96,8 @@ internal class XcfaOcTraceExtractor( } if (!stateList.last().processes[violation.pid]!!.locs.peek().error) { - extend( - stateList.last(), violation.pid, violation.errorLoc, - explState.innerState - )?.let { (midActions, midStates) -> + extend(stateList.last(), violation.pid, violation.errorLoc, + explState.innerState)?.let { (midActions, midStates) -> actionList.addAll(midActions) stateList.addAll(midStates) } @@ -167,9 +163,9 @@ internal class XcfaOcTraceExtractor( currentState = currentState.copy(processes = currentState.processes.toMutableMap().apply { put( stepPid, XcfaProcessState( - locs = LinkedList(listOf(edge.target)), - varLookup = LinkedList(emptyList()) - ) + locs = LinkedList(listOf(edge.target)), + varLookup = LinkedList(emptyList()) + ) ) }, sGlobal = PtrState(explState), mutexes = currentState.mutexes.update(edge, stepPid)) states.add(currentState) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt index f454fd25e9..d036c61ecd 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/por/XcfaDporLts.kt @@ -200,8 +200,7 @@ open class XcfaDporLts(private val xcfa: XCFA) : LTS { val lastButOne = stack[stack.size - 2] val mutexNeverReleased = last.mutexLocks.containsKey( - "" - ) && (last.state.mutexes.keys subtract lastButOne.state.mutexes.keys).contains( + "") && (last.state.mutexes.keys subtract lastButOne.state.mutexes.keys).contains( "" ) if (last.node.explored.isEmpty() || mutexNeverReleased) { @@ -261,9 +260,7 @@ open class XcfaDporLts(private val xcfa: XCFA) : LTS { val action = node.inEdge.get().action if (relevantProcesses.contains(action.pid)) { if (newLastDependents.containsKey(action.pid) && index <= checkNotNull( - newLastDependents[action.pid] - ) - ) { + newLastDependents[action.pid])) { // there is an action a' such that action -> a' -> newaction (->: happens-before) relevantProcesses.remove(action.pid) } else if (dependent(newaction, action)) { diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt index 8e01612ffa..b4aa758303 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt @@ -82,30 +82,23 @@ class XcfaExplAnalysisTest { val lts = getXcfaLts() - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec()) - ) + ItpRefToPtrPrec(ItpRefToExplPrec())) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -134,30 +127,23 @@ class XcfaExplAnalysisTest { val lts = XcfaSporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec()) - ) + ItpRefToPtrPrec(ItpRefToExplPrec())) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -187,30 +173,23 @@ class XcfaExplAnalysisTest { val lts = XcfaDporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec()) - ) + ItpRefToPtrPrec(ItpRefToExplPrec())) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, ConsoleLogger( - Logger.Level.DETAIL - ) - ) as Refiner>, XcfaAction, XcfaPrec>> + Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -239,31 +218,24 @@ class XcfaExplAnalysisTest { val lts = XcfaAasporLts(xcfa, mutableMapOf()) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec()) - ) + ItpRefToPtrPrec(ItpRefToExplPrec())) val atomicNodePruner = AtomicNodePruner>, XcfaAction>() val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner - ) as Refiner>, XcfaAction, XcfaPrec>> + atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) @@ -293,26 +265,21 @@ class XcfaExplAnalysisTest { val lts = XcfaAadporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner(ItpRefToPtrPrec(ItpRefToExplPrec())) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt index 88d068adf7..e398b5ed07 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt @@ -84,30 +84,23 @@ class XcfaPredAnalysisTest { val lts = getXcfaLts() - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) - ) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -137,30 +130,23 @@ class XcfaPredAnalysisTest { val lts = XcfaSporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) - ) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -191,30 +177,23 @@ class XcfaPredAnalysisTest { val lts = XcfaDporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) - ) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, ConsoleLogger( - Logger.Level.DETAIL - ) - ) as Refiner>, XcfaAction, XcfaPrec>> + Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) @@ -244,31 +223,24 @@ class XcfaPredAnalysisTest { val lts = XcfaAasporLts(xcfa, mutableMapOf()) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) - ), + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) - ) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) val atomicNodePruner = AtomicNodePruner>, XcfaAction>() val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner - ) as Refiner>, XcfaAction, XcfaPrec>> + atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) @@ -299,28 +271,22 @@ class XcfaPredAnalysisTest { val lts = XcfaAadporLts(xcfa) - val abstractor = getXcfaAbstractor( - analysis, + val abstractor = getXcfaAbstractor(analysis, lts.waitlist, StopCriterions.firstCex>, XcfaAction>(), ConsoleLogger(Logger.Level.DETAIL), lts, - ErrorDetection.ERROR_LOCATION - ) as Abstractor>, XcfaAction, XcfaPrec>> + ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> val precRefiner = XcfaPrecRefiner( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) - ) + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) val refiner = XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create( - BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver() - ), + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver()), precRefiner, PruneStrategy.FULL, - NullLogger.getInstance() - ) as Refiner>, XcfaAction, XcfaPrec>> + NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> val cegarChecker = CegarChecker.create(abstractor, refiner) diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt index d02b0687d3..b1a815104b 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaStateLtsTest.kt @@ -67,8 +67,7 @@ class XcfaStateLtsTest { initState = XcfaState( xcfa, mapOf( - Pair( - 0, + Pair(0, XcfaProcessState( locs = LinkedList(listOf(edges[1].source)), varLookup = LinkedList(listOf(createLookup(xcfa.initProcedures[0].first, "T0", "P0"))) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index e835aaf239..9469c2eca3 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -176,15 +176,13 @@ fun frontend(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger): Tr logger.write( Logger.Level.INFO, "Frontend finished: ${xcfa.name} (in ${ - stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + } ms)\n" ) logger.write(RESULT, "ParsingResult Success\n") - logger.write( - RESULT, - "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n" - ) + logger.write(RESULT, + "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n") return Triple(xcfa, mcm, parseContext) } @@ -228,8 +226,8 @@ private fun backend( logger.write( Logger.Level.INFO, "Backend finished (in ${ - stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + } ms)\n" ) logger.write(RESULT, result.toString() + "\n") @@ -333,10 +331,8 @@ private fun postVerificationLogging( traceFile.writeText(GraphvizWriter.getInstance().writeString(traceG)) val sequenceFile = File(resultFolder, "trace.plantuml") - writeSequenceTrace( - sequenceFile, - safetyResult.asUnsafe().cex as Trace, XcfaAction> - ) { (_, act) -> + writeSequenceTrace(sequenceFile, + safetyResult.asUnsafe().cex as Trace, XcfaAction>) { (_, act) -> act.label.getFlatLabels().map(XcfaLabel::toString) } @@ -367,10 +363,8 @@ private fun postVerificationLogging( } } -private fun writeSequenceTrace( - sequenceFile: File, trace: Trace, XcfaAction>, - printer: (Pair, XcfaAction>) -> List -) { +private fun writeSequenceTrace(sequenceFile: File, trace: Trace, XcfaAction>, + printer: (Pair, XcfaAction>) -> List) { sequenceFile.writeText("@startuml\n") var maxWidth = 0 trace.actions.forEachIndexed { i, it -> diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt index 7feaca22b7..18e0bd82ca 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt @@ -30,31 +30,23 @@ import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getBoundedChecker( - xcfa: XCFA, mcm: MCM, +fun getBoundedChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger -): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { val boundedConfig = config.backendConfig.specConfig as BoundedConfig return BoundedChecker( monolithicExpr = xcfa.toMonolithicExpr(), - bmcSolver = tryGetSolver( - boundedConfig.bmcConfig.bmcSolver, - boundedConfig.bmcConfig.validateBMCSolver - )?.createSolver(), + bmcSolver = tryGetSolver(boundedConfig.bmcConfig.bmcSolver, + boundedConfig.bmcConfig.validateBMCSolver)?.createSolver(), bmcEnabled = { !boundedConfig.bmcConfig.disable }, lfPathOnly = { !boundedConfig.bmcConfig.nonLfPath }, - itpSolver = tryGetSolver( - boundedConfig.itpConfig.itpSolver, - boundedConfig.itpConfig.validateItpSolver - )?.createItpSolver(), + itpSolver = tryGetSolver(boundedConfig.itpConfig.itpSolver, + boundedConfig.itpConfig.validateItpSolver)?.createItpSolver(), imcEnabled = { !boundedConfig.itpConfig.disable }, - indSolver = tryGetSolver( - boundedConfig.indConfig.indSolver, - boundedConfig.indConfig.validateIndSolver - )?.createSolver(), + indSolver = tryGetSolver(boundedConfig.indConfig.indSolver, + boundedConfig.indConfig.validateIndSolver)?.createSolver(), kindEnabled = { !boundedConfig.indConfig.disable }, valToState = { xcfa.valToState(it) }, biValToAction = { val1, val2 -> xcfa.valToAction(val1, val2) }, diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt index 6417f4e57c..8c39486021 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt @@ -43,20 +43,14 @@ import hu.bme.mit.theta.xcfa.cli.params.* import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getCegarChecker( - xcfa: XCFA, mcm: MCM, +fun getCegarChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger -): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { + logger: Logger): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { val cegarConfig = config.backendConfig.specConfig as CegarConfig - val abstractionSolverFactory: SolverFactory = getSolver( - cegarConfig.abstractorConfig.abstractionSolver, - cegarConfig.abstractorConfig.validateAbstractionSolver - ) - val refinementSolverFactory: SolverFactory = getSolver( - cegarConfig.refinerConfig.refinementSolver, - cegarConfig.refinerConfig.validateRefinementSolver - ) + val abstractionSolverFactory: SolverFactory = getSolver(cegarConfig.abstractorConfig.abstractionSolver, + cegarConfig.abstractorConfig.validateAbstractionSolver) + val refinementSolverFactory: SolverFactory = getSolver(cegarConfig.refinerConfig.refinementSolver, + cegarConfig.refinerConfig.validateRefinementSolver) val ignoredVarRegistry = mutableMapOf, MutableSet>() @@ -65,14 +59,12 @@ fun getCegarChecker( (cegarConfig.coi.porLts as XcfaDporLts).waitlist } else { PriorityWaitlist.create>, XcfaAction>>( - cegarConfig.abstractorConfig.search.getComp(xcfa) - ) + cegarConfig.abstractorConfig.search.getComp(xcfa)) } val abstractionSolverInstance = abstractionSolverFactory.createSolver() val globalStatePartialOrd: PartialOrd> = cegarConfig.abstractorConfig.domain.partialOrd( - abstractionSolverInstance - ) as PartialOrd> + abstractionSolverInstance) as PartialOrd> val corePartialOrd: PartialOrd>> = if (xcfa.isInlined) getPartialOrder(globalStatePartialOrd) else getStackPartialOrder(globalStatePartialOrd) @@ -99,23 +91,18 @@ fun getCegarChecker( val precRefiner: PrecRefiner = cegarConfig.abstractorConfig.domain.itpPrecRefiner(cegarConfig.refinerConfig.exprSplitter.exprSplitter) as PrecRefiner - val atomicNodePruner: NodePruner = - cegarConfig.abstractorConfig.domain.nodePruner as NodePruner + val atomicNodePruner: NodePruner = cegarConfig.abstractorConfig.domain.nodePruner as NodePruner val refiner: Refiner = if (cegarConfig.refinerConfig.refinement == Refinement.MULTI_SEQ) if (cegarConfig.porLevel == POR.AASPOR) - MultiExprTraceRefiner.create( - ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner - ) + MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner) else MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) else if (cegarConfig.porLevel == POR.AASPOR) - XcfaSingleExprTraceRefiner.create( - ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner - ) + XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner) else XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) @@ -138,11 +125,9 @@ fun getCegarChecker( return object : SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { override fun check( - prec: XcfaPrec<*>? - ): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { + prec: XcfaPrec<*>?): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { return cegarChecker.check( - prec - ) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> + prec) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> } override fun check(): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt index 2315b6405b..4bd2dce149 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToChecker.kt @@ -31,11 +31,9 @@ import hu.bme.mit.theta.xcfa.cli.params.Backend import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.model.XCFA -fun getChecker( - xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, +fun getChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger, - uniqueLogger: Logger -): SafetyChecker<*, *, XcfaPrec<*>> = + uniqueLogger: Logger): SafetyChecker<*, *, XcfaPrec<*>> = if (config.backendConfig.inProcess) { InProcessChecker(xcfa, config, parseContext, logger) } else { diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt index 80cae60477..df14f6ee8f 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt @@ -31,18 +31,14 @@ import hu.bme.mit.theta.xcfa.cli.params.OcConfig import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.model.XCFA -fun getOcChecker( - xcfa: XCFA, mcm: MCM, +fun getOcChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger -): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { val ocChecker = XcfaOcChecker(xcfa, (config.backendConfig.specConfig as OcConfig).decisionProcedure, logger) return object : SafetyChecker>, XcfaAction>, XcfaPrec<*>> { override fun check( - prec: XcfaPrec<*>? - ): SafetyResult>, XcfaAction>> = check() + prec: XcfaPrec<*>?): SafetyResult>, XcfaAction>> = check() - override fun check(): SafetyResult>, XcfaAction>> = - ocChecker.check() + override fun check(): SafetyResult>, XcfaAction>> = ocChecker.check() } } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt index 0daeedf5e8..a105f36786 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToPortfolio.kt @@ -40,52 +40,47 @@ import javax.script.ScriptEngine import javax.script.ScriptEngineManager import javax.script.SimpleBindings -fun getPortfolioChecker( - xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, +fun getPortfolioChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger, - uniqueLogger: Logger -): SafetyChecker>, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> = - SafetyChecker { _ -> + uniqueLogger: Logger): SafetyChecker>, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> = SafetyChecker { _ -> - val sw = Stopwatch.createStarted() - val portfolioName = (config.backendConfig.specConfig as PortfolioConfig).portfolio + val sw = Stopwatch.createStarted() + val portfolioName = (config.backendConfig.specConfig as PortfolioConfig).portfolio - val portfolioStm = when (portfolioName) { - "STABLE", - "CEGAR", - "COMPLEX", - "COMPLEX24" -> complexPortfolio24(xcfa, mcm, parseContext, config, logger, uniqueLogger) + val portfolioStm = when (portfolioName) { + "STABLE", + "CEGAR", + "COMPLEX", + "COMPLEX24" -> complexPortfolio24(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "COMPLEX23" -> complexPortfolio23(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "COMPLEX23" -> complexPortfolio23(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "EMERGENT", - "BOUNDED" -> boundedPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "EMERGENT", + "BOUNDED" -> boundedPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) - "TESTING", - "CHC", - "HORN" -> hornPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) + "TESTING", + "CHC", + "HORN" -> hornPortfolio(xcfa, mcm, parseContext, config, logger, uniqueLogger) - else -> { - if (File(portfolioName).exists()) { - val kotlinEngine: ScriptEngine = ScriptEngineManager().getEngineByExtension("kts") - val bindings: Bindings = SimpleBindings() - bindings["xcfa"] = xcfa - bindings["mcm"] = mcm - bindings["parseContext"] = parseContext - bindings["portfolioConfig"] = config - bindings["logger"] = logger - bindings["uniqueLogger"] = uniqueLogger - kotlinEngine.eval(FileReader(portfolioName), bindings) as STM - } else { - error("No such file or built-in config: $portfolioName") - } + else -> { + if (File(portfolioName).exists()) { + val kotlinEngine: ScriptEngine = ScriptEngineManager().getEngineByExtension("kts") + val bindings: Bindings = SimpleBindings() + bindings["xcfa"] = xcfa + bindings["mcm"] = mcm + bindings["parseContext"] = parseContext + bindings["portfolioConfig"] = config + bindings["logger"] = logger + bindings["uniqueLogger"] = uniqueLogger + kotlinEngine.eval(FileReader(portfolioName), bindings) as STM + } else { + error("No such file or built-in config: $portfolioName") } } + } - val result = portfolioStm.execute() as Pair, SafetyResult<*, *>> + val result = portfolioStm.execute() as Pair, SafetyResult<*, *>> - logger.write( - Logger.Level.RESULT, "Config ${result.first} succeeded in ${sw.elapsed(TimeUnit.MILLISECONDS)} ms\n" - ) - result.second as SafetyResult>, XcfaAction>, Trace>, XcfaAction>>? - } \ No newline at end of file + logger.write(Logger.Level.RESULT, "Config ${result.first} succeeded in ${sw.elapsed(TimeUnit.MILLISECONDS)} ms\n") + result.second as SafetyResult>, XcfaAction>, Trace>, XcfaAction>>? +} \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt index 276f6455d8..a20d9a5aaf 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt @@ -47,8 +47,7 @@ class InProcessChecker( ) : SafetyChecker> { override fun check( - prec: XcfaPrec<*>? - ): SafetyResult { + prec: XcfaPrec<*>?): SafetyResult { return check() } @@ -81,18 +80,16 @@ class InProcessChecker( getGson(xcfa).toJson(processConfig) } - val pb = NuProcessBuilder( - listOf( - ProcessHandle.current().info().command().orElse("java"), - "-Xss120m", - "-Xmx14210m", - "-cp", - File(XcfaCli::class.java.protectionDomain.codeSource.location.toURI()).absolutePath, - XcfaCli::class.qualifiedName, - "-c", - configJson.absolutePath - ).filterNotNull() - ) + val pb = NuProcessBuilder(listOf( + ProcessHandle.current().info().command().orElse("java"), + "-Xss120m", + "-Xmx14210m", + "-cp", + File(XcfaCli::class.java.protectionDomain.codeSource.location.toURI()).absolutePath, + XcfaCli::class.qualifiedName, + "-c", + configJson.absolutePath + ).filterNotNull()) val processHandler = ProcessHandler() pb.setProcessListener(processHandler) val process: NuProcess = pb.start() @@ -105,10 +102,8 @@ class InProcessChecker( process.destroy(true) throw ErrorCodeException(ExitCodes.TIMEOUT.code) } else { - logger.write( - Logger.Level.RESULT, - "Config timed out but started writing result, trying to wait an additional 10%..." - ) + logger.write(Logger.Level.RESULT, + "Config timed out but started writing result, trying to wait an additional 10%...") val retCode = process.waitFor(config.backendConfig.timeoutMs / 10, TimeUnit.MILLISECONDS) if (retCode != 0) { throw ErrorCodeException(retCode) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt index 83dbae2747..ac5b3d3236 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt @@ -116,10 +116,8 @@ enum class Domain( EXPL( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor( - ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), d, - e, f, g, h - ) + getXcfaAbstractor(ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), d, + e, f, g, h) }, itpPrecRefiner = { XcfaPrecRefiner, ExplPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToExplPrec())) @@ -131,12 +129,8 @@ enum class Domain( ), PRED_BOOL( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor( - PredXcfaAnalysis( - a, b, PredAbstractors.booleanAbstractor(b), - i as PartialOrd>>, j - ), d, e, f, g, h - ) + getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanAbstractor(b), + i as PartialOrd>>, j), d, e, f, g, h) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -148,12 +142,8 @@ enum class Domain( ), PRED_CART( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor( - PredXcfaAnalysis( - a, b, PredAbstractors.cartesianAbstractor(b), - i as PartialOrd>>, j - ), d, e, f, g, h - ) + getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.cartesianAbstractor(b), + i as PartialOrd>>, j), d, e, f, g, h) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -165,12 +155,8 @@ enum class Domain( ), PRED_SPLIT( abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor( - PredXcfaAnalysis( - a, b, PredAbstractors.booleanSplitAbstractor(b), - i as PartialOrd>>, j - ), d, e, f, g, h - ) + getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanSplitAbstractor(b), + i as PartialOrd>>, j), d, e, f, g, h) }, itpPrecRefiner = { a -> XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) @@ -294,19 +280,15 @@ enum class Search { BFS { override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine( - ArgNodeComparators.targetFirst(), - ArgNodeComparators.bfs() - ) + return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), + ArgNodeComparators.bfs()) } }, DFS { override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine( - ArgNodeComparators.targetFirst(), - ArgNodeComparators.dfs() - ) + return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), + ArgNodeComparators.dfs()) } }, ERR { @@ -339,8 +321,7 @@ enum class InitPrec( ALLASSUMES( explPrec = { xcfa -> XcfaPrec( - PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet()) - ) + PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet())) }, predPrec = { xcfa -> XcfaPrec(PtrPrec(PredPrec.of(xcfa.collectAssumes()), emptySet())) }, ), diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt index 3a8e43940a..a52a05c957 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/XcfaConfig.kt @@ -70,22 +70,16 @@ data class InputConfig( @Parameter(names = ["--cat"], description = "Path of the cat model") var catFile: File? = null, - @Parameter( - names = ["--parse-ctx"], - description = "Path of the parse context JSON (may contain additional metadata)" - ) + @Parameter(names = ["--parse-ctx"], + description = "Path of the parse context JSON (may contain additional metadata)") var parseCtx: File? = null, - @Parameter( - names = ["--xcfa-w-ctx"], - description = "XCFA and ParseContext (will overwrite --input and --parse-ctx when given)" - ) + @Parameter(names = ["--xcfa-w-ctx"], + description = "XCFA and ParseContext (will overwrite --input and --parse-ctx when given)") var xcfaWCtx: Triple? = null, - @Parameter( - names = ["--property"], - description = "Path of the property file (will overwrite --property when given)" - ) + @Parameter(names = ["--property"], + description = "Path of the property file (will overwrite --property when given)") var propertyFile: File? = null, @Parameter(names = ["--property-value"], description = "Property") @@ -106,22 +100,16 @@ data class FrontendConfig( @Parameter(names = ["--static-coi"], description = "Enable static cone-of-influence") var staticCoi: Boolean = false, - @Parameter( - names = ["--unroll"], - description = "Max number of loop iterations to unroll (use -1 to unroll completely when possible)" - ) + @Parameter(names = ["--unroll"], + description = "Max number of loop iterations to unroll (use -1 to unroll completely when possible)") var loopUnroll: Int = 1000, - @Parameter( - names = ["--force-unroll"], - description = "Number of loop iteration to unroll even if the number of iterations is unknown; in case of such a bounded loop unrolling, the safety result cannot be safe (use -1 to disable)" - ) + @Parameter(names = ["--force-unroll"], + description = "Number of loop iteration to unroll even if the number of iterations is unknown; in case of such a bounded loop unrolling, the safety result cannot be safe (use -1 to disable)") var forceUnroll: Int = -1, - @Parameter( - names = ["--enable-few"], - description = "Enable the FetchExecuteWriteback pass, which introduces a local temp var for all memory accesses" - ) + @Parameter(names = ["--enable-few"], + description = "Enable the FetchExecuteWriteback pass, which introduces a local temp var for all memory accesses") var enableFew: Boolean = false, @Parameter(names = ["--input-type"], description = "Format of the input") @@ -218,28 +206,22 @@ data class CegarAbstractorConfig( @Parameter(names = ["--abstraction-solver"], description = "Abstraction solver name") var abstractionSolver: String = "Z3", - @Parameter( - names = ["--validate-abstraction-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-abstraction-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateAbstractionSolver: Boolean = false, @Parameter(names = ["--domain"], description = "Abstraction domain") var domain: Domain = Domain.EXPL, - @Parameter( - names = ["--maxenum"], - description = "How many successors to enumerate in a transition. Only relevant to the explicit domain. Use 0 for no limit." - ) + @Parameter(names = ["--maxenum"], + description = "How many successors to enumerate in a transition. Only relevant to the explicit domain. Use 0 for no limit.") var maxEnum: Int = 1, @Parameter(names = ["--search"], description = "Search strategy") var search: Search = Search.ERR, - @Parameter( - names = ["--havoc-memory"], - description = "HAVOC memory model (do not track pointers in transition function)" - ) + @Parameter(names = ["--havoc-memory"], + description = "HAVOC memory model (do not track pointers in transition function)") var havocMemory: Boolean = false ) : Config @@ -247,10 +229,8 @@ data class CegarRefinerConfig( @Parameter(names = ["--refinement-solver"], description = "Refinement solver name") var refinementSolver: String = "Z3", - @Parameter( - names = ["--validate-refinement-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-refinement-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateRefinementSolver: Boolean = false, @Parameter(names = ["--refinement"], description = "Refinement strategy") @@ -301,10 +281,8 @@ data class BMCConfig( @Parameter(names = ["--bmc-solver"], description = "BMC solver name") var bmcSolver: String = "Z3", - @Parameter( - names = ["--validate-bmc-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-bmc-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateBMCSolver: Boolean = false, ) : Config @@ -315,22 +293,16 @@ data class InductionConfig( @Parameter(names = ["--induction-solver", "--ind-solver"], description = "Induction solver name") var indSolver: String = "Z3", - @Parameter( - names = ["--validate-induction-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-induction-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateIndSolver: Boolean = false, - @Parameter( - names = ["--ind-min-bound"], - description = "Start induction after reaching this bound" - ) + @Parameter(names = ["--ind-min-bound"], + description = "Start induction after reaching this bound") var indMinBound: Int = 0, - @Parameter( - names = ["--ind-frequency"], - description = "Frequency of induction check" - ) + @Parameter(names = ["--ind-frequency"], + description = "Frequency of induction check") var indFreq: Int = 1, ) : Config @@ -341,10 +313,8 @@ data class InterpolationConfig( @Parameter(names = ["--interpolation-solver", "--itp-solver"], description = "Interpolation solver name") var itpSolver: String = "Z3", - @Parameter( - names = ["--validate-interpolation-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-interpolation-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateItpSolver: Boolean = false, ) : Config @@ -419,10 +389,8 @@ data class WitnessConfig( @Parameter(names = ["--cex-solver"], description = "Concretizer solver name") var concretizerSolver: String = "Z3", - @Parameter( - names = ["--validate-cex-solver"], - description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues." - ) + @Parameter(names = ["--validate-cex-solver"], + description = "Activates a wrapper, which validates the assertions in the solver in each (SAT) check. Filters some solver issues.") var validateConcretizerSolver: Boolean = false ) : Config @@ -441,15 +409,11 @@ data class DebugConfig( @Parameter(names = ["--loglevel"], description = "Detailedness of logging") var logLevel: Logger.Level = Logger.Level.MAINSTEP, - @Parameter( - names = ["--arg-debug"], - description = "ARG debug mode (use the web-based debugger for ARG visualization)" - ) + @Parameter(names = ["--arg-debug"], + description = "ARG debug mode (use the web-based debugger for ARG visualization)") var argdebug: Boolean = false, - @Parameter( - names = ["--arg-to-file"], - description = "Visualize the resulting file here: https://ftsrg-edu.github.io/student-sisak-argviz/" - ) + @Parameter(names = ["--arg-to-file"], + description = "Visualize the resulting file here: https://ftsrg-edu.github.io/student-sisak-argviz/") var argToFile: Boolean = false ) : Config \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt index 2cb473abb9..787774d93f 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/bounded.kt @@ -38,8 +38,7 @@ fun boundedPortfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger -): STM { + uniqueLogger: Logger): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -48,14 +47,12 @@ fun boundedPortfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property - ), + property = portfolioConfig.inputConfig.property), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) - ), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), backendConfig = BackendConfig( backend = Backend.BOUNDED, solverHome = portfolioConfig.backendConfig.solverHome, @@ -65,8 +62,7 @@ fun boundedPortfolio( maxBound = 0, indConfig = InductionConfig(true), itpConfig = InterpolationConfig(true) - ) - ), + )), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -118,49 +114,40 @@ fun boundedPortfolio( timeoutMs: Long = 0, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, BoundedConfig> { - return copy( - backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - bmcConfig = backendConfig.specConfig!!.bmcConfig.copy(disable = !bmcEnabled, bmcSolver = bmcSolver), - indConfig = backendConfig.specConfig!!.indConfig.copy(disable = !indEnabled, indSolver = indSolver), - itpConfig = backendConfig.specConfig!!.itpConfig.copy(disable = !itpEnabled, itpSolver = itpSolver), - ) + return copy(backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + bmcConfig = backendConfig.specConfig!!.bmcConfig.copy(disable = !bmcEnabled, bmcSolver = bmcSolver), + indConfig = backendConfig.specConfig!!.indConfig.copy(disable = !indEnabled, indSolver = indSolver), + itpConfig = backendConfig.specConfig!!.itpConfig.copy(disable = !itpEnabled, itpSolver = itpSolver), ) - ) + )) } fun getStm(inProcess: Boolean): STM { val edges = LinkedHashSet() - val configBmcZ3 = ConfigNode( - "BmcZ3-$inProcess", + val configBmcZ3 = ConfigNode("BmcZ3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcEnabled = true, timeoutMs = 30000 - ), checker - ) - val configBmcMathsat = ConfigNode( - "BmcMathsat-$inProcess", + ), checker) + val configBmcMathsat = ConfigNode("BmcMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcSolver = "mathsat:5.6.10", bmcEnabled = true, timeoutMs = 30000 - ), checker - ) - val configIndZ3 = ConfigNode( - "IndZ3-$inProcess", + ), checker) + val configIndZ3 = ConfigNode("IndZ3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcEnabled = true, indEnabled = true, timeoutMs = 300000 - ), checker - ) - val configIndMathsat = ConfigNode( - "IndMathsat-$inProcess", + ), checker) + val configIndMathsat = ConfigNode("IndMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, bmcSolver = "mathsat:5.6.10", @@ -168,54 +155,33 @@ fun boundedPortfolio( bmcEnabled = true, indEnabled = true, timeoutMs = 300000 - ), checker - ) - val configItpCvc5 = ConfigNode( - "ItpCvc5-$inProcess", + ), checker) + val configItpCvc5 = ConfigNode("ItpCvc5-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, itpEnabled = true, itpSolver = "cvc5:1.0.8", timeoutMs = 0 - ), checker - ) - val configItpMathsat = ConfigNode( - "ItpMathsat-$inProcess", + ), checker) + val configItpMathsat = ConfigNode("ItpMathsat-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, itpSolver = "mathsat:5.6.10", itpEnabled = true, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(configBmcZ3, configBmcMathsat, solverError)) - edges.add( - Edge( - configBmcZ3, configIndZ3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - configBmcMathsat, configIndMathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) + edges.add(Edge(configBmcZ3, configIndZ3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(configBmcMathsat, configIndMathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) edges.add(Edge(configIndZ3, configIndMathsat, solverError)) - edges.add( - Edge( - configIndZ3, configItpCvc5, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - configIndMathsat, configItpCvc5, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) + edges.add(Edge(configIndZ3, configItpCvc5, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(configIndMathsat, configItpCvc5, + if (inProcess) timeoutOrNotSolvableError else anyError)) edges.add(Edge(configItpCvc5, configItpMathsat, anyError)) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt index 9c62a7e047..c6901d3838 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex23.kt @@ -29,13 +29,11 @@ import hu.bme.mit.theta.xcfa.model.XCFA import hu.bme.mit.theta.xcfa.passes.LbePass import java.nio.file.Paths -fun complexPortfolio23( - xcfa: XCFA, mcm: MCM, +fun complexPortfolio23(xcfa: XCFA, mcm: MCM, parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger -): STM { + uniqueLogger: Logger): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -44,14 +42,12 @@ fun complexPortfolio23( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property - ), + property = portfolioConfig.inputConfig.property), frontendConfig = FrontendConfig( lbeLevel = LbePass.LbeLevel.LBE_SEQ, loopUnroll = 50, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) - ), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -76,9 +72,7 @@ fun complexPortfolio23( refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ) - ) - ), + ))), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -98,8 +92,7 @@ fun complexPortfolio23( refinerConfig = baseCegarConfig.refinerConfig.copy(pruneStrategy = PruneStrategy.LAZY) ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) - ) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) } val timeoutTrigger = ExceptionTrigger( @@ -130,25 +123,23 @@ fun complexPortfolio23( validateRefinementSolver: Boolean = this.backendConfig.specConfig!!.refinerConfig.validateRefinementSolver, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, CegarConfig> { - return copy( - backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - initPrec = initPrec, - abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( - abstractionSolver = abstractionSolver, - validateAbstractionSolver = validateAbstractionSolver, - domain = domain, - ), - refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( - refinementSolver = refinementSolver, - validateRefinementSolver = validateRefinementSolver, - refinement = refinement, - ) + return copy(backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + initPrec = initPrec, + abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( + abstractionSolver = abstractionSolver, + validateAbstractionSolver = validateAbstractionSolver, + domain = domain, + ), + refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( + refinementSolver = refinementSolver, + validateRefinementSolver = validateRefinementSolver, + refinement = refinement, ) ) - ) + )) } val quickExplConfig = baseConfig.adaptConfig(initPrec = InitPrec.ALLVARS, timeoutMs = 90_000) @@ -157,92 +148,50 @@ fun complexPortfolio23( fun integerStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_z3_4.10.1_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "z3:4.10.1", + val config_1_1 = ConfigNode("QuickFullExpl_z3_4.10.1_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_2_1 = ConfigNode( - "EmptyExpl_z3_4.10.1_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinement = Refinement.NWT_IT_WP), checker) + val config_2_1 = ConfigNode("EmptyExpl_z3_4.10.1_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", refinementSolver = "z3:4.10.1", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_3_1 = ConfigNode( - "PredCart_z3_4.10.1_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "z3:4.10.1", - refinementSolver = "z3:4.10.1" - ), checker - ) - - val config_1_2 = ConfigNode( - "QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess), checker - ) - val config_2_2 = ConfigNode( - "EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess), - checker - ) - val config_3_2 = ConfigNode( - "PredCart_Z3_$inProcess", predConfig.adaptConfig(inProcess = inProcess), - checker - ) - - val config_1_3 = ConfigNode( - "QuickFullExpl_princess_2022_07_01_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01" - ), - checker - ) - val config_2_3 = ConfigNode( - "EmptyExpl_princess_2022_07_01_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01" - ), - checker - ) - val config_3_3 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8" - ), - checker - ) - - val config_1_4 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8" - ), - checker - ) - val config_2_4 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8" - ), - checker - ) - val config_3_4 = ConfigNode( - "PredCart_princess_2022_07_01_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "princess:2022-07-01", - refinementSolver = "princess:2022-07-01" - ), - checker - ) + refinement = Refinement.NWT_IT_WP), checker) + val config_3_1 = ConfigNode("PredCart_z3_4.10.1_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinementSolver = "z3:4.10.1"), checker) + + val config_1_2 = ConfigNode("QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess), checker) + val config_2_2 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess), + checker) + val config_3_2 = ConfigNode("PredCart_Z3_$inProcess", predConfig.adaptConfig(inProcess = inProcess), + checker) + + val config_1_3 = ConfigNode("QuickFullExpl_princess_2022_07_01_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01"), + checker) + val config_2_3 = ConfigNode("EmptyExpl_princess_2022_07_01_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01"), + checker) + val config_3_3 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8"), + checker) + + val config_1_4 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8"), + checker) + val config_2_4 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8"), + checker) + val config_3_4 = ConfigNode("PredCart_princess_2022_07_01_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "princess:2022-07-01", + refinementSolver = "princess:2022-07-01"), + checker) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -254,23 +203,15 @@ fun complexPortfolio23( Edge(config_1_3, config_2_3, timeoutTrigger), Edge(config_2_3, config_3_1, timeoutTrigger), - Edge( - config_1_4, config_2_4, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), - Edge( - config_2_4, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), + Edge(config_1_4, config_2_4, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge(config_2_4, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -288,10 +229,8 @@ fun complexPortfolio23( return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode( - "InProcess", - getStm(!portfolioConfig.debugConfig.debug) - ) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode("InProcess", + getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) @@ -301,72 +240,40 @@ fun complexPortfolio23( fun bitwiseStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), checker - ) - val config_2_1 = ConfigNode( - "EmptyExpl_Z3_$inProcess", + val config_1_1 = ConfigNode("QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), checker) + val config_2_1 = ConfigNode("EmptyExpl_Z3_$inProcess", emptyExplConfig.adaptConfig(inProcess = inProcess, refinement = Refinement.NWT_IT_WP), - checker - ) - val config_3_1 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8" - ), - checker - ) - - val config_1_2 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + checker) + val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8"), + checker) + + val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_2_2 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker) + val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_3_2 = ConfigNode( - "PredCart_z3_4.10.1_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "z3:4.10.1", - refinementSolver = "z3:4.10.1" - ), checker - ) + refinement = Refinement.NWT_IT_WP), checker) + val config_3_2 = ConfigNode("PredCart_z3_4.10.1_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "z3:4.10.1", + refinementSolver = "z3:4.10.1"), checker) - val config_1_3 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_2_3 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP), checker) + val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", - refinement = Refinement.SEQ_ITP - ), checker - ) - val config_3_3 = ConfigNode( - "PredCart_cvc5_1.0.2_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP), checker) + val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) + refinement = Refinement.NWT_IT_WP), checker) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -375,23 +282,15 @@ fun complexPortfolio23( Edge(config_1_2, config_2_2, timeoutTrigger), Edge(config_2_2, config_3_1, timeoutTrigger), - Edge( - config_1_3, config_2_3, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), - Edge( - config_2_3, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), + Edge(config_1_3, config_2_3, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge(config_2_3, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -406,10 +305,8 @@ fun complexPortfolio23( return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode( - "InProcess", - getStm(!portfolioConfig.debugConfig.debug) - ) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode("InProcess", + getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) @@ -419,134 +316,74 @@ fun complexPortfolio23( fun floatsStm(): STM { fun getStm(inProcess: Boolean): STM { - val config_1_1 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + val config_1_1 = ConfigNode("QuickFullExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_2_1 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker) + val config_2_1 = ConfigNode("EmptyExpl_cvc5_1.0.2_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_3_1 = ConfigNode( - "PredCart_mathsat_5.6.8_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", - refinementSolver = "mathsat:5.6.8" - ), - checker - ) - - val config_1_2 = ConfigNode( - "QuickFullExpl_cvc5_1.0.2_seq_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), checker) + val config_3_1 = ConfigNode("PredCart_mathsat_5.6.8_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinementSolver = "mathsat:5.6.8"), + checker) + + val config_1_2 = ConfigNode("QuickFullExpl_cvc5_1.0.2_seq_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP - ), checker - ) - val config_2_2 = ConfigNode( - "EmptyExpl_cvc5_1.0.2_seq_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.SEQ_ITP), checker) + val config_2_2 = ConfigNode("EmptyExpl_cvc5_1.0.2_seq_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.SEQ_ITP - ), checker - ) - val config_3_2 = ConfigNode( - "PredCart_bitwuzla_latest_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "bitwuzla:latest", + refinement = Refinement.SEQ_ITP), checker) + val config_3_2 = ConfigNode("PredCart_bitwuzla_latest_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "bitwuzla:latest", refinementSolver = "bitwuzla:latest", - refinement = Refinement.NWT_IT_WP - ), checker - ) + refinement = Refinement.NWT_IT_WP), checker) - val config_1_3 = ConfigNode( - "QuickFullExpl_mathsat_5.6.8_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + val config_1_3 = ConfigNode("QuickFullExpl_mathsat_5.6.8_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", validateAbstractionSolver = true, validateRefinementSolver = true, - refinement = Refinement.NWT_IT_WP - ), - checker - ) - val config_2_3 = ConfigNode( - "EmptyExpl_mathsat_5.6.8_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", + refinement = Refinement.NWT_IT_WP), + checker) + val config_2_3 = ConfigNode("EmptyExpl_mathsat_5.6.8_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:5.6.8", refinementSolver = "mathsat:5.6.8", validateAbstractionSolver = true, validateRefinementSolver = true, - refinement = Refinement.NWT_IT_WP - ), - checker - ) - val config_3_3 = ConfigNode( - "PredCart_cvc5_1.0.2_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", + refinement = Refinement.NWT_IT_WP), + checker) + val config_3_3 = ConfigNode("PredCart_cvc5_1.0.2_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "cvc5:1.0.2", refinementSolver = "cvc5:1.0.2", - refinement = Refinement.NWT_IT_WP - ), checker - ) + refinement = Refinement.NWT_IT_WP), checker) - val config_1_4 = ConfigNode( - "QuickFullExpl_mathsat_fp_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:fp", + val config_1_4 = ConfigNode("QuickFullExpl_mathsat_fp_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker - ) - val config_2_4 = ConfigNode( - "EmptyExpl_mathsat_fp_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true), checker) + val config_2_4 = ConfigNode("EmptyExpl_mathsat_fp_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker - ) - val config_3_4 = ConfigNode( - "PredCart_mathsat_fp_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "mathsat:fp", + validateAbstractionSolver = true, validateRefinementSolver = true), checker) + val config_3_4 = ConfigNode("PredCart_mathsat_fp_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "mathsat:fp", refinementSolver = "mathsat:fp", - validateAbstractionSolver = true, validateRefinementSolver = true - ), checker - ) + validateAbstractionSolver = true, validateRefinementSolver = true), checker) - val config_1_5 = ConfigNode( - "QuickFullExpl_Z3_$inProcess", - quickExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + val config_1_5 = ConfigNode("QuickFullExpl_Z3_$inProcess", + quickExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_2_5 = ConfigNode( - "EmptyExpl_Z3_$inProcess", - emptyExplConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker) + val config_2_5 = ConfigNode("EmptyExpl_Z3_$inProcess", + emptyExplConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", validateAbstractionSolver = true, - validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP - ), checker - ) - val config_3_5 = ConfigNode( - "PredCart_Z3_$inProcess", - predConfig.adaptConfig( - inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP - ), - checker - ) + validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP), checker) + val config_3_5 = ConfigNode("PredCart_Z3_$inProcess", + predConfig.adaptConfig(inProcess = inProcess, abstractionSolver = "Z3", refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP), + checker) val timeouts = setOf( Edge(config_1_1, config_2_1, timeoutTrigger), @@ -561,23 +398,15 @@ fun complexPortfolio23( Edge(config_1_4, config_2_4, timeoutTrigger), Edge(config_2_4, config_3_1, timeoutTrigger), - Edge( - config_1_5, config_2_5, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), - Edge( - config_2_5, config_3_1, - if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything") - ), + Edge(config_1_5, config_2_5, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), + Edge(config_2_5, config_3_1, + if (inProcess) timeoutOrSolverError else ExceptionTrigger(label = "Anything")), ) - val notTimeout = if (inProcess) ExceptionTrigger( - ErrorCodeException(ExitCodes.SOLVER_ERROR.code), - label = "SolverError" - ) else ExceptionTrigger( - fallthroughExceptions = timeoutTrigger.exceptions, - label = "AnythingButTimeout" - ) + val notTimeout = if (inProcess) ExceptionTrigger(ErrorCodeException(ExitCodes.SOLVER_ERROR.code), + label = "SolverError") else ExceptionTrigger(fallthroughExceptions = timeoutTrigger.exceptions, + label = "AnythingButTimeout") val solverExceptions = setOf( Edge(config_1_1, config_1_2, notTimeout), @@ -598,10 +427,8 @@ fun complexPortfolio23( return STM(config_1_1, timeouts union solverExceptions) } - val inProcess = HierarchicalNode( - "InProcess", - getStm(!portfolioConfig.debugConfig.debug) - ) // if not debug, then in process, else not in process + val inProcess = HierarchicalNode("InProcess", + getStm(!portfolioConfig.debugConfig.debug)) // if not debug, then in process, else not in process val notInProcess = HierarchicalNode("NotInprocess", getStm(false)) val fallbackEdge = Edge(inProcess, notInProcess, ExceptionTrigger(label = "Anything")) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt index 8a5c005c3e..ca6f147553 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/complex24.kt @@ -37,8 +37,7 @@ fun complexPortfolio24( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger -): STM { + uniqueLogger: Logger): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -47,14 +46,12 @@ fun complexPortfolio24( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property - ), + property = portfolioConfig.inputConfig.property), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) - ), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -78,9 +75,7 @@ fun complexPortfolio24( refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ) - ) - ), + ))), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -100,8 +95,7 @@ fun complexPortfolio24( abstractorConfig = baseCegarConfig.abstractorConfig.copy(search = Search.DFS), ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) - ) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) } if (!xcfa.isInlined) { @@ -146,31 +140,28 @@ fun complexPortfolio24( validateRefinementSolver: Boolean = this.backendConfig.specConfig!!.refinerConfig.validateRefinementSolver, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, CegarConfig> { - return copy( - backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - initPrec = initPrec, - abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( - abstractionSolver = abstractionSolver, - validateAbstractionSolver = validateAbstractionSolver, - domain = domain, - ), - refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( - refinementSolver = refinementSolver, - validateRefinementSolver = validateRefinementSolver, - refinement = refinement, - ) + return copy(backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + initPrec = initPrec, + abstractorConfig = backendConfig.specConfig!!.abstractorConfig.copy( + abstractionSolver = abstractionSolver, + validateAbstractionSolver = validateAbstractionSolver, + domain = domain, + ), + refinerConfig = backendConfig.specConfig!!.refinerConfig.copy( + refinementSolver = refinementSolver, + validateRefinementSolver = validateRefinementSolver, + refinement = refinement, ) ) - ) + )) } fun getStm(trait: ArithmeticTrait, inProcess: Boolean): STM { val edges = LinkedHashSet() - val config_BITWISE_EXPL_NWT_IT_WP_cvc5 = ConfigNode( - "BITWISE_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + val config_BITWISE_EXPL_NWT_IT_WP_cvc5 = ConfigNode("BITWISE_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -178,10 +169,8 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) - val config_BITWISE_EXPL_NWT_IT_WP_Z3 = ConfigNode( - "BITWISE_EXPL_NWT_IT_WP_Z3-$inProcess", + ), checker) + val config_BITWISE_EXPL_NWT_IT_WP_Z3 = ConfigNode("BITWISE_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -189,11 +178,9 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) + ), checker) edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_EXPL_NWT_IT_WP_Z3, solverError)) - val config_BITWISE_EXPL_NWT_IT_WP_mathsat = ConfigNode( - "BITWISE_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_BITWISE_EXPL_NWT_IT_WP_mathsat = ConfigNode("BITWISE_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -201,11 +188,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) + ), checker) edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_BITWISE_PRED_CART_SEQ_ITP_mathsat = ConfigNode( - "BITWISE_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_BITWISE_PRED_CART_SEQ_ITP_mathsat = ConfigNode("BITWISE_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -213,28 +198,14 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_BITWISE_EXPL_NWT_IT_WP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_BITWISE_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( - "BITWISE_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_cvc5, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_Z3, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_BITWISE_EXPL_NWT_IT_WP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) + val config_BITWISE_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("BITWISE_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -242,11 +213,9 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_BITWISE_EXPL_SEQ_ITP_mathsat = ConfigNode( - "BITWISE_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_BITWISE_EXPL_SEQ_ITP_mathsat = ConfigNode("BITWISE_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -254,22 +223,12 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_BITWISE_PRED_CART_SEQ_ITP_cvc5, config_BITWISE_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_BITWISE_EXPL_SEQ_ITP_cvc5 = ConfigNode( - "BITWISE_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_BITWISE_PRED_CART_SEQ_ITP_cvc5, config_BITWISE_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) + val config_BITWISE_EXPL_SEQ_ITP_cvc5 = ConfigNode("BITWISE_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -277,11 +236,9 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_BITWISE_EXPL_SEQ_ITP_mathsat, config_BITWISE_EXPL_SEQ_ITP_cvc5, solverError)) - val config_FLOAT_EXPL_NWT_IT_WP_cvc5 = ConfigNode( - "FLOAT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + val config_FLOAT_EXPL_NWT_IT_WP_cvc5 = ConfigNode("FLOAT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -289,21 +246,17 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 200000 - ), checker - ) - val config_FLOAT_EXPL_NWT_IT_WP_Z3 = ConfigNode( - "FLOAT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 200000 - ), checker - ) + ), checker) + val config_FLOAT_EXPL_NWT_IT_WP_Z3 = ConfigNode("FLOAT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 200000 + ), checker) edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_EXPL_NWT_IT_WP_Z3, solverError)) - val config_FLOAT_EXPL_NWT_IT_WP_mathsat = ConfigNode( - "FLOAT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_FLOAT_EXPL_NWT_IT_WP_mathsat = ConfigNode("FLOAT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -311,11 +264,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.NWT_IT_WP, timeoutMs = 200000 - ), checker - ) + ), checker) edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_FLOAT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( - "FLOAT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_FLOAT_PRED_CART_SEQ_ITP_mathsat = ConfigNode("FLOAT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -323,28 +274,14 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_FLOAT_EXPL_NWT_IT_WP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_FLOAT_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( - "FLOAT_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_cvc5, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_Z3, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_FLOAT_EXPL_NWT_IT_WP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) + val config_FLOAT_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("FLOAT_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -352,11 +289,9 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_FLOAT_EXPL_SEQ_ITP_mathsat = ConfigNode( - "FLOAT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_FLOAT_EXPL_SEQ_ITP_mathsat = ConfigNode("FLOAT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -364,22 +299,12 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", validateRefinementSolver = true, refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_FLOAT_PRED_CART_SEQ_ITP_cvc5, config_FLOAT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_FLOAT_EXPL_SEQ_ITP_cvc5 = ConfigNode( - "FLOAT_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_FLOAT_PRED_CART_SEQ_ITP_cvc5, config_FLOAT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) + val config_FLOAT_EXPL_SEQ_ITP_cvc5 = ConfigNode("FLOAT_EXPL_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -387,11 +312,9 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_FLOAT_EXPL_SEQ_ITP_mathsat, config_FLOAT_EXPL_SEQ_ITP_cvc5, solverError)) - val config_LIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode( - "LIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + val config_LIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode("LIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -399,10 +322,8 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) - val config_LIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode( - "LIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", + ), checker) + val config_LIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode("LIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -410,33 +331,21 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) + ), checker) edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_NWT_IT_WP_Z3, solverError)) - val config_LIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode( - "LIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.SEQ_ITP, - timeoutMs = 300000 - ), checker - ) - edges.add( - Edge( - config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_LIN_INT_EXPL_NWT_IT_WP_Z3, config_LIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_LIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode( - "LIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_LIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode("LIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.SEQ_ITP, + timeoutMs = 300000 + ), checker) + edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_mathsat, config_LIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_LIN_INT_EXPL_NWT_IT_WP_Z3, config_LIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError)) + val config_LIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode("LIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -444,11 +353,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 300000 - ), checker - ) + ), checker) edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_EXPL_SEQ_ITP_mathsat, solverError)) - val config_LIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode( - "LIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", + val config_LIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -456,22 +363,12 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_LIN_INT_EXPL_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_LIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( - "LIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", + ), checker) + edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_LIN_INT_EXPL_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError)) + val config_LIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -479,11 +376,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_LIN_INT_PRED_CART_SEQ_ITP_Z3, config_LIN_INT_PRED_CART_SEQ_ITP_mathsat, solverError)) - val config_LIN_INT_PRED_CART_SEQ_ITP_z3 = ConfigNode( - "LIN_INT_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + val config_LIN_INT_PRED_CART_SEQ_ITP_z3 = ConfigNode("LIN_INT_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -491,11 +386,9 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add(Edge(config_LIN_INT_PRED_CART_SEQ_ITP_mathsat, config_LIN_INT_PRED_CART_SEQ_ITP_z3, solverError)) - val config_NONLIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode( - "NONLIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", + val config_NONLIN_INT_EXPL_NWT_IT_WP_Z3 = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -503,10 +396,8 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) - val config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode( - "NONLIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", + ), checker) + val config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -514,11 +405,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) + ), checker) edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_NONLIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode( - "NONLIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", + val config_NONLIN_INT_EXPL_SEQ_ITP_Z3 = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -526,22 +415,12 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 100000 - ), checker - ) - edges.add( - Edge( - config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_NONLIN_INT_EXPL_SEQ_ITP_z3 = ConfigNode( - "NONLIN_INT_EXPL_SEQ_ITP_z3:4.12.2-$inProcess", + ), checker) + edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_NONLIN_INT_EXPL_NWT_IT_WP_mathsat, config_NONLIN_INT_EXPL_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError)) + val config_NONLIN_INT_EXPL_SEQ_ITP_z3 = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -549,11 +428,9 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 100000 - ), checker - ) + ), checker) edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_z3, solverError)) - val config_NONLIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode( - "NONLIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + val config_NONLIN_INT_EXPL_SEQ_ITP_mathsat = ConfigNode("NONLIN_INT_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -561,38 +438,23 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 200000 - ), checker - ) - edges.add( - Edge( - config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_NONLIN_INT_EXPL_SEQ_ITP_z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) + ), checker) + edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_z3, config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) val config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat = ConfigNode( "NONLIN_INT_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.SEQ_ITP, - timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode( - "NONLIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.SEQ_ITP, + timeoutMs = 0 + ), checker) + edges.add(Edge(config_NONLIN_INT_EXPL_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, + if (inProcess) timeoutOrSolverError else anyError)) + val config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3 = ConfigNode("NONLIN_INT_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -600,13 +462,10 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add( - Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, solverError) - ) - val config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5 = ConfigNode( - "NONLIN_INT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, solverError)) + val config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5 = ConfigNode("NONLIN_INT_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -614,22 +473,12 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_ARR_EXPL_NWT_IT_WP_cvc5 = ConfigNode( - "ARR_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_mathsat, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_NONLIN_INT_PRED_CART_SEQ_ITP_Z3, config_NONLIN_INT_EXPL_NWT_IT_WP_cvc5, + if (inProcess) timeoutOrSolverError else anyError)) + val config_ARR_EXPL_NWT_IT_WP_cvc5 = ConfigNode("ARR_EXPL_NWT_IT_WP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -637,43 +486,29 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.NWT_IT_WP, timeoutMs = 100000 - ), checker - ) - val config_ARR_EXPL_NWT_IT_WP_Z3 = ConfigNode( - "ARR_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 100000 - ), checker - ) + ), checker) + val config_ARR_EXPL_NWT_IT_WP_Z3 = ConfigNode("ARR_EXPL_NWT_IT_WP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 100000 + ), checker) edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_EXPL_NWT_IT_WP_Z3, solverError)) - val config_ARR_PRED_CART_SEQ_ITP_Z3 = ConfigNode( - "ARR_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "Z3", - refinementSolver = "Z3", - refinement = Refinement.SEQ_ITP, - timeoutMs = 300000 - ), checker - ) - edges.add( - Edge( - config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_ARR_EXPL_NWT_IT_WP_Z3, config_ARR_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_ARR_PRED_CART_SEQ_ITP_z3 = ConfigNode( - "ARR_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + val config_ARR_PRED_CART_SEQ_ITP_Z3 = ConfigNode("ARR_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "Z3", + refinementSolver = "Z3", + refinement = Refinement.SEQ_ITP, + timeoutMs = 300000 + ), checker) + edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_cvc5, config_ARR_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_ARR_EXPL_NWT_IT_WP_Z3, config_ARR_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError)) + val config_ARR_PRED_CART_SEQ_ITP_z3 = ConfigNode("ARR_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -681,11 +516,9 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 300000 - ), checker - ) + ), checker) edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_z3, solverError)) - val config_ARR_PRED_CART_SEQ_ITP_princess = ConfigNode( - "ARR_PRED_CART_SEQ_ITP_princess:2023-06-19-$inProcess", + val config_ARR_PRED_CART_SEQ_ITP_princess = ConfigNode("ARR_PRED_CART_SEQ_ITP_princess:2023-06-19-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -693,22 +526,12 @@ fun complexPortfolio24( refinementSolver = "princess:2023-06-19", refinement = Refinement.SEQ_ITP, timeoutMs = 500000 - ), checker - ) - edges.add( - Edge( - config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_princess, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_ARR_PRED_CART_SEQ_ITP_z3, config_ARR_PRED_CART_SEQ_ITP_princess, - if (inProcess) timeoutOrSolverError else anyError - ) - ) - val config_ARR_PRED_CART_SEQ_ITP_cvc5 = ConfigNode( - "ARR_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", + ), checker) + edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_Z3, config_ARR_PRED_CART_SEQ_ITP_princess, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_z3, config_ARR_PRED_CART_SEQ_ITP_princess, + if (inProcess) timeoutOrSolverError else anyError)) + val config_ARR_PRED_CART_SEQ_ITP_cvc5 = ConfigNode("ARR_PRED_CART_SEQ_ITP_cvc5:1.0.8-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -716,11 +539,9 @@ fun complexPortfolio24( refinementSolver = "cvc5:1.0.8", refinement = Refinement.SEQ_ITP, timeoutMs = 500000 - ), checker - ) + ), checker) edges.add(Edge(config_ARR_PRED_CART_SEQ_ITP_princess, config_ARR_PRED_CART_SEQ_ITP_cvc5, solverError)) - val config_MULTITHREAD_EXPL_SEQ_ITP_Z3 = ConfigNode( - "MULTITHREAD_EXPL_SEQ_ITP_Z3-$inProcess", + val config_MULTITHREAD_EXPL_SEQ_ITP_Z3 = ConfigNode("MULTITHREAD_EXPL_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -728,10 +549,8 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 150000 - ), checker - ) - val config_MULTITHREAD_EXPL_SEQ_ITP_mathsat = ConfigNode( - "MULTITHREAD_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", + ), checker) + val config_MULTITHREAD_EXPL_SEQ_ITP_mathsat = ConfigNode("MULTITHREAD_EXPL_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -739,11 +558,9 @@ fun complexPortfolio24( refinementSolver = "mathsat:5.6.10", refinement = Refinement.SEQ_ITP, timeoutMs = 150000 - ), checker - ) + ), checker) edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, solverError)) - val config_MULTITHREAD_EXPL_NWT_IT_WP_z3 = ConfigNode( - "MULTITHREAD_EXPL_NWT_IT_WP_z3:4.12.2-$inProcess", + val config_MULTITHREAD_EXPL_NWT_IT_WP_z3 = ConfigNode("MULTITHREAD_EXPL_NWT_IT_WP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.EXPL, @@ -751,33 +568,22 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.NWT_IT_WP, timeoutMs = 300000 - ), checker - ) - edges.add( - Edge( - config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) + ), checker) + edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_Z3, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_MULTITHREAD_EXPL_SEQ_ITP_mathsat, config_MULTITHREAD_EXPL_NWT_IT_WP_z3, + if (inProcess) timeoutOrSolverError else anyError)) val config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat = ConfigNode( "MULTITHREAD_EXPL_NWT_IT_WP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.EXPL, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.NWT_IT_WP, - timeoutMs = 300000 - ), checker - ) + inProcess = inProcess, + domain = Domain.EXPL, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.NWT_IT_WP, + timeoutMs = 300000 + ), checker) edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, solverError)) - val config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3 = ConfigNode( - "MULTITHREAD_PRED_CART_SEQ_ITP_Z3-$inProcess", + val config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3 = ConfigNode("MULTITHREAD_PRED_CART_SEQ_ITP_Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -785,35 +591,23 @@ fun complexPortfolio24( refinementSolver = "Z3", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) - edges.add( - Edge( - config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrNotSolvableError else anyError - ) - ) - edges.add( - Edge( - config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, - if (inProcess) timeoutOrSolverError else anyError - ) - ) + ), checker) + edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrNotSolvableError else anyError)) + edges.add(Edge(config_MULTITHREAD_EXPL_NWT_IT_WP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, + if (inProcess) timeoutOrSolverError else anyError)) val config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat = ConfigNode( "MULTITHREAD_PRED_CART_SEQ_ITP_mathsat:5.6.10-$inProcess", baseConfig.adaptConfig( - inProcess = inProcess, - domain = Domain.PRED_CART, - abstractionSolver = "mathsat:5.6.10", - refinementSolver = "mathsat:5.6.10", - refinement = Refinement.SEQ_ITP, - timeoutMs = 0 - ), checker - ) + inProcess = inProcess, + domain = Domain.PRED_CART, + abstractionSolver = "mathsat:5.6.10", + refinementSolver = "mathsat:5.6.10", + refinement = Refinement.SEQ_ITP, + timeoutMs = 0 + ), checker) edges.add( - Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, solverError) - ) - val config_MULTITHREAD_PRED_CART_SEQ_ITP_z3 = ConfigNode( - "MULTITHREAD_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", + Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_Z3, config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, solverError)) + val config_MULTITHREAD_PRED_CART_SEQ_ITP_z3 = ConfigNode("MULTITHREAD_PRED_CART_SEQ_ITP_z3:4.12.2-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, domain = Domain.PRED_CART, @@ -821,11 +615,9 @@ fun complexPortfolio24( refinementSolver = "z3:4.12.2", refinement = Refinement.SEQ_ITP, timeoutMs = 0 - ), checker - ) + ), checker) edges.add( - Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_z3, solverError) - ) + Edge(config_MULTITHREAD_PRED_CART_SEQ_ITP_mathsat, config_MULTITHREAD_PRED_CART_SEQ_ITP_z3, solverError)) if (trait == ArithmeticTrait.BITWISE) { return STM(config_BITWISE_EXPL_NWT_IT_WP_cvc5, edges) } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt index 1a56abd89c..5a3933b59c 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/horn.kt @@ -34,8 +34,7 @@ fun hornPortfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger -): STM { + uniqueLogger: Logger): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -44,14 +43,12 @@ fun hornPortfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property - ), + property = portfolioConfig.inputConfig.property), frontendConfig = FrontendConfig( lbeLevel = LbePass.level, loopUnroll = LoopUnrollPass.UNROLL_LIMIT, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) - ), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), backendConfig = BackendConfig( backend = Backend.CHC, solverHome = portfolioConfig.backendConfig.solverHome, @@ -59,8 +56,7 @@ fun hornPortfolio( specConfig = HornConfig( solver = "z3:4.13.0", validateSolver = false - ) - ), + )), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -107,42 +103,34 @@ fun hornPortfolio( timeoutMs: Long = 0, inProcess: Boolean = this.backendConfig.inProcess ): XcfaConfig<*, HornConfig> { - return copy( - backendConfig = backendConfig.copy( - timeoutMs = timeoutMs, - inProcess = inProcess, - specConfig = backendConfig.specConfig!!.copy( - solver = solver, - ) + return copy(backendConfig = backendConfig.copy( + timeoutMs = timeoutMs, + inProcess = inProcess, + specConfig = backendConfig.specConfig!!.copy( + solver = solver, ) - ) + )) } fun getStm(inProcess: Boolean): STM { val edges = LinkedHashSet() - val configZ3 = ConfigNode( - "Z3-$inProcess", + val configZ3 = ConfigNode("Z3-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, timeoutMs = 100_000 - ), checker - ) - val configEldarica = ConfigNode( - "Eldarica-$inProcess", + ), checker) + val configEldarica = ConfigNode("Eldarica-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, solver = "eldarica:2.1", timeoutMs = 500_000 - ), checker - ) - val configGolem = ConfigNode( - "Golem-$inProcess", + ), checker) + val configGolem = ConfigNode("Golem-$inProcess", baseConfig.adaptConfig( inProcess = inProcess, solver = "golem:0.5.0", timeoutMs = 300_000 - ), checker - ) + ), checker) edges.add(Edge(configZ3, configEldarica, anyError)) edges.add(Edge(configEldarica, configGolem, anyError)) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt index 27d08a1c2b..d98b44e8f9 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/portfolio/stm.kt @@ -36,10 +36,8 @@ ${innerSTM.visualize()} }""".trimIndent() } -class ConfigNode( - name: String, private val config: XcfaConfig<*, *>, - private val check: (config: XcfaConfig<*, *>) -> SafetyResult<*, *> -) : Node(name) { +class ConfigNode(name: String, private val config: XcfaConfig<*, *>, + private val check: (config: XcfaConfig<*, *>) -> SafetyResult<*, *>) : Node(name) { override fun execute(): Pair { println("Current configuration: $config") @@ -50,12 +48,10 @@ class ConfigNode( .map { "state ${name.replace(Regex("[:\\.-]+"), "_")}: $it" }.reduce { a, b -> "$a\n$b" } } -data class Edge( - val source: Node, +data class Edge(val source: Node, val target: Node, val trigger: (Throwable) -> Boolean, - val guard: (Node, Edge) -> Boolean = { _, _ -> true } -) { + val guard: (Node, Edge) -> Boolean = { _, _ -> true }) { init { source.outEdges.add(this) @@ -74,10 +70,8 @@ class ExceptionTrigger( val label: String? = null ) : (Throwable) -> Boolean { - constructor(vararg exceptions: Throwable, label: String? = null) : this( - exceptions.toSet(), - label = label - ) + constructor(vararg exceptions: Throwable, label: String? = null) : this(exceptions.toSet(), + label = label) override fun invoke(e: Throwable): Boolean = if (exceptions.isNotEmpty()) @@ -95,8 +89,7 @@ data class STM(val initNode: Node, val edges: Set) { val nodes = edges.map { listOf(it.source, it.target) }.flatten().toSet() nodes.forEach { check( - it.parent == null || it.parent === this - ) { "Edges to behave encapsulated (offender: $it)" } + it.parent == null || it.parent === this) { "Edges to behave encapsulated (offender: $it)" } it.parent = this } } @@ -123,11 +116,9 @@ ${edges.map { it.visualize() }.reduce { a, b -> "$a\n$b" }} println("Handling exception as ${edge.trigger}") currentNode = edge.target } else { - println( - "Could not handle trigger $e (Available triggers: ${ - currentNode.outEdges.map { it.trigger }.toList() - })" - ) + println("Could not handle trigger $e (Available triggers: ${ + currentNode.outEdges.map { it.trigger }.toList() + })") throw e } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt index 8ef9ed0318..ad9011bd82 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/GsonUtils.kt @@ -76,40 +76,30 @@ private fun traceHelper(stateType: java.lang.reflect.Type): java.lang.reflect.Ty ).type @JvmOverloads -internal fun getGson( - xcfa: XCFA, domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") } -): Gson { +internal fun getGson(xcfa: XCFA, domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") }): Gson { val (scope, env) = xcfa.getSymbols() return getGson(scope, env, false, domain, solver) } @JvmOverloads -internal fun getGson( - domain: () -> Domain = { error("Domain needs to be specified.") }, - solver: () -> Solver = { error("Solver is necessary.") } -): Gson { +internal fun getGson(domain: () -> Domain = { error("Domain needs to be specified.") }, + solver: () -> Solver = { error("Solver is necessary.") }): Gson { return getGson(XcfaScope(SymbolTable()), Env(), true, domain, solver) } -private fun getGson( - scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> Domain, - solver: () -> Solver -): Gson { +private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean, domain: () -> Domain, + solver: () -> Solver): Gson { val gsonBuilder = GsonBuilder() lateinit var gson: Gson gsonBuilder.registerTypeHierarchyAdapter(FrontendConfig::class.java, SpecFrontendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(BackendConfig::class.java, SpecBackendConfigTypeAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(File::class.java, StringTypeAdapter { File(it) }) - gsonBuilder.registerTypeHierarchyAdapter( - XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter) - ) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, + StringTypeAdapter(xcfaLocationAdapter)) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter( - VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope) - ) + gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, + VarDeclAdapter({ gson }, scope, env, !newScope)) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -119,14 +109,10 @@ private fun getGson( gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) gsonBuilder.registerTypeHierarchyAdapter(ExplState::class.java, ExplStateAdapter(scope, env)) - gsonBuilder.registerTypeHierarchyAdapter( - PredState::class.java, - PredStateAdapter({ gson }, scope, env) - ) - gsonBuilder.registerTypeHierarchyAdapter( - XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson }) - ) + gsonBuilder.registerTypeHierarchyAdapter(PredState::class.java, + PredStateAdapter({ gson }, scope, env)) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, + XcfaLabelAdapter(scope, env, { gson })) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) @@ -134,19 +120,15 @@ private fun getGson( XcfaStateAdapter({ gson }) { domain().stateType }) gsonBuilder.registerTypeHierarchyAdapter(XcfaAction::class.java, XcfaActionAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Trace::class.java, TraceAdapter({ gson }, { - TypeToken.getParameterized( - TypeToken.get(XcfaState::class.java).type, - domain().stateType - ).type + TypeToken.getParameterized(TypeToken.get(XcfaState::class.java).type, + domain().stateType).type }, TypeToken.get(XcfaAction::class.java).type)) gsonBuilder.registerTypeHierarchyAdapter(ARG::class.java, ArgAdapter({ gson }, { domain().partialOrd(solver()) }, - { argAdapterHelper(domain().stateType) }) - ) + { argAdapterHelper(domain().stateType) })) gsonBuilder.registerTypeHierarchyAdapter(SafetyResult::class.java, SafetyResultAdapter({ gson }, { argHelper(domain().stateType) }, - { traceHelper(domain().stateType) }) - ) + { traceHelper(domain().stateType) })) gsonBuilder.registerTypeHierarchyAdapter(ParseContext::class.java, ParseContextAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(FrontendMetadata::class.java, diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt index cc3c24338d..c053280a14 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/PropertyUtils.kt @@ -36,10 +36,8 @@ fun determineProperty(config: XcfaConfig<*, *>, logger: Logger): ErrorDetection } else -> { - logger.write( - Logger.Level.INFO, - "Unknown property $propertyFile, using full state space exploration (no refinement)\n" - ) + logger.write(Logger.Level.INFO, + "Unknown property $propertyFile, using full state space exploration (no refinement)\n") ErrorDetection.NO_ERROR } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt index a987f153d7..cb18d5c237 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaParser.kt @@ -46,17 +46,13 @@ fun getXcfa(config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger when (config.frontendConfig.inputType) { InputType.CHC -> { val chcConfig = config.frontendConfig.specConfig as CHCFrontendConfig - parseChc( - config.inputConfig.input!!, chcConfig.chcTransformation, parseContext, logger, - uniqueWarningLogger - ) + parseChc(config.inputConfig.input!!, chcConfig.chcTransformation, parseContext, logger, + uniqueWarningLogger) } InputType.C -> { - parseC( - config.inputConfig.input!!, config.inputConfig.property, parseContext, logger, - uniqueWarningLogger - ) + parseC(config.inputConfig.input!!, config.inputConfig.property, parseContext, logger, + uniqueWarningLogger) } InputType.LLVM -> XcfaUtils.fromFile(config.inputConfig.input!!, ArithmeticType.efficient) @@ -80,65 +76,48 @@ fun getXcfa(config: XcfaConfig<*, *>, parseContext: ParseContext, logger: Logger exitProcess(ExitCodes.FRONTEND_FAILED.code) } -private fun parseC( - input: File, explicitProperty: ErrorDetection, parseContext: ParseContext, logger: Logger, - uniqueWarningLogger: Logger -): XCFA { +private fun parseC(input: File, explicitProperty: ErrorDetection, parseContext: ParseContext, logger: Logger, + uniqueWarningLogger: Logger): XCFA { val xcfaFromC = try { val stream = FileInputStream(input) - getXcfaFromC( - stream, parseContext, false, - explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger - ).first + getXcfaFromC(stream, parseContext, false, + explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger).first } catch (e: Throwable) { if (parseContext.arithmetic == ArchitectureConfig.ArithmeticType.efficient) { parseContext.arithmetic = ArchitectureConfig.ArithmeticType.bitvector logger.write(Logger.Level.INFO, "Retrying parsing with bitvector arithmetic...\n") val stream = FileInputStream(input) - val xcfa = getXcfaFromC( - stream, parseContext, false, - explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger - ).first + val xcfa = getXcfaFromC(stream, parseContext, false, + explicitProperty == ErrorDetection.OVERFLOW, uniqueWarningLogger).first parseContext.addArithmeticTrait(ArithmeticTrait.BITWISE) xcfa } else { throw e } } - logger.write( - Logger.Level.RESULT, - "Arithmetic: ${parseContext.arithmeticTraits}\n" - ) + logger.write(Logger.Level.RESULT, + "Arithmetic: ${parseContext.arithmeticTraits}\n") return xcfaFromC } -private fun parseChc( - input: File, chcTransformation: ChcFrontend.ChcTransformation, parseContext: ParseContext, - logger: Logger, uniqueWarningLogger: Logger -): XCFA { +private fun parseChc(input: File, chcTransformation: ChcFrontend.ChcTransformation, parseContext: ParseContext, + logger: Logger, uniqueWarningLogger: Logger): XCFA { var chcFrontend: ChcFrontend - val xcfaBuilder = - if (chcTransformation == ChcFrontend.ChcTransformation.PORTFOLIO) { // try forward, fallback to backward - chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.FORWARD) - try { - chcFrontend.buildXcfa( - CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger) - ) - } catch (e: UnsupportedOperationException) { - logger.write(Logger.Level.INFO, "Non-linear CHC found, retrying using backward transformation...\n") - chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.BACKWARD) - chcFrontend.buildXcfa( - CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger) - ) - } - } else { - chcFrontend = ChcFrontend(chcTransformation) - chcFrontend.buildXcfa( - CharStreams.fromStream(FileInputStream(input)), - ChcPasses(parseContext, uniqueWarningLogger) - ) + val xcfaBuilder = if (chcTransformation == ChcFrontend.ChcTransformation.PORTFOLIO) { // try forward, fallback to backward + chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.FORWARD) + try { + chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger)) + } catch (e: UnsupportedOperationException) { + logger.write(Logger.Level.INFO, "Non-linear CHC found, retrying using backward transformation...\n") + chcFrontend = ChcFrontend(ChcFrontend.ChcTransformation.BACKWARD) + chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger)) } + } else { + chcFrontend = ChcFrontend(chcTransformation) + chcFrontend.buildXcfa(CharStreams.fromStream(FileInputStream(input)), + ChcPasses(parseContext, uniqueWarningLogger)) + } return xcfaBuilder.build() } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt index 5ad00f3717..722fa7d91d 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/utils/XcfaWitnessWriter.kt @@ -47,8 +47,7 @@ class XcfaWitnessWriter { if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex is Trace<*, *>) { val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, cexSolverFactory, - parseContext - ) + parseContext) val witnessTrace = traceToWitness(trace = concrTrace, parseContext = parseContext) val witness = Witness(witnessTrace, inputFile) @@ -58,93 +57,63 @@ class XcfaWitnessWriter { val taskHash = WitnessWriter.createTaskHash(inputFile.absolutePath) val dummyWitness = StringBuilder() dummyWitness.append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "false" - ).append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "" - ) + "false").append(System.lineSeparator()).append( + "").append(System.lineSeparator()).append( + "") .append(System.lineSeparator()).append( - "false" - ).append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "" - ) + "false").append(System.lineSeparator()).append( + "").append(System.lineSeparator()).append( + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ) + "") .append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "correctness_witness" - ) + "").append(System.lineSeparator()).append( + "correctness_witness") .append(System.lineSeparator()).append( - "theta" - ).append(System.lineSeparator()).append( - "CHECK( init(main()), LTL(G ! call(reach_error())) )" - ) + "theta").append(System.lineSeparator()).append( + "CHECK( init(main()), LTL(G ! call(reach_error())) )") .append(System.lineSeparator()).append( - "C" - ).append(System.lineSeparator()).append( - "32bit" - ).append(System.lineSeparator()) + "C").append(System.lineSeparator()).append( + "32bit").append(System.lineSeparator()) .append( - "" - ) + "") dummyWitness.append(taskHash) dummyWitness.append("").append(System.lineSeparator()).append( - "" - ) + "") val tz: TimeZone = TimeZone.getTimeZone("UTC") val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'" - ) // Quoted "Z" to indicate UTC, no timezone offset + "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset df.timeZone = tz val isoDate: String = df.format(Date()) dummyWitness.append(isoDate) dummyWitness.append("").append(System.lineSeparator()).append( - "" - ) + "") dummyWitness.append(inputFile.name) dummyWitness.append("").append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "true" - ).append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "" - ).append(System.lineSeparator()).append( - "" - ) + "").append(System.lineSeparator()).append( + "true").append(System.lineSeparator()).append( + "").append(System.lineSeparator()).append( + "").append(System.lineSeparator()).append( + "") try { BufferedWriter(FileWriter(witnessfile)).use { bw -> diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt index d6848feffe..38ab39f52b 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/TraceToWitness.kt @@ -46,10 +46,8 @@ fun traceToWitness( val newStates = ArrayList() val newActions = ArrayList() - var lastNode = WitnessNode( - id = "N${newStates.size}", entry = true, sink = false, - violation = false - ) + var lastNode = WitnessNode(id = "N${newStates.size}", entry = true, sink = false, + violation = false) newStates.add(lastNode) for (i in 0 until trace.length()) { @@ -69,10 +67,8 @@ fun traceToWitness( ) if (node != WitnessNode(id = "N${newStates.size}")) { newStates.add(node) - val edge = WitnessEdge( - sourceId = lastNode.id, targetId = node.id, - threadId = trace.actions[i].pid.toString() - ) + val edge = WitnessEdge(sourceId = lastNode.id, targetId = node.id, + threadId = trace.actions[i].pid.toString()) newActions.add(edge) lastNode = node } @@ -80,14 +76,10 @@ fun traceToWitness( val action = trace.actions[i] val flattenedSequence = flattenSequence(action.edge.label) for (xcfaLabel in flattenedSequence) { - val node = WitnessNode( - id = "N${newStates.size}", entry = false, sink = false, - violation = false - ) - var edge = labelToEdge( - lastNode, node, xcfaLabel, action.pid, - nextState.sGlobal.getVal(), parseContext - ) + val node = WitnessNode(id = "N${newStates.size}", entry = false, sink = false, + violation = false) + var edge = labelToEdge(lastNode, node, xcfaLabel, action.pid, + nextState.sGlobal.getVal(), parseContext) if (newThreads.isNotEmpty() && xcfaLabel is StartLabel) { edge = edge.copy(createThread = newThreads.joinToString(",")) } @@ -128,10 +120,8 @@ fun shouldInclude(edge: WitnessEdge, verbosity: Verbosity): Boolean = } -private fun labelToEdge( - lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, - valuation: Valuation, parseContext: ParseContext -): WitnessEdge = +private fun labelToEdge(lastNode: WitnessNode, node: WitnessNode, xcfaLabel: XcfaLabel, pid: Int, + valuation: Valuation, parseContext: ParseContext): WitnessEdge = WitnessEdge( sourceId = lastNode.id, targetId = node.id, @@ -200,17 +190,14 @@ private fun printLit(litExpr: LitExpr<*>): String? { for (i in boolList.indices) { if (i % 4 == 0 && i > 0) { if (aggregate < 10) hexDigits.add( - ('0'.code + aggregate).toChar() - ) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar() - ) + ('0'.code + aggregate).toChar()) else hexDigits.add( + ('A'.code - 10 + aggregate).toChar()) aggregate = 0 } if (boolList[i]) aggregate += 1 shl i % 4 } if (aggregate < 10) hexDigits.add(('0'.code + aggregate).toChar()) else hexDigits.add( - ('A'.code - 10 + aggregate).toChar() - ) + ('A'.code - 10 + aggregate).toChar()) val stringBuilder = StringBuilder("0x") for (character in Lists.reverse(hexDigits)) { stringBuilder.append(character) diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt index 4bcbcc99bb..4569a1b557 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/witnesses/Witness.kt @@ -59,12 +59,8 @@ class Witness(private val trace: Trace, programFile: F attributes.add(WitnessAttribute("assumption", "string", "edge", "assumption")) attributes.add(WitnessAttribute("assumption.scope", "string", "edge", "assumption.scope")) - attributes.add( - WitnessAttribute( - "assumption.resultfunction", "string", "edge", - "assumption.resultfunction" - ) - ) + attributes.add(WitnessAttribute("assumption.resultfunction", "string", "edge", + "assumption.resultfunction")) attributes.add(WitnessAttribute("control", "string", "edge", "control")) attributes.add(WitnessAttribute("startline", "string", "edge", "startline")) attributes.add(WitnessAttribute("endline", "string", "edge", "endline")) @@ -73,8 +69,7 @@ class Witness(private val trace: Trace, programFile: F attributes.add(WitnessAttribute("enterLoopHead", "string", "edge", "enterLoopHead")) attributes.add(WitnessAttribute("enterFunction", "string", "edge", "enterFunction")) attributes.add( - WitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction") - ) + WitnessAttribute("returnFromFunction", "string", "edge", "returnFromFunction")) attributes.add(WitnessAttribute("threadId", "string", "edge", "threadId")) attributes.add(WitnessAttribute("createThread", "string", "edge", "createThread")) attributes.add(WitnessAttribute("stmt", "string", "edge", "stmt")) @@ -276,8 +271,7 @@ private fun bytesToHex(hash: ByteArray): String { private fun getIsoDate(): String { val tz: TimeZone = TimeZone.getTimeZone("UTC") val df: DateFormat = SimpleDateFormat( - "yyyy-MM-dd'T'HH:mm:ss'Z'" - ) // Quoted "Z" to indicate UTC, no timezone offset + "yyyy-MM-dd'T'HH:mm:ss'Z'") // Quoted "Z" to indicate UTC, no timezone offset df.timeZone = tz return df.format(Date()) @@ -287,8 +281,7 @@ private fun getIsoDate(): String { private fun prettyFormat(input: String, indent: Int): String { return try { val xmlInput: Source = StreamSource( - StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), "")) - ) + StringReader(input.replace(Regex("( )|[\\t\\n\\r]"), ""))) val stringWriter = StringWriter() val xmlOutput = StreamResult(stringWriter) val transformerFactory: TransformerFactory = TransformerFactory.newInstance() diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt index d886fe23dd..a6aa6b8bb5 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliParseTest.kt @@ -169,14 +169,12 @@ class XcfaCliParseTest { @ParameterizedTest @MethodSource("cFiles") fun testCParse(filePath: String) { - main( - arrayOf( - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", "--stacktrace", + "--debug" + )) } // @ParameterizedTest @@ -194,71 +192,61 @@ class XcfaCliParseTest { @ParameterizedTest @MethodSource("chcFiles") fun testCHCParse(filePath: String, chcTransformation: ChcFrontend.ChcTransformation) { - main( - arrayOf( - "--input-type", "CHC", - "--chc-transformation", chcTransformation.toString(), - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "CHC", + "--chc-transformation", chcTransformation.toString(), + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + )) } @ParameterizedTest @MethodSource("dslFiles") fun testDSLParse(filePath: String) { - main( - arrayOf( - "--input-type", "DSL", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "DSL", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + )) } @ParameterizedTest @MethodSource("jsonFiles") fun testJSONParse(filePath: String) { - main( - arrayOf( - "--input-type", "JSON", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "JSON", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--debug" + )) } @ParameterizedTest @MethodSource("cFiles") fun testJSONParseRoundTrip(filePath: String) { val temp = createTempDirectory() - main( - arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - ) - ) + main(arrayOf( + "--enable-output", + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--output-directory", temp.toAbsolutePath().toString(), + "--debug" + )) val xcfaJson = temp.resolve("xcfa.json").toFile() - main( - arrayOf( - "--input-type", "JSON", - "--input", xcfaJson.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "JSON", + "--input", xcfaJson.absolutePath.toString(), + "--backend", "NONE", + "--stacktrace", + "--debug" + )) temp.toFile().deleteRecursively() } @@ -266,28 +254,24 @@ class XcfaCliParseTest { @MethodSource("simpleCFiles") fun testCParseRoundTrip(filePath: String) { val temp = createTempDirectory() - main( - arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - "--backend", "NONE", - "--stacktrace", - "--output-directory", temp.toAbsolutePath().toString(), - "--debug" - ) - ) + main(arrayOf( + "--enable-output", + "--input-type", "C", + "--input", javaClass.getResource(filePath)!!.path, + "--backend", "NONE", + "--stacktrace", + "--output-directory", temp.toAbsolutePath().toString(), + "--debug" + )) val xcfaC = temp.resolve("xcfa.c").toFile() checkState(xcfaC.exists(), "File does not exist: $xcfaC") - main( - arrayOf( - "--input-type", "C", - "--input", xcfaC.absolutePath.toString(), - "--backend", "NONE", - "--stacktrace", - "--debug" - ) - ) + main(arrayOf( + "--input-type", "C", + "--input", xcfaC.absolutePath.toString(), + "--backend", "NONE", + "--stacktrace", + "--debug" + )) temp.toFile().deleteRecursively() } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt index d7838c0403..9d9dc0e0f2 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliPortfolioTest.kt @@ -63,23 +63,17 @@ class XcfaCliPortfolioTest { @ParameterizedTest @MethodSource("portfolios") - fun testPortfolio( - portfolio: ( - xcfa: XCFA, - mcm: MCM, - parseContext: ParseContext, - portfolioConfig: XcfaConfig<*, *>, - logger: Logger, - uniqueLogger: Logger - ) -> STM - ) { + fun testPortfolio(portfolio: (xcfa: XCFA, + mcm: MCM, + parseContext: ParseContext, + portfolioConfig: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger) -> STM) { for (value in ArithmeticTrait.values()) { - val stm = portfolio( - XCFA("name", setOf()), emptySet(), ParseContext(), - XcfaConfig(), NullLogger.getInstance(), NullLogger.getInstance() - ) + val stm = portfolio(XCFA("name", setOf()), emptySet(), ParseContext(), + XcfaConfig(), NullLogger.getInstance(), NullLogger.getInstance()) Assertions.assertTrue(stm.visualize().isNotEmpty()) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt index 8b1c73b540..c5fb4dbb56 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliVerifyTest.kt @@ -144,10 +144,8 @@ class XcfaCliVerifyTest { fun chcFiles(): Stream { return Stream.of( Arguments.of("/chc/chc-LIA-Lin_000.smt2", ChcFrontend.ChcTransformation.FORWARD, "--domain PRED_CART"), - Arguments.of( - "/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD, - "--domain PRED_CART --search BFS" - ), + Arguments.of("/chc/chc-LIA-Arrays_000.smt2", ChcFrontend.ChcTransformation.BACKWARD, + "--domain PRED_CART --search BFS"), ) } } @@ -245,16 +243,14 @@ class XcfaCliVerifyTest { @ParameterizedTest @MethodSource("chcFiles") fun testCHCVerify(filePath: String, chcTransformation: ChcFrontend.ChcTransformation, extraArgs: String?) { - main( - arrayOf( - "--input-type", "CHC", - "--chc-transformation", chcTransformation.toString(), - "--input", javaClass.getResource(filePath)!!.path, - "--stacktrace", - *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), - "--debug" - ) - ) + main(arrayOf( + "--input-type", "CHC", + "--chc-transformation", chcTransformation.toString(), + "--input", javaClass.getResource(filePath)!!.path, + "--stacktrace", + *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), + "--debug" + )) } @ParameterizedTest diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt index 8405c761ae..bc5657f5ba 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt @@ -39,28 +39,24 @@ class XcfaCliWitnessTest { @JvmStatic fun cFiles(): Stream { return Stream.of( - Arguments.of( - "/c/litmustest/singlethread/witness_test.c", null, listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - ) - ), - Arguments.of( - "/c/litmustest/singlethread/witness_test.c", "--backend BOUNDED", listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - ) - ), + Arguments.of("/c/litmustest/singlethread/witness_test.c", null, listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ), + )), + Arguments.of("/c/litmustest/singlethread/witness_test.c", "--backend BOUNDED", listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ), + )), ) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt index 8fb8f64b90..53d5ba6130 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaDslTest.kt @@ -88,23 +88,18 @@ class XcfaDslTest { fun verifyXcfa() { SolverManager.registerSolverManager(Z3SolverManager.create()) val config = XcfaConfig( - backendConfig = BackendConfig(backend = Backend.CEGAR, specConfig = CegarConfig()) - ) + backendConfig = BackendConfig(backend = Backend.CEGAR, specConfig = CegarConfig())) run { val xcfa = getSyncXcfa() - val checker = getChecker( - xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), - NullLogger.getInstance() - ) + val checker = getChecker(xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), + NullLogger.getInstance()) val safetyResult = checker.check() Assert.assertTrue(safetyResult.isSafe) } run { val xcfa = getAsyncXcfa() - val checker = getChecker( - xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), - NullLogger.getInstance() - ) + val checker = getChecker(xcfa, emptySet(), config, ParseContext(), NullLogger.getInstance(), + NullLogger.getInstance()) val safetyResult = checker.check() Assert.assertTrue(safetyResult.isUnsafe) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt index fc7783b64f..51372ee26d 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaToCTest.kt @@ -55,17 +55,11 @@ class XcfaToCTest { val chcFrontend = ChcFrontend(chcTransformation) val xcfa = chcFrontend.buildXcfa( CharStreams.fromStream(FileInputStream(javaClass.getResource(filePath)!!.path)), ChcPasses( - ParseContext(), NullLogger.getInstance() - ) - ).build() + ParseContext(), NullLogger.getInstance())).build() val temp = createTempDirectory() val file = temp.resolve("${filePath.split("/").last()}.c").also { - it.toFile().writeText( - xcfa.toC( - ParseContext(), - true, false, false - ) - ) + it.toFile().writeText(xcfa.toC(ParseContext(), + true, false, false)) } System.err.println(file) } diff --git a/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts b/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts index 2a8aaae312..fb98c7344d 100644 --- a/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts +++ b/subprojects/xcfa/xcfa-cli/src/test/resources/simple.kts @@ -34,8 +34,7 @@ fun portfolio( parseContext: ParseContext, portfolioConfig: XcfaConfig<*, *>, logger: Logger, - uniqueLogger: Logger -): STM { + uniqueLogger: Logger): STM { val checker = { config: XcfaConfig<*, *> -> runConfig(config, logger, uniqueLogger, true) } @@ -44,14 +43,12 @@ fun portfolio( input = null, xcfaWCtx = Triple(xcfa, mcm, parseContext), propertyFile = null, - property = portfolioConfig.inputConfig.property - ), + property = portfolioConfig.inputConfig.property), frontendConfig = FrontendConfig( lbeLevel = LbePass.LbeLevel.LBE_SEQ, loopUnroll = 50, inputType = InputType.C, - specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient) - ), + specConfig = CFrontendConfig(arithmetic = ArchitectureConfig.ArithmeticType.efficient)), backendConfig = BackendConfig( backend = Backend.CEGAR, solverHome = portfolioConfig.backendConfig.solverHome, @@ -75,9 +72,7 @@ fun portfolio( refinement = Refinement.SEQ_ITP, exprSplitter = ExprSplitterOptions.WHOLE, pruneStrategy = PruneStrategy.FULL - ) - ) - ), + ))), outputConfig = OutputConfig( versionInfo = false, resultFolder = Paths.get("./").toFile(), // cwd @@ -96,8 +91,7 @@ fun portfolio( abstractorConfig = baseCegarConfig.abstractorConfig.copy(search = Search.DFS), ) baseConfig = baseConfig.copy( - backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig) - ) + backendConfig = baseConfig.backendConfig.copy(specConfig = multiThreadedCegarConfig)) } if (!xcfa.isInlined) { diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt index 924f0f7a24..cc6f24571b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/Utils.kt @@ -453,35 +453,27 @@ fun XcfaLabel.simplify(valuation: MutableValuation, parseContext: ParseContext): is MemoryAssignStmt<*, *, *> -> { simplified as MemoryAssignStmt<*, *, *> if (parseContext.metadata.getMetadataValue(stmt.expr, "cType").isPresent) - parseContext.metadata.create( - simplified.expr, "cType", - CComplexType.getType(stmt.expr, parseContext) - ) + parseContext.metadata.create(simplified.expr, "cType", + CComplexType.getType(stmt.expr, parseContext)) if (parseContext.metadata.getMetadataValue(stmt.deref, "cType").isPresent) - parseContext.metadata.create( - simplified.deref, "cType", - CComplexType.getType(stmt.deref, parseContext) - ) + parseContext.metadata.create(simplified.deref, "cType", + CComplexType.getType(stmt.deref, parseContext)) StmtLabel(simplified, metadata = metadata) } is AssignStmt<*> -> { simplified as AssignStmt<*> if (parseContext.metadata.getMetadataValue(stmt.expr, "cType").isPresent) - parseContext.metadata.create( - simplified.expr, "cType", - CComplexType.getType(stmt.expr, parseContext) - ) + parseContext.metadata.create(simplified.expr, "cType", + CComplexType.getType(stmt.expr, parseContext)) StmtLabel(simplified, metadata = metadata) } is AssumeStmt -> { simplified as AssumeStmt if (parseContext.metadata.getMetadataValue(stmt.cond, "cType").isPresent) { - parseContext.metadata.create( - simplified.cond, "cType", - CComplexType.getType(stmt.cond, parseContext) - ) + parseContext.metadata.create(simplified.cond, "cType", + CComplexType.getType(stmt.cond, parseContext)) } parseContext.metadata.create(simplified, "cTruth", stmt.cond is NeqExpr<*>) StmtLabel(simplified, metadata = metadata, choiceType = choiceType) @@ -528,10 +520,8 @@ val XCFA.lazyPointsToGraph: Lazy, Set>>> .filter { (i, pair) -> pair.second != ParamDirection.IN && it.params[i] is RefExpr<*> } .map { (i, pair) -> val (param, _) = pair - Assign( - cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), - cast(param.ref, param.type) - ) + Assign(cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), + cast(param.ref, param.type)) } } ?: listOf() } @@ -544,10 +534,8 @@ val XCFA.lazyPointsToGraph: Lazy, Set>>> Assign(cast(param, param.type), cast(it.params[i], param.type)) } + proc.params.filter { it.second != ParamDirection.IN }.mapIndexed { i, (param, _) -> - Assign( - cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), - cast(param.ref, param.type) - ) + Assign(cast((it.params[i] as RefExpr<*>).decl as VarDecl<*>, param.type), + cast(param.ref, param.type)) } } ?: listOf() } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt index 0114015fc1..6eacb8f086 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/XcfaToC.kt @@ -57,10 +57,8 @@ import hu.bme.mit.theta.xcfa.model.* private const val arraySize = 10; -fun XCFA.toC( - parseContext: ParseContext, arraySupport: Boolean, exactArraySupport: Boolean, - intRangeConstraint: Boolean -): String = """ +fun XCFA.toC(parseContext: ParseContext, arraySupport: Boolean, exactArraySupport: Boolean, + intRangeConstraint: Boolean): String = """ extern void abort(); extern unsigned short __VERIFIER_nondet_ushort(); extern short __VERIFIER_nondet_short(); diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt index 338ff8d66d..9cf2736445 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaAdapter.kt @@ -111,8 +111,7 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { private fun parseInitProcedures( reader: JsonReader, - procedures: Map - ): List>>> { + procedures: Map): List>>> { reader.beginArray() val ret = ArrayList>>>() val paramsType = object : TypeToken>>() {}.type @@ -191,11 +190,9 @@ class XcfaAdapter(val gsonSupplier: () -> Gson) : TypeAdapter() { } } } - ret[name] = XcfaProcedure( - name, params, vars, locs.values.toSet(), edges, initLoc, + ret[name] = XcfaProcedure(name, params, vars, locs.values.toSet(), edges, initLoc, Optional.ofNullable(finalLoc), - Optional.ofNullable(errorLoc) - ).also { it.parent = xcfa } + Optional.ofNullable(errorLoc)).also { it.parent = xcfa } reader.endObject() } reader.endArray() diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt index a06254cf5b..eeebe05881 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/gson/XcfaLabelAdapter.kt @@ -80,14 +80,11 @@ class XcfaLabelAdapter(val scope: Scope, val env: Env, val gsonSupplier: () -> G checkNotNull(constructor) { "${clazz.simpleName} has no fromString() method." } val obj = try { - constructor.call( - clazz.companionObject!!.objectInstance, content, scope, env, - metadata - ) + constructor.call(clazz.companionObject!!.objectInstance, content, scope, env, + metadata) } catch (e: Exception) { System.err.println( - "Could not parse $content\nscope: ${scope}\nenv: $env\ntype: ${clazz.simpleName}" - ) + "Could not parse $content\nscope: ${scope}\nenv: $env\ntype: ${clazz.simpleName}") throw e } check(obj is XcfaLabel) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt index e3885b34b8..b146c7d4f9 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Dsl.kt @@ -39,14 +39,10 @@ class VarContext(val builder: XcfaBuilder, private val local: Boolean) { infix fun Pair.init(initValue: String): VarDecl { val varDecl = Var(first, second) builder.addVar( - XcfaGlobalVar( - varDecl, + XcfaGlobalVar(varDecl, ExpressionWrapper(SimpleScope(SymbolTable()), initValue).instantiate( - Env() - ) as LitExpr<*>, - local - ) - ) + Env()) as LitExpr<*>, + local)) return varDecl } } @@ -93,8 +89,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun start(vararg expr: Any) { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } builder.parent.addEntryPoint(builder, exprs) } @@ -117,8 +112,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { infix fun String.assign(to: String): SequenceLabel { val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this - ) as VarDecl + this) as VarDecl val rhs: Expr = this@XcfaProcedureBuilderContext.builder.parse(to) as Expr val label = StmtLabel(Assign(lhs, rhs)) labelList.add(label) @@ -134,8 +128,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { infix fun String.assign(to: Expr<*>): SequenceLabel { val lhs: VarDecl = this@XcfaProcedureBuilderContext.builder.lookup( - this - ) as VarDecl + this) as VarDecl val rhs: Expr = to as Expr val label = StmtLabel(Assign(lhs, rhs)) labelList.add(label) @@ -178,8 +171,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { operator fun XcfaProcedureBuilderContext.invoke(vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = InvokeLabel(this.builder.name, exprs, EmptyMetaData) this@SequenceLabelContext.labelList.add(label) @@ -189,8 +181,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { operator fun String.invoke(vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = InvokeLabel(this, exprs, EmptyMetaData) this@SequenceLabelContext.labelList.add(label) @@ -201,8 +192,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = StartLabel(ctx.builder.name, exprs, lhs, EmptyMetaData) labelList.add(label) @@ -212,8 +202,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun VarDecl<*>.start(ctx: XcfaProcedureBuilderContext, vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = StartLabel(ctx.builder.name, exprs, this, EmptyMetaData) labelList.add(label) @@ -224,8 +213,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { val lhs = this@XcfaProcedureBuilderContext.builder.lookup(this) val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = StartLabel(ctx, exprs, lhs, EmptyMetaData) labelList.add(label) @@ -235,8 +223,7 @@ class XcfaProcedureBuilderContext(val builder: XcfaProcedureBuilder) { fun VarDecl<*>.start(ctx: String, vararg expr: Any): SequenceLabel { val exprs = expr.map { if (it is Expr<*>) it else if (it is String) this@XcfaProcedureBuilderContext.builder.parse( - it - ) else error("Bad type") + it) else error("Bad type") } val label = StartLabel(ctx, exprs, this, EmptyMetaData) labelList.add(label) @@ -314,10 +301,8 @@ fun XcfaBuilder.threadlocal(lambda: VarContext.() -> Unit) { context.apply(lambda) } -fun XcfaBuilder.procedure( - name: String, passManager: ProcedurePassManager, - lambda: XcfaProcedureBuilderContext.() -> Unit -): XcfaProcedureBuilderContext { +fun XcfaBuilder.procedure(name: String, passManager: ProcedurePassManager, + lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { val builder = XcfaProcedureBuilder(name, passManager) builder.parent = this val procBuilder = XcfaProcedureBuilderContext(builder).apply(lambda) @@ -325,9 +310,7 @@ fun XcfaBuilder.procedure( return procBuilder } -fun XcfaBuilder.procedure( - name: String, - lambda: XcfaProcedureBuilderContext.() -> Unit -): XcfaProcedureBuilderContext { +fun XcfaBuilder.procedure(name: String, + lambda: XcfaProcedureBuilderContext.() -> Unit): XcfaProcedureBuilderContext { return procedure(name, ProcedurePassManager(), lambda) } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt index 4080379efa..177c75758d 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/Visualizer.kt @@ -37,8 +37,7 @@ fun XcfaProcedure.toDot(edgeLabelCustomizer: ((XcfaEdge) -> String)?): String { locs.forEach { builder.appendLine("${it.name}[];") } edges.forEach { builder.appendLine( - "${it.source.name} -> ${it.target.name} [label=\"${it.label} ${edgeLabelCustomizer?.invoke(it) ?: ""}\"];" - ) + "${it.source.name} -> ${it.target.name} [label=\"${it.label} ${edgeLabelCustomizer?.invoke(it) ?: ""}\"];") } return builder.toString() } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt index 519a9d8627..93f636b306 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/model/XcfaLabel.kt @@ -50,11 +50,9 @@ data class InvokeLabel @JvmOverloads constructor( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (name, params) = Regex("([^\\(]*)\\((.*)\\)").matchEntire(s)!!.destructured - return InvokeLabel( - name, + return InvokeLabel(name, params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, - metadata = metadata - ) + metadata = metadata) } } } @@ -89,14 +87,11 @@ data class StartLabel( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (pidVarName, pidVarType, name, params) = Regex( - "\\(var (.*) (.*)\\) = start (.*)\\((.*)\\)" - ).matchEntire(s)!!.destructured + "\\(var (.*) (.*)\\) = start (.*)\\((.*)\\)").matchEntire(s)!!.destructured val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> - return StartLabel( - name, + return StartLabel(name, params.split(",").map { ExpressionWrapper(scope, it).instantiate(env) }, pidVar, - metadata = metadata - ) + metadata = metadata) } } } @@ -114,8 +109,7 @@ data class JoinLabel( fun fromString(s: String, scope: Scope, env: Env, metadata: MetaData): XcfaLabel { val (pidVarName, pidVarType) = Regex("join \\(var (.*) (.*)\\)").matchEntire( - s - )!!.destructured + s)!!.destructured val pidVar = env.eval(scope.resolve(pidVarName).orElseThrow()) as VarDecl<*> return JoinLabel(pidVar, metadata = metadata) } @@ -136,8 +130,7 @@ data class StmtLabel @JvmOverloads constructor( init { check( - stmt !is NonDetStmt && stmt !is SequenceStmt - ) { "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } + stmt !is NonDetStmt && stmt !is SequenceStmt) { "NonDetStmt and SequenceStmt are not supported in XCFA. Use the corresponding labels instead." } } override fun toStmt(): Stmt = stmt @@ -154,15 +147,11 @@ data class StmtLabel @JvmOverloads constructor( val matchResult = Regex("\\((.*)\\)\\[choiceType=(.*)]").matchEntire(s) if (matchResult != null) { val (stmt, choiceTypeStr) = matchResult.destructured - return StmtLabel( - StatementWrapper(stmt, scope).instantiate(env), - choiceType = ChoiceType.valueOf(choiceTypeStr), metadata = metadata - ) + return StmtLabel(StatementWrapper(stmt, scope).instantiate(env), + choiceType = ChoiceType.valueOf(choiceTypeStr), metadata = metadata) } else { - return StmtLabel( - StatementWrapper(s, scope).instantiate(env), - choiceType = ChoiceType.NONE, metadata = metadata - ) + return StmtLabel(StatementWrapper(s, scope).instantiate(env), + choiceType = ChoiceType.NONE, metadata = metadata) } } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt index 7db5191f4b..17bbdde26e 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AssumeFalseRemovalPass.kt @@ -29,8 +29,7 @@ class AssumeFalseRemovalPass : ProcedurePass { override fun run(builder: XcfaProcedureBuilder): XcfaProcedureBuilder { builder.getEdges().toSet().forEach { edge -> if (edge.getFlatLabels() - .any { it is StmtLabel && it.stmt is AssumeStmt && it.stmt.cond is FalseExpr } - ) { + .any { it is StmtLabel && it.stmt is AssumeStmt && it.stmt.cond is FalseExpr }) { builder.removeEdge(edge) } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt index 5366595cc5..d4927ebaad 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/AtomicReadsOneWritePass.kt @@ -160,12 +160,9 @@ class AtomicReadsOneWritePass : ProcedurePass { private fun XcfaLabel.replaceAccesses(localVersions: Map, VarDecl<*>>): XcfaLabel { return when (this) { is StmtLabel -> when (val stmt = stmt) { - is AssignStmt<*> -> StmtLabel( - AssignStmt.of( - cast(localVersions[stmt.varDecl] ?: stmt.varDecl, stmt.varDecl.type), - cast(stmt.expr.replace(localVersions), stmt.varDecl.type) - ) - ) + is AssignStmt<*> -> StmtLabel(AssignStmt.of( + cast(localVersions[stmt.varDecl] ?: stmt.varDecl, stmt.varDecl.type), + cast(stmt.expr.replace(localVersions), stmt.varDecl.type))) is AssumeStmt -> StmtLabel(AssumeStmt.of(stmt.cond.replace(localVersions))) is HavocStmt<*> -> StmtLabel(HavocStmt.of(localVersions[stmt.varDecl] ?: stmt.varDecl)) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt index 9fddf43123..7803f1daaf 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/CLibraryFunctionsPass.kt @@ -71,13 +71,9 @@ class CLibraryFunctionsPass : ProcedurePass { val param = invokeLabel.params[4] - listOf( - StartLabel( - (funcptr as RefExpr).decl.name, - listOf(Int(0), param), // int(0) to solve StartLabel not handling return params - (handle as RefExpr).decl as VarDecl<*>, metadata - ) - ) + listOf(StartLabel((funcptr as RefExpr).decl.name, + listOf(Int(0), param), // int(0) to solve StartLabel not handling return params + (handle as RefExpr).decl as VarDecl<*>, metadata)) } "pthread_mutex_lock" -> { @@ -105,10 +101,8 @@ class CLibraryFunctionsPass : ProcedurePass { check(handle is RefExpr && (handle as RefExpr).decl is VarDecl) listOf( - FenceLabel( - setOf("start_cond_wait(${cond.decl.name},${handle.decl.name})"), - metadata - ), + FenceLabel(setOf("start_cond_wait(${cond.decl.name},${handle.decl.name})"), + metadata), FenceLabel(setOf("cond_wait(${cond.decl.name},${handle.decl.name})"), metadata) ) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt index 6dd64e2b45..d539cb6240 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ErrorLocationPass.kt @@ -29,16 +29,13 @@ class ErrorLocationPass(private val checkOverflow: Boolean) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( - XcfaEdge(it.source, builder.errorLoc.get(), SequenceLabel(listOf())) - ) + XcfaEdge(it.source, builder.errorLoc.get(), SequenceLabel(listOf()))) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt index 894f89ccb2..0ed1eee7a1 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FetchExecuteWriteback.kt @@ -73,44 +73,29 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { is InvokeLabel -> { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { - StmtLabel( - Assign( - cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) - ) - ) - } + InvokeLabel( - this.name, this.params.map { it.replaceDerefs(lut) }, metadata, - tempLookup - ), metadata - ) + StmtLabel(Assign(cast(it.value, it.value.type), + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type))) + } + InvokeLabel(this.name, this.params.map { it.replaceDerefs(lut) }, metadata, + tempLookup), metadata) } is StartLabel -> { val lut = getDerefLut(dereferences, builder) SequenceLabel(lut.map { - StmtLabel( - Assign( - cast(it.value, it.value.type), - cast(it.key.map { it.replaceDerefs(lut) }, it.value.type) - ) - ) + StmtLabel(Assign(cast(it.value, it.value.type), + cast(it.key.map { it.replaceDerefs(lut) }, it.value.type))) } + StartLabel(name, params.map { it.replaceDerefs(lut) }, pidVar, metadata, tempLookup), metadata) } - is StmtLabel -> SequenceLabel( - stmt.replaceDerefs(builder).map { StmtLabel(it, choiceType, metadata) }, - metadata - ) + is StmtLabel -> SequenceLabel(stmt.replaceDerefs(builder).map { StmtLabel(it, choiceType, metadata) }, + metadata) else -> error("Not implemented for ${this.javaClass.simpleName}") } } else this - private fun getDerefLut( - dereferences: List>, - builder: XcfaProcedureBuilder - ) = dereferences.associateWith { + private fun getDerefLut(dereferences: List>, + builder: XcfaProcedureBuilder) = dereferences.associateWith { val tmpVar = Var("__THETA_heap_tmp_$cnt", it.type) builder.addVar(tmpVar) tmpVar @@ -133,24 +118,15 @@ class FetchExecuteWriteback(val parseContext: ParseContext) : ProcedurePass { val ret = ArrayList() val accessType = dereferencesWithAccessTypes.filter { dereferences.contains(it.first) } for (dereference in accessType.filter { it.second.isRead }.map { it.first }) { - ret.add( - Assign( - cast(lut[dereference]!!, dereference.type), - cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type) - ) - ) + ret.add(Assign(cast(lut[dereference]!!, dereference.type), + cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, dereference.type))) } ret.add(stmt) for (dereference in accessType.filter { it.second.isWritten }.map { it.first }) { - ret.add( - MemoryAssign( - cast( - dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, - dereference.type - ) as Dereference<*, *, Type>, - cast(lut[dereference]!!, dereference.type).ref - ) - ) + ret.add(MemoryAssign( + cast(dereference.map { it.replaceDerefs(lut.filter { it.key != dereference }) }, + dereference.type) as Dereference<*, *, Type>, + cast(lut[dereference]!!, dereference.type).ref)) } return ret } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt index e586621cad..987722b622 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FinalLocationPass.kt @@ -31,23 +31,15 @@ class FinalLocationPass(private val checkOverflow: Boolean) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { if (builder.finalLoc.isEmpty) builder.createFinalLoc() - builder.addEdge( - XcfaEdge( - it.source, builder.finalLoc.get(), SequenceLabel( - listOf( - StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata) - ), - metadata = it.metadata - ) - ) - ) + builder.addEdge(XcfaEdge(it.source, builder.finalLoc.get(), SequenceLabel( + listOf( + StmtLabel(Stmts.Assume(BoolExprs.False()), metadata = it.metadata)), + metadata = it.metadata))) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt index 8cabaf35e0..8a05f0ef2b 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/FpFunctionsToExprsPass.kt @@ -57,78 +57,44 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private val handlers: MutableMap> = LinkedHashMap() - private fun addHandler( - names: Array, - handler: BiFunction - ) { + private fun addHandler(names: Array, + handler: BiFunction) { for (name in names) { handlers[name] = handler } } init { - addHandler( - arrayOf( - "fabs", "fabsf", - "fabsl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("fabs", "fabsf", + "fabsl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFabs(builder, callStmt) } - addHandler( - arrayOf( - "floor", "floorf", - "floorl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("floor", "floorf", + "floorl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFloor(builder, callStmt) } - addHandler( - arrayOf( - "fmax", "fmaxf", - "fmaxl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("fmax", "fmaxf", + "fmaxl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmax(builder, callStmt) } - addHandler( - arrayOf( - "fmin", "fminf", - "fminl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("fmin", "fminf", + "fminl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmin(builder, callStmt) } - addHandler( - arrayOf( - "fmod", "fmodf", - "fmodl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("fmod", "fmodf", + "fmodl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFmod(builder, callStmt) } - addHandler( - arrayOf( - "sqrt", "sqrtf", - "sqrtl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("sqrt", "sqrtf", + "sqrtl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleSqrt(builder, callStmt) } - addHandler( - arrayOf( - "round", "roundf", - "roundl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("round", "roundf", + "roundl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleRound(builder, callStmt) } - addHandler( - arrayOf( - "isnan", "__isnan", "isnanf", "__isnanf", "isnanl", - "__isnanl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("isnan", "__isnan", "isnanf", "__isnanf", "isnanl", + "__isnanl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsnan(builder, callStmt) } addHandler(arrayOf("trunc")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> @@ -137,37 +103,22 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { addHandler(arrayOf("ceil")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleCeil(builder, callStmt) } - addHandler( - arrayOf( - "isnormal" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf( + "isnormal")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsnormal(builder, callStmt) } - addHandler( - arrayOf( - "isinf", "__isinf", "__isinff", "isinff", - "__isinfl", "isinfl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("isinf", "__isinf", "__isinff", "isinff", + "__isinfl", "isinfl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsinf(builder, callStmt) } - addHandler( - arrayOf( - "isfinite", "finite", "isfinitef", "finitef", "isfinite", "finitel", "__finite", "__finitef", - "__finitel", - "__isfinite", - "__isfinitef", "__isfinitel" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf( + "isfinite", "finite", "isfinitef", "finitef", "isfinite", "finitel", "__finite", "__finitef", "__finitel", + "__isfinite", + "__isfinitef", "__isfinitel")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleIsfinite(builder, callStmt) } - addHandler( - arrayOf( - "__fpclassify", "__fpclassifyf", - "__fpclassifyl" - ) - ) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> + addHandler(arrayOf("__fpclassify", "__fpclassifyf", + "__fpclassifyl")) { builder: XcfaProcedureBuilder, callStmt: InvokeLabel -> handleFpclassify(builder, callStmt) } } @@ -176,16 +127,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of( - FpRoundingMode.RTZ, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of(FpRoundingMode.RTZ, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -196,16 +141,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of( - FpRoundingMode.RTP, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of(FpRoundingMode.RTP, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -219,54 +158,38 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { val type = CSignedInt(null, parseContext) val assign: AssignStmt<*> = Stmts.Assign( TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast( - AbstractExprs.Ite( - FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue - ), - type.smtType - ) - ) + TypeUtils.cast(AbstractExprs.Ite( + FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + type.unitValue, type.nullValue), + type.smtType)) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } - private fun handleIsfinite( - builder: XcfaProcedureBuilder, - callStmt: InvokeLabel - ): XcfaLabel { + private fun handleIsfinite(builder: XcfaProcedureBuilder, + callStmt: InvokeLabel): XcfaLabel { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) val type = CSignedInt(null, parseContext) val assign: AssignStmt<*> = Stmts.Assign( TypeUtils.cast((expr as RefExpr<*>).decl as VarDecl<*>, type.smtType), - TypeUtils.cast( - AbstractExprs.Ite( - Or( - FpIsInfiniteExpr.of(callStmt.params[1] as Expr), - FpIsNanExpr.of(callStmt.params[1] as Expr) - ), - type.nullValue, type.unitValue - ), - type.smtType - ) - ) + TypeUtils.cast(AbstractExprs.Ite( + Or(FpIsInfiniteExpr.of(callStmt.params[1] as Expr), + FpIsNanExpr.of(callStmt.params[1] as Expr)), + type.nullValue, type.unitValue), + type.smtType)) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } - private fun handleIsnormal( - builder: XcfaProcedureBuilder, - callStmt: InvokeLabel - ): XcfaLabel { + private fun handleIsnormal(builder: XcfaProcedureBuilder, + callStmt: InvokeLabel): XcfaLabel { throw UnsupportedOperationException() } - private fun handleFpclassify( - builder: XcfaProcedureBuilder, - callStmt: InvokeLabel - ): XcfaLabel { + private fun handleFpclassify(builder: XcfaProcedureBuilder, + callStmt: InvokeLabel): XcfaLabel { throw UnsupportedOperationException() } @@ -281,10 +204,7 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { TypeUtils.cast( AbstractExprs.Ite( FpIsNanExpr.of(callStmt.params[1] as Expr), - type.unitValue, type.nullValue - ), type.smtType - ) - ) + type.unitValue, type.nullValue), type.smtType)) parseContext.metadata.create(assign.expr, "cType", type) return StmtLabel(assign, metadata = callStmt.metadata) } else { @@ -296,16 +216,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of( - FpRoundingMode.RNA, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of(FpRoundingMode.RNA, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -316,16 +230,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpSqrtExpr.of( - FpRoundingMode.RNE, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpSqrtExpr.of(FpRoundingMode.RNE, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -337,25 +245,15 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private fun handleFmin(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState( - callStmt.params.size == 3, - "Function is presumed to be binary!" - ) + Preconditions.checkState(callStmt.params.size == 3, + "Function is presumed to be binary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpMinExpr.of( - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpMinExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -363,25 +261,15 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { } private fun handleFmax(builder: XcfaProcedureBuilder, callStmt: InvokeLabel): XcfaLabel { - Preconditions.checkState( - callStmt.params.size == 3, - "Function is presumed to be binary!" - ) + Preconditions.checkState(callStmt.params.size == 3, + "Function is presumed to be binary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpMaxExpr.of( - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpMaxExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[2]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -392,16 +280,10 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpRoundToIntegralExpr.of( - FpRoundingMode.RTN, - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpRoundToIntegralExpr.of(FpRoundingMode.RTN, + TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } @@ -412,15 +294,9 @@ class FpFunctionsToExprsPass(val parseContext: ParseContext) : ProcedurePass { Preconditions.checkState(callStmt.params.size == 2, "Function is presumed to be unary!") val expr = callStmt.params[0] Preconditions.checkState(expr is RefExpr<*>) - val assign = Stmts.Assign( - (expr as RefExpr<*>).decl as VarDecl, - FpAbsExpr.of( - TypeUtils.cast( - CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), - CComplexType.getType(expr, parseContext).smtType - ) as Expr - ) - ) + val assign = Stmts.Assign((expr as RefExpr<*>).decl as VarDecl, + FpAbsExpr.of(TypeUtils.cast(CComplexType.getType(expr, parseContext).castTo(callStmt.params[1]), + CComplexType.getType(expr, parseContext).smtType) as Expr)) if (parseContext.metadata.getMetadataValue(expr, "cType").isPresent) { parseContext.metadata.create(assign.expr, "cType", CComplexType.getType(expr, parseContext)) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt index b1fb46146a..7b0b3eccfa 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/HavocPromotionAndRange.kt @@ -75,8 +75,7 @@ class HavocPromotionAndRange(val parseContext: ParseContext) : ProcedurePass { // val type = CComplexType.getType(((edge.label.labels[index + 1] as StmtLabel).stmt as AssignStmt<*>).expr, parseContext) val havoc = Havoc(varDecl) newLabels.add( - StmtLabel(havoc, metadata = edge.label.labels[index].metadata) - ) + StmtLabel(havoc, metadata = edge.label.labels[index].metadata)) // newLabels.add(StmtLabel(type.limit(varDecl.ref))) } else if (index == indices[offset] + 1) { offset++ @@ -99,15 +98,11 @@ class HavocPromotionAndRange(val parseContext: ParseContext) : ProcedurePass { for ((index, value) in reversed) { val varDecl = ((value as StmtLabel).stmt as HavocStmt<*>).varDecl if (parseContext.metadata.getMetadataValue(varDecl.ref, "cType").isPresent) { - val type = CComplexType.getType( - varDecl.ref, - parseContext - ) // TODO: what to do when no info is available? + val type = CComplexType.getType(varDecl.ref, + parseContext) // TODO: what to do when no info is available? if (type !is CVoid) { - list.add( - index + 1, - StmtLabel(type.limit(varDecl.ref), metadata = value.metadata) - ) + list.add(index + 1, + StmtLabel(type.limit(varDecl.ref), metadata = value.metadata)) } } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt index c4656380c5..48114fc020 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/InlineProceduresPass.kt @@ -63,34 +63,25 @@ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { procedure.getVars().forEach { builder.addVar(it) } procedure.getParams().forEach { builder.addVar(it.first) } procedure.getEdges().forEach { - builder.addEdge( - it.withSource(checkNotNull(newLocs[it.source])) - .withTarget(checkNotNull(newLocs[it.target])) - ) + builder.addEdge(it.withSource(checkNotNull(newLocs[it.source])) + .withTarget(checkNotNull(newLocs[it.target]))) } val inStmts: MutableList = ArrayList() val outStmts: MutableList = ArrayList() for ((i, param) in procedure.getParams().withIndex()) { if (param.second != ParamDirection.OUT) { - val stmt = AssignStmt.of( - cast(param.first, param.first.type), - cast( - CComplexType.getType(param.first.ref, parseContext) - .castTo(invokeLabel.params[i]), param.first.type - ) - ) + val stmt = AssignStmt.of(cast(param.first, param.first.type), + cast(CComplexType.getType(param.first.ref, parseContext) + .castTo(invokeLabel.params[i]), param.first.type)) inStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) } if (param.second != ParamDirection.IN) { val varDecl = (invokeLabel.params[i] as RefExpr<*>).decl as VarDecl<*> - val stmt = AssignStmt.of( - cast(varDecl, param.first.type), cast( - CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), - param.first.type - ) - ) + val stmt = AssignStmt.of(cast(varDecl, param.first.type), cast( + CComplexType.getType(varDecl.ref, parseContext).castTo(param.first.ref), + param.first.type)) outStmts.add(StmtLabel(stmt, metadata = invokeLabel.metadata)) } } @@ -101,20 +92,13 @@ class InlineProceduresPass(val parseContext: ParseContext) : ProcedurePass { builder.addEdge(XcfaEdge(source, checkNotNull(newLocs[initLoc]), SequenceLabel(inStmts))) if (finalLoc.isPresent) - builder.addEdge( - XcfaEdge( - checkNotNull(newLocs[finalLoc.get()]), target, - SequenceLabel(outStmts) - ) - ) + builder.addEdge(XcfaEdge(checkNotNull(newLocs[finalLoc.get()]), target, + SequenceLabel(outStmts))) if (errorLoc.isPresent) { if (builder.errorLoc.isEmpty) builder.createErrorLoc() builder.addEdge( - XcfaEdge( - checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), - SequenceLabel(listOf()) - ) - ) + XcfaEdge(checkNotNull(newLocs[errorLoc.get()]), builder.errorLoc.get(), + SequenceLabel(listOf()))) } } else { builder.addEdge(e) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt index 8e37818330..bc745cfe67 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/LbePass.kt @@ -145,10 +145,8 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * @param strict If true, cascade collapsing is limited to locations in locationsToVisit. * @return Returns the list of removed locations. */ - private fun collapseParallelsAndSnakes( - locationsToVisit: List, - strict: Boolean - ): List { + private fun collapseParallelsAndSnakes(locationsToVisit: List, + strict: Boolean): List { val editedLocationsToVisit = locationsToVisit.toMutableList() val removedLocations = mutableListOf() while (editedLocationsToVisit.isNotEmpty()) { @@ -202,10 +200,8 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * @param locationsToVisit Adds the targets of parallel edges to this list (new parallel edges and snakes * can appear in these locations) */ - private fun collapseParallelEdges( - location: XcfaLocation, - locationsToVisit: MutableList - ) { + private fun collapseParallelEdges(location: XcfaLocation, + locationsToVisit: MutableList) { val edgesByTarget = mutableMapOf>() for (edge in location.outgoingEdges) { val edgesToTarget = edgesByTarget.getOrDefault(edge.target, ArrayList()) @@ -239,10 +235,8 @@ class LbePass(val parseContext: ParseContext) : ProcedurePass { * added to this list * @param removedLocations The list of removed locations: the collapsed location is added to this list */ - private fun collapsePartOfSnake( - location: XcfaLocation, - locationsToVisit: MutableList, removedLocations: MutableList - ) { + private fun collapsePartOfSnake(location: XcfaLocation, + locationsToVisit: MutableList, removedLocations: MutableList) { if (location.incomingEdges.size == 1 && location.outgoingEdges.size == 1) { val previousLocation = location.incomingEdges.first().source val removed = removeMiddleLocation(location) diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt index 638bee932d..07a1b62bb9 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/MallocFunctionPass.kt @@ -45,9 +45,7 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { @@ -56,21 +54,15 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { val mallocVar = builder.parent.malloc if (builder.parent.getVars().none { it.wrappedVar == mallocVar }) { // initial creation builder.parent.addVar( - XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue) - ) + XcfaGlobalVar(mallocVar, CComplexType.getType(ret, parseContext).nullValue)) val initProc = builder.parent.getInitProcedures().map { it.first } checkState(initProc.size == 1, "Multiple start procedure are not handled well") initProc.forEach { - val initAssign = StmtLabel( - Assign( - cast(mallocVar, mallocVar.type), - cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type) - ) - ) + val initAssign = StmtLabel(Assign(cast(mallocVar, mallocVar.type), + cast(CComplexType.getType(ret, parseContext).nullValue, mallocVar.type))) val newEdges = it.initLoc.outgoingEdges.map { it.withLabel( - SequenceLabel(listOf(initAssign) + it.label.getFlatLabels(), it.label.metadata) - ) + SequenceLabel(listOf(initAssign) + it.label.getFlatLabels(), it.label.metadata)) } it.initLoc.outgoingEdges.forEach(it::removeEdge) newEdges.forEach(it::addEdge) @@ -78,24 +70,14 @@ class MallocFunctionPass(val parseContext: ParseContext) : ProcedurePass { } val assign1 = AssignStmt.of( cast(mallocVar, ret.type), - cast( - Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), - ret.type - ) - ) + cast(Add(mallocVar.ref, CComplexType.getType(ret, parseContext).getValue("3")), + ret.type)) val assign2 = AssignStmt.of( - cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type) - ) - builder.addEdge( - XcfaEdge( - it.source, it.target, SequenceLabel( - listOf( - StmtLabel(assign1, metadata = invokeLabel.metadata), - StmtLabel(assign2, metadata = invokeLabel.metadata) - ) - ) - ) - ) + cast(ret.decl as VarDecl<*>, ret.type), cast(mallocVar.ref, ret.type)) + builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( + listOf( + StmtLabel(assign1, metadata = invokeLabel.metadata), + StmtLabel(assign2, metadata = invokeLabel.metadata))))) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt index cf88e7314b..ffcda3e8bb 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NoSideEffectPass.kt @@ -30,9 +30,7 @@ class NoSideEffectPass(val parseContext: ParseContext) : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt index b5b4eb8faf..fd7dfcb847 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NondetFunctionPass.kt @@ -32,23 +32,15 @@ class NondetFunctionPass : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { val invokeLabel = it.label.labels[0] as InvokeLabel val havoc = HavocStmt.of( - (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*> - ) - builder.addEdge( - XcfaEdge( - it.source, it.target, SequenceLabel( - listOf(StmtLabel(havoc, metadata = invokeLabel.metadata)) - ) - ) - ) + (invokeLabel.params[0] as RefExpr<*>).decl as VarDecl<*>) + builder.addEdge(XcfaEdge(it.source, it.target, SequenceLabel( + listOf(StmtLabel(havoc, metadata = invokeLabel.metadata))))) } else { builder.addEdge(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt index db22bd7169..418090364d 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/NormalizePass.kt @@ -65,9 +65,7 @@ class NormalizePass : ProcedurePass { is NopLabel -> {} is StmtLabel -> if (!(label.stmt is AssumeStmt && label.stmt.cond.equals( - True() - )) - ) collector.forEach { it.add(label) } + True()))) collector.forEach { it.add(label) } else -> collector.forEach { it.add(label) } } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt index 836a01d635..02cb00683e 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ProcedurePassManager.kt @@ -78,28 +78,26 @@ class CPasses(checkOverflow: Boolean, parseContext: ParseContext, uniqueWarningL ) ) -class ChcPasses(parseContext: ParseContext, uniqueWarningLogger: Logger) : ProcedurePassManager( - listOf( - // formatting - NormalizePass(), - DeterministicPass(), - // removing redundant elements - EmptyEdgeRemovalPass(), - UnusedLocRemovalPass(), - // optimizing - SimplifyExprsPass(parseContext), - ), listOf( - // trying to inline procedures - InlineProceduresPass(parseContext), - RemoveDeadEnds(), - EliminateSelfLoops(), - // handling remaining function calls - LbePass(parseContext), - NormalizePass(), // needed after lbe, TODO - DeterministicPass(), // needed after lbe, TODO - // Final cleanup - UnusedVarPass(uniqueWarningLogger), - ) -) +class ChcPasses(parseContext: ParseContext, uniqueWarningLogger: Logger) : ProcedurePassManager(listOf( + // formatting + NormalizePass(), + DeterministicPass(), + // removing redundant elements + EmptyEdgeRemovalPass(), + UnusedLocRemovalPass(), + // optimizing + SimplifyExprsPass(parseContext), +), listOf( + // trying to inline procedures + InlineProceduresPass(parseContext), + RemoveDeadEnds(), + EliminateSelfLoops(), + // handling remaining function calls + LbePass(parseContext), + NormalizePass(), // needed after lbe, TODO + DeterministicPass(), // needed after lbe, TODO + // Final cleanup + UnusedVarPass(uniqueWarningLogger), +)) class LitmusPasses : ProcedurePassManager() \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt index b216917361..e06e7ce39f 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/ReferenceElimination.kt @@ -60,12 +60,8 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { val lit = CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt") builder.parent.addVar(XcfaGlobalVar(varDecl, lit)) parseContext.metadata.create(varDecl.ref, "cType", ptrType) - val assign = StmtLabel( - AssignStmt.of( - cast(varDecl, varDecl.type), - cast(lit, varDecl.type) - ) - ) + val assign = StmtLabel(AssignStmt.of(cast(varDecl, varDecl.type), + cast(lit, varDecl.type))) Pair(varDecl, assign) } } @@ -81,12 +77,8 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { val varDecl = Var(it.name + "*", ptrType.smtType) builder.addVar(varDecl) parseContext.metadata.create(varDecl.ref, "cType", ptrType) - val assign = StmtLabel( - AssignStmt.of( - cast(varDecl, varDecl.type), - cast(CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt"), varDecl.type) - ) - ) + val assign = StmtLabel(AssignStmt.of(cast(varDecl, varDecl.type), + cast(CComplexType.getType(varDecl.ref, parseContext).getValue("$cnt"), varDecl.type))) Pair(varDecl, assign) } + globalReferredVars @@ -114,37 +106,25 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } @JvmOverloads - fun XcfaLabel.changeReferredVars( - varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null - ): XcfaLabel = + fun XcfaLabel.changeReferredVars(varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null): XcfaLabel = if (varLut.isNotEmpty()) when (this) { - is InvokeLabel -> InvokeLabel( - name, params.map { it.changeReferredVars(varLut, parseContext) }, - metadata = metadata - ) - - is NondetLabel -> NondetLabel( - labels.map { it.changeReferredVars(varLut, parseContext) }.toSet(), - metadata = metadata - ) - - is SequenceLabel -> SequenceLabel( - labels.map { it.changeReferredVars(varLut, parseContext) }, - metadata = metadata - ) - - is StartLabel -> StartLabel( - name, params.map { it.changeReferredVars(varLut, parseContext) }, - pidVar, metadata = metadata - ) + is InvokeLabel -> InvokeLabel(name, params.map { it.changeReferredVars(varLut, parseContext) }, + metadata = metadata) + + is NondetLabel -> NondetLabel(labels.map { it.changeReferredVars(varLut, parseContext) }.toSet(), + metadata = metadata) + + is SequenceLabel -> SequenceLabel(labels.map { it.changeReferredVars(varLut, parseContext) }, + metadata = metadata) + + is StartLabel -> StartLabel(name, params.map { it.changeReferredVars(varLut, parseContext) }, + pidVar, metadata = metadata) is StmtLabel -> SequenceLabel(stmt.changeReferredVars(varLut, parseContext).map { - StmtLabel( - it, metadata = metadata, - choiceType = this.choiceType - ) + StmtLabel(it, metadata = metadata, + choiceType = this.choiceType) }).let { if (it.labels.size == 1) it.labels[0] else it } else -> this @@ -152,10 +132,8 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { else this @JvmOverloads - fun Stmt.changeReferredVars( - varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null - ): List { + fun Stmt.changeReferredVars(varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null): List { val stmts = when (this) { is AssignStmt<*> -> if (this.varDecl in varLut.keys) { val newVar = varLut[this.varDecl]!!.first @@ -164,31 +142,20 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { Dereference( cast(newVar.ref, newVar.type), cast(CComplexType.getSignedLong(parseContext).nullValue, newVar.type), - this.expr.type - ), - this.expr.changeReferredVars(varLut, parseContext) - ) - ) + this.expr.type), + this.expr.changeReferredVars(varLut, parseContext))) } else { - listOf( - AssignStmt.of( - cast(this.varDecl, this.varDecl.type), - cast(this.expr.changeReferredVars(varLut, parseContext), this.varDecl.type) - ) - ) + listOf(AssignStmt.of(cast(this.varDecl, this.varDecl.type), + cast(this.expr.changeReferredVars(varLut, parseContext), this.varDecl.type))) } is MemoryAssignStmt<*, *, *> -> listOf( - MemoryAssignStmt.create( - deref.changeReferredVars(varLut, parseContext) as Dereference<*, *, *>, - expr.changeReferredVars(varLut, parseContext) - ) - ) + MemoryAssignStmt.create(deref.changeReferredVars(varLut, parseContext) as Dereference<*, *, *>, + expr.changeReferredVars(varLut, parseContext))) is AssumeStmt -> listOf(AssumeStmt.of(cond.changeReferredVars(varLut, parseContext))) is SequenceStmt -> listOf( - SequenceStmt.of(this.stmts.flatMap { it.changeReferredVars(varLut, parseContext) }) - ) + SequenceStmt.of(this.stmts.flatMap { it.changeReferredVars(varLut, parseContext) })) is SkipStmt -> listOf(this) else -> TODO("Not yet implemented ($this)") @@ -203,10 +170,8 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } @JvmOverloads - fun Expr.changeReferredVars( - varLut: Map, Pair, StmtLabel>>, - parseContext: ParseContext? = null - ): Expr = + fun Expr.changeReferredVars(varLut: Map, Pair, StmtLabel>>, + parseContext: ParseContext? = null): Expr = if (this is RefExpr) { (decl as VarDecl).changeReferredVars(varLut) } else if (this is Reference<*, *> && this.expr is RefExpr<*> && (this.expr as RefExpr<*>).decl in varLut.keys) { @@ -220,13 +185,10 @@ class ReferenceElimination(val parseContext: ParseContext) : ProcedurePass { } fun VarDecl.changeReferredVars( - varLut: Map, Pair, StmtLabel>> - ): Expr = + varLut: Map, Pair, StmtLabel>>): Expr = varLut[this]?.first?.let { - Dereference( - cast(it.ref, it.type), cast(CComplexType.getSignedInt(parseContext).nullValue, it.type), - this.type - ) as Expr + Dereference(cast(it.ref, it.type), cast(CComplexType.getSignedInt(parseContext).nullValue, it.type), + this.type) as Expr } ?: this.ref } \ No newline at end of file diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt index c92d5f08ee..46933ea4e9 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/SvCompIntrinsicsPass.kt @@ -40,8 +40,7 @@ class SvCompIntrinsicsPass : ProcedurePass { builder.addEdge(outgoingEdge.withLabel(SequenceLabel(labels))) } for (incomingEdge in ArrayList( - builder.finalLoc.getOrNull()?.incomingEdges ?: listOf() - )) { + builder.finalLoc.getOrNull()?.incomingEdges ?: listOf())) { builder.removeEdge(incomingEdge) val labels = ArrayList((incomingEdge.label as SequenceLabel).labels) labels.add(FenceLabel(setOf("ATOMIC_END"), metadata = incomingEdge.metadata)) @@ -51,24 +50,18 @@ class SvCompIntrinsicsPass : ProcedurePass { for (edge in ArrayList(builder.getEdges())) { val edges = edge.splitIf(this::predicate) if (edges.size > 1 || (edges.size == 1 && predicate( - (edges[0].label as SequenceLabel).labels[0] - )) - ) { + (edges[0].label as SequenceLabel).labels[0]))) { builder.removeEdge(edge) val labels: MutableList = ArrayList() edges.forEach { if (predicate((it.label as SequenceLabel).labels[0])) { val invokeLabel = it.label.labels[0] as InvokeLabel val fence = when (invokeLabel.name) { - "__VERIFIER_atomic_begin" -> FenceLabel( - setOf("ATOMIC_BEGIN"), - metadata = invokeLabel.metadata - ) + "__VERIFIER_atomic_begin" -> FenceLabel(setOf("ATOMIC_BEGIN"), + metadata = invokeLabel.metadata) - "__VERIFIER_atomic_end" -> FenceLabel( - setOf("ATOMIC_END"), - metadata = invokeLabel.metadata - ) + "__VERIFIER_atomic_end" -> FenceLabel(setOf("ATOMIC_END"), + metadata = invokeLabel.metadata) else -> invokeLabel } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt index c8ed0b0c27..1f88251fab 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/UnusedVarPass.kt @@ -62,11 +62,9 @@ class UnusedVarPass(private val uniqueWarningLogger: Logger) : ProcedurePass { val allVars = Sets.union(builder.getVars(), builder.parent.getVars().map { it.wrappedVar }.toSet()) val varsAndParams = Sets.union(allVars, builder.getParams().map { it.first }.toSet()) if (!varsAndParams.containsAll(usedVars)) { - uniqueWarningLogger.write( - Logger.Level.INFO, + uniqueWarningLogger.write(Logger.Level.INFO, "WARNING: There are some used variables not present as declarations: " + - "${usedVars.filter { it !in varsAndParams }}\n" - ) + "${usedVars.filter { it !in varsAndParams }}\n") } builder.getVars().filter { it !in usedVars }.forEach { builder.removeVar(it) } diff --git a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt index 55ae7e42e0..cb5c74b8cb 100644 --- a/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt +++ b/subprojects/xcfa/xcfa/src/main/java/hu/bme/mit/theta/xcfa/passes/Utils.kt @@ -76,41 +76,27 @@ fun Stmt.flatten(): List { fun XcfaLabel.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): XcfaLabel = if (varLut.isNotEmpty()) when (this) { - is InvokeLabel -> InvokeLabel( - name, params.map { it.changeVars(varLut, parseContext) }, - metadata = metadata - ) + is InvokeLabel -> InvokeLabel(name, params.map { it.changeVars(varLut, parseContext) }, + metadata = metadata) is JoinLabel -> JoinLabel(pidVar.changeVars(varLut), metadata = metadata) - is NondetLabel -> NondetLabel( - labels.map { it.changeVars(varLut, parseContext) }.toSet(), - metadata = metadata - ) - - is ReadLabel -> ReadLabel( - local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata - ) - - is SequenceLabel -> SequenceLabel( - labels.map { it.changeVars(varLut, parseContext) }, - metadata = metadata - ) - - is StartLabel -> StartLabel( - name, params.map { it.changeVars(varLut, parseContext) }, - pidVar.changeVars(varLut), metadata = metadata - ) - - is StmtLabel -> StmtLabel( - stmt.changeVars(varLut, parseContext), metadata = metadata, - choiceType = this.choiceType - ) - - is WriteLabel -> WriteLabel( - local.changeVars(varLut), global.changeVars(varLut), labels, - metadata = metadata - ) + is NondetLabel -> NondetLabel(labels.map { it.changeVars(varLut, parseContext) }.toSet(), + metadata = metadata) + + is ReadLabel -> ReadLabel(local.changeVars(varLut), global.changeVars(varLut), labels, + metadata = metadata) + + is SequenceLabel -> SequenceLabel(labels.map { it.changeVars(varLut, parseContext) }, + metadata = metadata) + + is StartLabel -> StartLabel(name, params.map { it.changeVars(varLut, parseContext) }, + pidVar.changeVars(varLut), metadata = metadata) + + is StmtLabel -> StmtLabel(stmt.changeVars(varLut, parseContext), metadata = metadata, + choiceType = this.choiceType) + + is WriteLabel -> WriteLabel(local.changeVars(varLut), global.changeVars(varLut), labels, + metadata = metadata) is ReturnLabel -> ReturnLabel(enclosedLabel.changeVars(varLut)) @@ -121,15 +107,11 @@ fun XcfaLabel.changeVars(varLut: Map, VarDecl<*>>, parseContext: Par @JvmOverloads fun Stmt.changeVars(varLut: Map, VarDecl<*>>, parseContext: ParseContext? = null): Stmt { val stmt = when (this) { - is AssignStmt<*> -> AssignStmt.of( - cast(varDecl.changeVars(varLut), varDecl.type), - cast(expr.changeVars(varLut, parseContext), varDecl.type) - ) - - is MemoryAssignStmt<*, *, *> -> MemoryAssignStmt.create( - deref.changeVars(varLut) as Dereference, - expr.changeVars(varLut) - ) + is AssignStmt<*> -> AssignStmt.of(cast(varDecl.changeVars(varLut), varDecl.type), + cast(expr.changeVars(varLut, parseContext), varDecl.type)) + + is MemoryAssignStmt<*, *, *> -> MemoryAssignStmt.create(deref.changeVars(varLut) as Dereference, + expr.changeVars(varLut)) is HavocStmt<*> -> HavocStmt.of(varDecl.changeVars(varLut)) is AssumeStmt -> AssumeStmt.of(cond.changeVars(varLut, parseContext)) diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt index b7b48eb5a4..65a89e0533 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/gson/GsonTest.kt @@ -46,15 +46,11 @@ class GsonTest { private fun getGson(scope: XcfaScope, env: Env, newScope: Boolean): Gson { val gsonBuilder = GsonBuilder() lateinit var gson: Gson - gsonBuilder.registerTypeHierarchyAdapter( - XcfaLocation::class.java, - StringTypeAdapter(xcfaLocationAdapter) - ) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLocation::class.java, + StringTypeAdapter(xcfaLocationAdapter)) gsonBuilder.registerTypeHierarchyAdapter(XCFA::class.java, XcfaAdapter { gson }) - gsonBuilder.registerTypeHierarchyAdapter( - VarDecl::class.java, - VarDeclAdapter({ gson }, scope, env, !newScope) - ) + gsonBuilder.registerTypeHierarchyAdapter(VarDecl::class.java, + VarDeclAdapter({ gson }, scope, env, !newScope)) gsonBuilder.registerTypeHierarchyAdapter(Stmt::class.java, StringTypeAdapter { StatementWrapper(it, scope).instantiate(env) }) gsonBuilder.registerTypeHierarchyAdapter(Expr::class.java, @@ -63,10 +59,8 @@ class GsonTest { StringTypeAdapter { TypeWrapper(it).instantiate() }) gsonBuilder.registerTypeHierarchyAdapter(VarIndexing::class.java, StringTypeAdapter { BasicVarIndexing.fromString(it, scope, env) }) - gsonBuilder.registerTypeHierarchyAdapter( - XcfaLabel::class.java, - XcfaLabelAdapter(scope, env, { gson }) - ) + gsonBuilder.registerTypeHierarchyAdapter(XcfaLabel::class.java, + XcfaLabelAdapter(scope, env, { gson })) gsonBuilder.registerTypeHierarchyAdapter(MetaData::class.java, MetaDataAdapter()) gsonBuilder.registerTypeHierarchyAdapter(Pair::class.java, PairAdapter { gson }) gsonBuilder.registerTypeHierarchyAdapter(Optional::class.java, OptionalAdapter { gson }) @@ -118,10 +112,8 @@ class GsonTest { val env = Env() val gson = getGson(symbolTable, env, true) - assertEquals( - parseContext.metadata.lookupKeyValue, - gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue - ) + assertEquals(parseContext.metadata.lookupKeyValue, + gson.fromJson(gson.toJson(parseContext), ParseContext::class.java).metadata.lookupKeyValue) } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt index e1084b1fab..570ab2b126 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/PassTests.kt @@ -45,8 +45,7 @@ class PassTests { global: VarContext.() -> Unit, input: XcfaProcedureBuilderContext.() -> Unit, output: (XcfaProcedureBuilderContext.() -> Unit)?, - val passes: List - ) : Arguments { + val passes: List) : Arguments { private val builder = XcfaBuilder("").also { it.global(global) } private val inputBuilder = builder.procedure("", input).builder @@ -333,13 +332,11 @@ class PassTests { } (init to final) { "y".assign( - "(ite (isinfinite x) #b00000000000000000000000000000001 #b00000000000000000000000000000000)" - ) + "(ite (isinfinite x) #b00000000000000000000000000000001 #b00000000000000000000000000000000)") } (init to final) { "y".assign( - "(ite (or (isinfinite x) (fpisnan x)) #b00000000000000000000000000000000 #b00000000000000000000000000000001)" - ) + "(ite (or (isinfinite x) (fpisnan x)) #b00000000000000000000000000000000 #b00000000000000000000000000000001)") } }, ), @@ -375,8 +372,7 @@ class PassTests { "y".assign("x").also { parseContext.metadata.create( ((it.labels.last() as StmtLabel).stmt as AssignStmt<*>).varDecl.ref, "cType", - CSignedInt(null, parseContext) - ) + CSignedInt(null, parseContext)) } } }, @@ -535,10 +531,8 @@ class PassTests { @ParameterizedTest @MethodSource("getData") - fun testPass( - input: XcfaProcedureBuilder, output: XcfaProcedureBuilder?, - passes: List - ) { + fun testPass(input: XcfaProcedureBuilder, output: XcfaProcedureBuilder?, + passes: List) { println("Trying to run $passes on input...") val actualOutput = passes.fold(input) { acc, procedurePass -> procedurePass.run(acc) } .build(dummyXcfa) @@ -568,15 +562,10 @@ class PassTests { @Test fun testInline() { val xcfaSource = xcfa("example") { - procedure( - "main", ProcedurePassManager( - listOf( - NormalizePass(), - DeterministicPass(), - InlineProceduresPass(parseContext) - ) - ) - ) { + procedure("main", ProcedurePassManager(listOf( + NormalizePass(), + DeterministicPass(), + InlineProceduresPass(parseContext)))) { (init to final) { "proc1"() } diff --git a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt index f2f25a473a..77c48dc44e 100644 --- a/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt +++ b/subprojects/xcfa/xcfa/src/test/java/hu/bme/mit/theta/xcfa/passes/UtilsTest.kt @@ -39,37 +39,25 @@ class UtilsTest { @JvmStatic fun getLabels(): List = listOf( - Arguments.of( - InvokeLabel("", listOf(x.ref, y.ref), EmptyMetaData), - InvokeLabel("", listOf(xPrime.ref, y.ref), EmptyMetaData) - ), + Arguments.of(InvokeLabel("", listOf(x.ref, y.ref), EmptyMetaData), + InvokeLabel("", listOf(xPrime.ref, y.ref), EmptyMetaData)), Arguments.of(JoinLabel(x, EmptyMetaData), JoinLabel(xPrime, EmptyMetaData)), Arguments.of(NondetLabel(setOf(NopLabel), EmptyMetaData), NondetLabel(setOf(NopLabel), EmptyMetaData)), - Arguments.of( - SequenceLabel(listOf(NopLabel), EmptyMetaData), - SequenceLabel(listOf(NopLabel), EmptyMetaData) - ), + Arguments.of(SequenceLabel(listOf(NopLabel), EmptyMetaData), + SequenceLabel(listOf(NopLabel), EmptyMetaData)), Arguments.of(ReadLabel(x, y, setOf(), EmptyMetaData), ReadLabel(xPrime, y, setOf(), EmptyMetaData)), Arguments.of(WriteLabel(x, y, setOf(), EmptyMetaData), WriteLabel(xPrime, y, setOf(), EmptyMetaData)), Arguments.of(FenceLabel(setOf(), EmptyMetaData), FenceLabel(setOf(), EmptyMetaData)), - Arguments.of( - StartLabel("", listOf(x.ref), y, EmptyMetaData), - StartLabel("", listOf(xPrime.ref), y, EmptyMetaData) - ), + Arguments.of(StartLabel("", listOf(x.ref), y, EmptyMetaData), + StartLabel("", listOf(xPrime.ref), y, EmptyMetaData)), Arguments.of(ReturnLabel(JoinLabel(x, EmptyMetaData)), ReturnLabel(JoinLabel(xPrime, EmptyMetaData))), - Arguments.of( - StmtLabel(Assign(x, y.ref)), - StmtLabel(Assign(xPrime, y.ref)) - ), - Arguments.of( - StmtLabel(Havoc(x)), - StmtLabel(Havoc(xPrime)) - ), - Arguments.of( - StmtLabel(Assume(Eq(x.ref, y.ref))), - StmtLabel(Assume(Eq(xPrime.ref, y.ref))) - ), + Arguments.of(StmtLabel(Assign(x, y.ref)), + StmtLabel(Assign(xPrime, y.ref))), + Arguments.of(StmtLabel(Havoc(x)), + StmtLabel(Havoc(xPrime))), + Arguments.of(StmtLabel(Assume(Eq(x.ref, y.ref))), + StmtLabel(Assume(Eq(xPrime.ref, y.ref)))), Arguments.of(StmtLabel(Skip()), StmtLabel(Skip())), ) } diff --git a/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt b/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt index 63d339aeb7..487a206379 100644 --- a/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt +++ b/subprojects/xcfa/xcfa2chc/src/test/java/hu/bme/mit/theta/xcfa2chc/TestChcUtils.kt @@ -139,47 +139,27 @@ class TestChcUtils { val init = Relation("init", i2i, i2i, i2i, i2i, Int()) // br, co, rf, com - val T0 = Relation( - "T0", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0G = Relation( - "T0_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0C = Relation( - "T0_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0CF = Relation( - "T0_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0F = Relation( - "T0_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - - val T1 = Relation( - "T1", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1G = Relation( - "T1_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1C = Relation( - "T1_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1CF = Relation( - "T1_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1F = Relation( - "T1_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), - Int() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0 = Relation("T0", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0G = Relation("T0_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0C = Relation("T0_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0CF = Relation("T0_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0F = Relation("T0_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + + val T1 = Relation("T1", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1G = Relation("T1_gate", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1C = Relation("T1_critical", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1CF = Relation("T1_critical_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1F = Relation("T1_final", i2i, i2i, i2i, i2i, Int(), Int(), Int(), Int(), + Int()) // br, co, rf, com, eid, turn, flag0, flag1, cnt val W = Relation("W", i2i, i2i, i2i, i2i, Int(), Int(), Int()) // br, co, rf, com, eid, vid, val @@ -460,39 +440,23 @@ class TestChcUtils { val init = Relation("init", i2i, i2i, i2i, i2i, Int()) // br, co, rf, com - val T0 = Relation( - "T0", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0G = Relation( - "T0_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0C = Relation( - "T0_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T0F = Relation( - "T0_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - - val T1 = Relation( - "T1", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1G = Relation( - "T1_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1C = Relation( - "T1_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt - val T1F = Relation( - "T1_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), - Bool() - ) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0 = Relation("T0", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0G = Relation("T0_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0C = Relation("T0_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T0F = Relation("T0_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + + val T1 = Relation("T1", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1G = Relation("T1_gate", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1C = Relation("T1_critical", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt + val T1F = Relation("T1_final", i2i, i2i, i2i, i2i, Int(), Bool(), Bool(), Bool(), + Bool()) // br, co, rf, com, eid, turn, flag0, flag1, cnt val W = Relation("W", i2i, i2i, i2i, i2i, Int(), Int(), Bool()) // br, co, rf, com, eid, vid, val diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt index 8d733b0bfe..4e4a63908b 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/XstsToRelations.kt @@ -55,8 +55,7 @@ fun XSTS.toRelations(): List { is EnumLitExpr -> { val value = enumValueLut.computeIfAbsent(this.type) { LinkedHashMap() }.computeIfAbsent( - this.value - ) { cnt++ } + this.value) { cnt++ } return IntLitExpr.of(BigInteger.valueOf(value.toLong())) } diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt index 06eead3068..a78b5bb70c 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/RandomXsts.kt @@ -29,10 +29,8 @@ import hu.bme.mit.theta.xsts.XSTS import kotlin.random.Random @JvmOverloads -fun generateXsts( - seed: Int, numCtrl: Int = 1, numClock: Int = 1, numOther: Int = 3, - requireAllVarsWritten: Boolean = false -): XSTS { +fun generateXsts(seed: Int, numCtrl: Int = 1, numClock: Int = 1, numOther: Int = 3, + requireAllVarsWritten: Boolean = false): XSTS { val writtenVars = object : StmtVisitor>, Set>> { override fun visit(stmt: SkipStmt?, param: Set>): Set> { return param @@ -79,8 +77,7 @@ fun generateXsts( } override fun visit( - stmt: MemoryAssignStmt?, param: Set>? - ): Set> { + stmt: MemoryAssignStmt?, param: Set>?): Set> { TODO("Not yet implemented") } @@ -181,21 +178,17 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { } fun randomSeq(currDepth: Int, maxDepth: Int): Stmt { - return Stmts.SequenceStmt( - listOf( - randomIntermediate(currDepth + 1, maxDepth), - randomIntermediate(currDepth + 1, maxDepth) - ) - ) + return Stmts.SequenceStmt(listOf( + randomIntermediate(currDepth + 1, maxDepth), + randomIntermediate(currDepth + 1, maxDepth) + )) } fun randomNonDet(currDepth: Int, maxDepth: Int): Stmt { - return Stmts.NonDetStmt( - listOf( - randomIntermediate(currDepth + 1, maxDepth), - randomIntermediate(currDepth + 1, maxDepth) - ) - ) + return Stmts.NonDetStmt(listOf( + randomIntermediate(currDepth + 1, maxDepth), + randomIntermediate(currDepth + 1, maxDepth) + )) } @@ -203,8 +196,7 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { var expr: Expr do expr = randomBoolExpr(0) while (ExprUtils.getVars(expr).isEmpty()) - return IfStmt.of( - expr, + return IfStmt.of(expr, randomIntermediate(currDepth + 1, maxDepth), randomIntermediate(currDepth + 1, maxDepth) ) @@ -230,8 +222,7 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { { BoolExprs.Or( randomBoolExpr(currDepth + 1), - randomBoolExpr(currDepth + 1) - ) + randomBoolExpr(currDepth + 1)) }, { BoolExprs.Imply(randomBoolExpr(currDepth + 1), randomBoolExpr(currDepth + 1)) }, { BoolExprs.Iff(randomBoolExpr(currDepth + 1), randomBoolExpr(currDepth + 1)) }, @@ -305,8 +296,7 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { } fun randomAssume() = (listOf(this::randomDataAssume) + (if (clockVars.isEmpty()) listOf() else listOf( - this::randomClockConstraint - ))).random(random)() + this::randomClockConstraint))).random(random)() fun randomDataAssume(): Stmt { var expr: Expr @@ -333,15 +323,13 @@ class RandomXsts(seed: Int, val exprMaxDepth: Int) { ).random()() val compareTo = IntExprs.Int(random.nextInt(10)) - return Stmts.Assume( - listOf( - { IntExprs.Leq(c, compareTo) }, - { IntExprs.Lt(c, compareTo) }, - { IntExprs.Geq(c, compareTo) }, - { IntExprs.Gt(c, compareTo) }, - { IntExprs.Eq(c, compareTo) }, - ).random(random)() - ) + return Stmts.Assume(listOf( + { IntExprs.Leq(c, compareTo) }, + { IntExprs.Lt(c, compareTo) }, + { IntExprs.Geq(c, compareTo) }, + { IntExprs.Gt(c, compareTo) }, + { IntExprs.Eq(c, compareTo) }, + ).random(random)()) } fun randomHavoc(): Stmt { diff --git a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt index e3d98a6c68..833a03799a 100644 --- a/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt +++ b/subprojects/xsts/xsts-analysis/src/main/kotlin/hu/bme/mit/theta/xsts/analysis/util/XstsSerializer.kt @@ -100,8 +100,7 @@ object XstsSerializer : StmtVisitor { } override fun visit( - stmt: MemoryAssignStmt?, param: Void? - ): String { + stmt: MemoryAssignStmt?, param: Void?): String { TODO("Not yet implemented") } diff --git a/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt b/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt index 7c9fd82f2f..c38b044ec5 100644 --- a/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt +++ b/subprojects/xsts/xsts/src/main/kotlin/hu/bme/mit/theta/xsts/utils/XSTSVarChanger.kt @@ -25,9 +25,7 @@ fun XSTS.copyWithReplacingVars(variableMapping: Map>): XSTS { val matchingCtrlVarNames = ctrlVars.filter { variableMapping.containsKey(it.name) }.map { it.name } val newCtrlVars = ctrlVars.filter { it.name !in variableMapping } .toSet() + variableMapping.filter { it.key in matchingCtrlVarNames }.values.toSet() - return XSTS( - newCtrlVars, init.changeVars(variableMapping) as NonDetStmt, + return XSTS(newCtrlVars, init.changeVars(variableMapping) as NonDetStmt, tran.changeVars(variableMapping) as NonDetStmt, env.changeVars(variableMapping) as NonDetStmt, - initFormula.changeVars(variableMapping), prop.changeVars(variableMapping) - ) + initFormula.changeVars(variableMapping), prop.changeVars(variableMapping)) } \ No newline at end of file From 348cbbe3449f7fcc3fc0262dfce14a6775e9ba43 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:23:16 +0200 Subject: [PATCH 27/40] Version bump --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7c35deef20..54816a6b4d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -89,4 +89,4 @@ tasks { username = System.getenv("OSSRH_USERNAME") password = System.getenv("OSSRH_PASSWORD") } -} \ No newline at end of file +} From 416f3b650cf25dd531d80e6d37abc64f5207ade9 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:27:33 +0200 Subject: [PATCH 28/40] Updated actions --- .github/actions/check-formatting/action.yml | 6 +- .github/workflows/reapply_copyright.yml | 77 --------------------- .github/workflows/reformat-code.yml | 9 +-- 3 files changed, 4 insertions(+), 88 deletions(-) delete mode 100644 .github/workflows/reapply_copyright.yml diff --git a/.github/actions/check-formatting/action.yml b/.github/actions/check-formatting/action.yml index 89ad28ffd8..72cf9f45cb 100644 --- a/.github/actions/check-formatting/action.yml +++ b/.github/actions/check-formatting/action.yml @@ -6,8 +6,6 @@ runs: - name: Checkout code uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Check for formatting - uses: leventeBajczi/intellij-idea-format@v1.0 + uses: ./.github/actions/cache-build with: - settings-file: "./.idea/codeStyles/Project.xml" - file-mask: "*.java,*.kt" - additional-options: "-dry" \ No newline at end of file + arguments: spotlessCheck \ No newline at end of file diff --git a/.github/workflows/reapply_copyright.yml b/.github/workflows/reapply_copyright.yml deleted file mode 100644 index 3acc9e3876..0000000000 --- a/.github/workflows/reapply_copyright.yml +++ /dev/null @@ -1,77 +0,0 @@ -name: Reapply Copyright - -on: - workflow_dispatch: - inputs: - file_mask: - description: 'File mask to reapply license header (argument to find)' - required: true - default: '-name "*.java" -o -name "*.kt" -o -name "*.kts"' - direct-commit: - type: boolean - default: false - description: Commit directly to source (instead of opening a PR) - -jobs: - copyright_checker: - runs-on: ubuntu-latest - steps: - - uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 - id: generate-token - with: - app_id: ${{ secrets.APP_ID }} - private_key: ${{ secrets.APP_PRIVATE_KEY }} - - - name: Checkout repository - uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - with: - token: ${{ steps.generate-token.outputs.token }} - - - name: Run Copyright Checker - shell: bash {0} - run: | - set +x - - for file in $(find . -type f \( ${{ inputs.file_mask }} \)); do - last_modified_year=$(git log -1 --format=%ad --date=format:%Y "$file") - echo "Checking file $file, last modified $last_modified_year" - - header_exists=$(head -n 2 "$file" | tail -n 1 | grep -c "Budapest University of Technology") - - echo "Header exists for $file: $header_exists" - - if [[ $header_exists -eq 0 ]]; then - echo "Adding copyright header to $file" - cat ./doc/copyright-header.txt "$file" > tmp_026204264 - mv tmp_026204264 "$file" - fi - - header_year=$(head -n 2 "$file" | tail -n 1 | grep -o -E '[0-9]{4}') - - echo "Header year for $file: $header_year" - - if [[ "$header_year" != "$last_modified_year" ]]; then - echo "Updating copyright year to $last_modified_year in $file (was $header_year)" - sed -i "s/Copyright [0-9]\{4\}/Copyright $last_modified_year/g" "$file" - fi - done - - - name: Create Pull Request - if: ${{ !inputs.direct-commit }} - uses: peter-evans/create-pull-request@153407881ec5c347639a548ade7d8ad1d6740e38 - with: - commit-message: "Reapplied copyright" - branch: "copyright-reapply" - title: '[AutoPR] Reaplied copyright' - token: ${{ steps.generate-token.outputs.token }} - committer: ThetaBotMaintainer[bot] <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> - author: ThetaBotMaintainer[bot] <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> - - - name: Commit changes - if: ${{ inputs.direct-commit }} - uses: stefanzweifel/git-auto-commit-action@3ea6ae190baf489ba007f7c92608f33ce20ef04a - with: - commit_message: "Reapplied copyright" - commit_user_name: ThetaBotMaintainer[bot] - commit_user_email: 139346997+ThetaBotMaintainer[bot]@users.noreply.github.com - commit_author: ThetaBotMaintainer[bot] <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> \ No newline at end of file diff --git a/.github/workflows/reformat-code.yml b/.github/workflows/reformat-code.yml index fe6fc24d9f..29411d1f37 100644 --- a/.github/workflows/reformat-code.yml +++ b/.github/workflows/reformat-code.yml @@ -3,10 +3,6 @@ name: Reformat code on: workflow_dispatch: inputs: - file_mask: - description: 'File mask to reformat' - required: true - default: '*.java,*.kts,*.kt' direct-commit: type: boolean default: false @@ -28,10 +24,9 @@ jobs: token: ${{ steps.generate-token.outputs.token }} - name: Do reformat - uses: leventeBajczi/intellij-idea-format@v1.0 + uses: ./.github/actions/cache-build with: - settings-file: "./.idea/codeStyles/Project.xml" - file-mask: ${{ inputs.file_mask }} + arguments: spotlessApply - name: Create Pull Request if: ${{ !inputs.direct-commit }} From 8e5a991f00114ef99307c93e541b69c8dd86ba9a Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:42:51 +0200 Subject: [PATCH 29/40] Added 'git fetch origin main' to ci Removed branch name --- .github/actions/cache-build/action.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/actions/cache-build/action.yml b/.github/actions/cache-build/action.yml index 277be1eb47..b1c7d0945d 100644 --- a/.github/actions/cache-build/action.yml +++ b/.github/actions/cache-build/action.yml @@ -6,13 +6,10 @@ inputs: runs: using: "composite" steps: -# - uses: actions/cache@88522ab9f39a2ea568f7027eddc7d8d8bc9d59c8 -# if: runner.os == 'Linux' -# id: cache -# with: -# path: . -# key: ${{ runner.os }}-${{github.sha}} - + - name: fetch + shell: bash + run: | + git fetch origin - name: build gradle uses: gradle/gradle-build-action@40b6781dcdec2762ad36556682ac74e31030cfe2 # v2.5.1 with: From 377355702d3e8f3264538a216f68ee836db59bd6 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:50:59 +0200 Subject: [PATCH 30/40] spotlessCheck not dependency of check --- buildSrc/src/main/kotlin/java-common.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/buildSrc/src/main/kotlin/java-common.gradle.kts b/buildSrc/src/main/kotlin/java-common.gradle.kts index 1eb2c30393..7f02a1bb67 100644 --- a/buildSrc/src/main/kotlin/java-common.gradle.kts +++ b/buildSrc/src/main/kotlin/java-common.gradle.kts @@ -69,6 +69,8 @@ tasks { spotless { ratchetFrom("origin/master") + + enforceCheck false val year = "\$YEAR" // you can't escape $ in raw strings.. val licenseHeader = """ /* From ac78c548952d0667f7e0f592e883b80188cd4973 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Sat, 19 Oct 2024 15:53:48 +0200 Subject: [PATCH 31/40] Syntax fix in gradle Syntax fix in gradle #2 --- buildSrc/src/main/kotlin/java-common.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/kotlin/java-common.gradle.kts b/buildSrc/src/main/kotlin/java-common.gradle.kts index 7f02a1bb67..838b4d4f41 100644 --- a/buildSrc/src/main/kotlin/java-common.gradle.kts +++ b/buildSrc/src/main/kotlin/java-common.gradle.kts @@ -70,7 +70,7 @@ tasks { spotless { ratchetFrom("origin/master") - enforceCheck false + isEnforceCheck = false val year = "\$YEAR" // you can't escape $ in raw strings.. val licenseHeader = """ /* From 5323d7f84ebc4e7b359ac6801dcaa89d04f9f012 Mon Sep 17 00:00:00 2001 From: "ThetaBotMaintainer[bot]" <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:29:02 +0000 Subject: [PATCH 32/40] Version bump --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 54816a6b4d..4316bed633 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.6.1" + version = "6.6.2" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } From 3fe13bfe2933ae5b3ba4eeca971ff964d5a45199 Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Mon, 21 Oct 2024 20:10:50 +0200 Subject: [PATCH 33/40] Fixed restarting --- .github/actions/benchexec-report/action.yml | 4 ++-- .github/workflows/check-copyright.yml | 2 +- .github/workflows/check-formatting.yml | 2 +- .github/workflows/check-version.yml | 2 +- .github/workflows/linux-build-test-deploy.yml | 2 +- .github/workflows/mac-build-test.yml | 2 +- .github/workflows/sonar.yml | 2 +- .github/workflows/win-build-test.yml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/actions/benchexec-report/action.yml b/.github/actions/benchexec-report/action.yml index 2fc30c965c..ea031af136 100644 --- a/.github/actions/benchexec-report/action.yml +++ b/.github/actions/benchexec-report/action.yml @@ -48,7 +48,7 @@ runs: then printf "\n| $task | " >> $GITHUB_OUTPUT fi lasttask="$task" - printf " $emoji ($correct / $incorrect / $all) [HTML](https://theta.mit.bme.hu/benchmark-results/${{ github.head_ref }}/$i/$(ls *.html))/[CSV](https://theta.mit.bme.hu/benchmark-results/${{ github.head_ref }}/$i/$(ls *.csv)) | " >> $GITHUB_OUTPUT + printf " $emoji ($correct / $incorrect / $all) [HTML](https://theta.mit.bme.hu/benchmark-results/${{ github.ref }}/$i/$(ls *.html))/[CSV](https://theta.mit.bme.hu/benchmark-results/${{ github.ref }}/$i/$(ls *.csv)) | " >> $GITHUB_OUTPUT popd else rm -rf $i @@ -68,7 +68,7 @@ runs: with: branch: gh-pages folder: artifacts - target-folder: benchmark-results/${{ github.head_ref }}/ + target-folder: benchmark-results/${{ github.ref }}/ single-commit: true - name: Comment on PR if: github.event_name == 'pull_request' diff --git a/.github/workflows/check-copyright.yml b/.github/workflows/check-copyright.yml index c441a8d667..74e14ec9d1 100644 --- a/.github/workflows/check-copyright.yml +++ b/.github/workflows/check-copyright.yml @@ -7,7 +7,7 @@ on: permissions: write-all concurrency: - group: copyright-${{ github.head_ref }} + group: copyright-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/check-formatting.yml b/.github/workflows/check-formatting.yml index 213bdcb52d..92661091a4 100644 --- a/.github/workflows/check-formatting.yml +++ b/.github/workflows/check-formatting.yml @@ -7,7 +7,7 @@ on: permissions: write-all concurrency: - group: formatting-${{ github.head_ref }} + group: formatting-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/check-version.yml b/.github/workflows/check-version.yml index 343ed50f53..ac0484a98a 100644 --- a/.github/workflows/check-version.yml +++ b/.github/workflows/check-version.yml @@ -4,7 +4,7 @@ on: types: [opened, synchronize, reopened] concurrency: - group: version-${{ github.head_ref }} + group: version-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/linux-build-test-deploy.yml b/.github/workflows/linux-build-test-deploy.yml index 6d5b209e16..4c101aca95 100644 --- a/.github/workflows/linux-build-test-deploy.yml +++ b/.github/workflows/linux-build-test-deploy.yml @@ -13,7 +13,7 @@ on: permissions: write-all concurrency: - group: deploy-${{ github.head_ref }}-${{ github.event_name }} + group: deploy-${{ github.ref }}-${{ github.event_name }} cancel-in-progress: true jobs: diff --git a/.github/workflows/mac-build-test.yml b/.github/workflows/mac-build-test.yml index 4a0f2183b0..71994579a5 100644 --- a/.github/workflows/mac-build-test.yml +++ b/.github/workflows/mac-build-test.yml @@ -7,7 +7,7 @@ on: permissions: write-all concurrency: - group: mac-${{ github.head_ref }} + group: mac-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index c291bdc97c..c66a14c329 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -8,7 +8,7 @@ on: permissions: read-all concurrency: - group: sonar-${{ github.head_ref }} + group: sonar-${{ github.ref }} cancel-in-progress: true jobs: diff --git a/.github/workflows/win-build-test.yml b/.github/workflows/win-build-test.yml index 1288984285..7fc33a46f5 100644 --- a/.github/workflows/win-build-test.yml +++ b/.github/workflows/win-build-test.yml @@ -7,7 +7,7 @@ on: permissions: write-all concurrency: - group: win-${{ github.head_ref }} + group: win-${{ github.ref }} cancel-in-progress: true jobs: From 5b1b673cb4b559c1469ea0accfef94f51e9a109a Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Mon, 21 Oct 2024 20:16:47 +0200 Subject: [PATCH 34/40] Added PR comment --- .github/workflows/check-formatting.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check-formatting.yml b/.github/workflows/check-formatting.yml index 92661091a4..3f7e3ccd91 100644 --- a/.github/workflows/check-formatting.yml +++ b/.github/workflows/check-formatting.yml @@ -16,5 +16,19 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 + - name: Setup java 17 + uses: actions/setup-java@5ffc13f4174014e2d4d4572b3d74c3fa61aeb2c2 # v3.11.0 + with: + distribution: temurin + java-version: 17 - name: Checking formatting - uses: ./.github/actions/check-formatting \ No newline at end of file + uses: ./.github/actions/check-formatting + - name: Comment + if: failure() && github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'reformat' + mode: 'recreate' + message: | + :exclamation: Please run `./gradlew spotlessApply` on your branch to fix formatting. From 8e5e212fbaef88d485fb25c69cff583137cfa69b Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Mon, 21 Oct 2024 20:18:53 +0200 Subject: [PATCH 35/40] Added more PR comments --- .github/workflows/check-copyright.yml | 11 ++++++++++- .github/workflows/check-version.yml | 11 ++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-copyright.yml b/.github/workflows/check-copyright.yml index 74e14ec9d1..0869284bdb 100644 --- a/.github/workflows/check-copyright.yml +++ b/.github/workflows/check-copyright.yml @@ -17,4 +17,13 @@ jobs: - name: Checkout repository uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3.5.3 - name: Check copyright - uses: ./.github/actions/check-copyright \ No newline at end of file + uses: ./.github/actions/check-copyright + - name: Comment + if: failure() && github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'copyright' + mode: 'recreate' + message: | + :exclamation: Please run `./gradlew spotlessApply` on your branch to fix copyright headers. \ No newline at end of file diff --git a/.github/workflows/check-version.yml b/.github/workflows/check-version.yml index ac0484a98a..1546929f98 100644 --- a/.github/workflows/check-version.yml +++ b/.github/workflows/check-version.yml @@ -35,4 +35,13 @@ jobs: if: ${{ steps.new_version.outputs.version == steps.master_version.outputs.version }} run: | echo "New version ${{ steps.new_version.outputs.version }} is NOT OK" - exit 1 \ No newline at end of file + exit 1 + - name: Comment + if: failure() && github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'version' + mode: 'recreate' + message: | + :exclamation: Please modify `build.gradle.kts` to contain a later version than ${{ steps.master_version.outputs.version }}. Current version is ${{ steps.new_version.outputs.version }}. \ No newline at end of file From d655fe082861cbb64fcf3f29c12d0dd81b6a1b2d Mon Sep 17 00:00:00 2001 From: Levente Bajczi Date: Mon, 21 Oct 2024 20:32:55 +0200 Subject: [PATCH 36/40] Removing comment on fix --- .github/workflows/check-copyright.yml | 10 +++++++++- .github/workflows/check-formatting.yml | 8 ++++++++ .github/workflows/check-version.yml | 10 +++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/.github/workflows/check-copyright.yml b/.github/workflows/check-copyright.yml index 0869284bdb..7eb1f23215 100644 --- a/.github/workflows/check-copyright.yml +++ b/.github/workflows/check-copyright.yml @@ -26,4 +26,12 @@ jobs: comment_tag: 'copyright' mode: 'recreate' message: | - :exclamation: Please run `./gradlew spotlessApply` on your branch to fix copyright headers. \ No newline at end of file + :exclamation: Please run `./gradlew spotlessApply` on your branch to fix copyright headers. + + - name: Delete Comment + if: github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'copyright' + mode: 'delete' \ No newline at end of file diff --git a/.github/workflows/check-formatting.yml b/.github/workflows/check-formatting.yml index 3f7e3ccd91..02647f3a04 100644 --- a/.github/workflows/check-formatting.yml +++ b/.github/workflows/check-formatting.yml @@ -32,3 +32,11 @@ jobs: mode: 'recreate' message: | :exclamation: Please run `./gradlew spotlessApply` on your branch to fix formatting. + + - name: Delete Comment + if: github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'reformat' + mode: 'delete' \ No newline at end of file diff --git a/.github/workflows/check-version.yml b/.github/workflows/check-version.yml index 1546929f98..83cbf94600 100644 --- a/.github/workflows/check-version.yml +++ b/.github/workflows/check-version.yml @@ -44,4 +44,12 @@ jobs: comment_tag: 'version' mode: 'recreate' message: | - :exclamation: Please modify `build.gradle.kts` to contain a later version than ${{ steps.master_version.outputs.version }}. Current version is ${{ steps.new_version.outputs.version }}. \ No newline at end of file + :exclamation: Please modify `build.gradle.kts` to contain a later version than ${{ steps.master_version.outputs.version }}. Current version is ${{ steps.new_version.outputs.version }}. + + - name: Delete Comment + if: github.event_name == 'pull_request' + uses: thollander/actions-comment-pull-request@dadb7667129e23f12ca3925c90dc5cd7121ab57e + continue-on-error: true # if we are in a fork, this will fail, but we don't care (tables will be missing) + with: + comment_tag: 'version' + mode: 'delete' \ No newline at end of file From e0868af3e8115ba4dde05203cbbb6abec14f2007 Mon Sep 17 00:00:00 2001 From: "ThetaBotMaintainer[bot]" <139346997+ThetaBotMaintainer[bot]@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:48:47 +0000 Subject: [PATCH 37/40] Version bump --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4316bed633..b76fd9f7ff 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.6.2" + version = "6.6.3" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } From 292dd94b789382e9ff453b7275c105dee04ade91 Mon Sep 17 00:00:00 2001 From: RipplB Date: Thu, 18 Jul 2024 13:17:15 +0200 Subject: [PATCH 38/40] Generalize abstractor, refiner, cegarchecker, visualizer These classes/interfaces depended on ARG and Trace before, which heavily limits reusability. They are now generalized over Witness and Cex. To ease the switch, the old entry points are replicated in "Arg..." classes, so a lot of these changes are just renames. --- build.gradle.kts | 2 +- .../cfa/analysis/config/CfaConfigBuilder.java | 433 ++++++++++--- .../analysis/algorithm/cegar/Abstractor.java | 22 +- .../algorithm/cegar/ArgAbstractor.java | 28 + .../algorithm/cegar/ArgCegarChecker.java | 48 ++ .../analysis/algorithm/cegar/ArgRefiner.java | 29 + ...bstractor.java => BasicArgAbstractor.java} | 12 +- .../algorithm/cegar/CegarChecker.java | 59 +- .../analysis/algorithm/cegar/Refiner.java | 18 +- .../algorithm/cegar/RefinerResult.java | 44 +- .../expr/refinement/AasporRefiner.java | 15 +- .../refinement/MultiExprTraceRefiner.java | 16 +- .../refinement/SingleExprTraceRefiner.java | 6 +- .../theta/analysis/utils/ArgVisualizer.java | 7 +- .../analysis/utils/WitnessVisualizer.java | 26 + .../multi/config/StmtMultiConfigBuilder.kt | 350 ++++++++--- .../sts/analysis/config/StsConfigBuilder.java | 196 +++--- .../mit/theta/sts/analysis/StsExplTest.java | 10 +- .../mit/theta/sts/analysis/StsPredTest.java | 10 +- .../mit/theta/xcfa/analysis/XcfaAbstractor.kt | 137 ---- .../mit/theta/xcfa/analysis/XcfaAnalysis.kt | 496 +++++++++------ .../theta/xcfa/analysis/XcfaArgAbstractor.kt | 143 +++++ .../analysis/XcfaSingeExprTraceRefiner.kt | 4 +- .../xcfa/analysis/XcfaExplAnalysisTest.kt | 549 ++++++++-------- .../xcfa/analysis/XcfaPredAnalysisTest.kt | 563 +++++++++-------- .../xcfa/cli/checkers/ConfigToCegarChecker.kt | 63 +- .../mit/theta/xcfa/cli/params/ParamValues.kt | 592 ++++++++++-------- .../analysis/config/XstsConfigBuilder.java | 256 +++++--- .../theta/xta/analysis/XtaAnalysisTest.java | 8 +- .../xta/analysis/XtaZoneAnalysisTest.java | 8 +- 30 files changed, 2536 insertions(+), 1614 deletions(-) create mode 100644 subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgAbstractor.java create mode 100644 subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java create mode 100644 subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java rename subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/{BasicAbstractor.java => BasicArgAbstractor.java} (91%) create mode 100644 subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java delete mode 100644 subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt create mode 100644 subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaArgAbstractor.kt diff --git a/build.gradle.kts b/build.gradle.kts index b76fd9f7ff..06036a38d7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ buildscript { allprojects { group = "hu.bme.mit.theta" - version = "6.6.3" + version = "6.6.4" apply(from = rootDir.resolve("gradle/shared-with-buildSrc/mirrors.gradle.kts")) } diff --git a/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/config/CfaConfigBuilder.java b/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/config/CfaConfigBuilder.java index 7427f38b20..37c30260ea 100644 --- a/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/config/CfaConfigBuilder.java +++ b/subprojects/cfa/cfa-analysis/src/main/java/hu/bme/mit/theta/cfa/analysis/config/CfaConfigBuilder.java @@ -15,16 +15,19 @@ */ package hu.bme.mit.theta.cfa.analysis.config; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.True; + import hu.bme.mit.theta.analysis.*; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators.ArgNodeComparator; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion; import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions; import hu.bme.mit.theta.analysis.expl.*; @@ -52,14 +55,10 @@ import hu.bme.mit.theta.common.logging.NullLogger; import hu.bme.mit.theta.solver.Solver; import hu.bme.mit.theta.solver.SolverFactory; - import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.True; - public class CfaConfigBuilder { private final SolverFactory abstractionSolverFactory; @@ -75,16 +74,19 @@ public class CfaConfigBuilder { private InitPrec initPrec = InitPrec.EMPTY; private PruneStrategy pruneStrategy = PruneStrategy.LAZY; - public CfaConfigBuilder(final Domain domain, final Refinement refinement, - final SolverFactory solverFactory) { + public CfaConfigBuilder( + final Domain domain, final Refinement refinement, final SolverFactory solverFactory) { this.domain = domain; this.refinement = refinement; this.abstractionSolverFactory = solverFactory; this.refinementSolverFactory = solverFactory; } - public CfaConfigBuilder(final Domain domain, final Refinement refinement, - final SolverFactory abstractionSolverFactory, final SolverFactory refinementSolverFactory) { + public CfaConfigBuilder( + final Domain domain, + final Refinement refinement, + final SolverFactory abstractionSolverFactory, + final SolverFactory refinementSolverFactory) { this.domain = domain; this.refinement = refinement; this.abstractionSolverFactory = abstractionSolverFactory; @@ -131,12 +133,13 @@ public CfaConfigBuilder pruneStrategy(final PruneStrategy pruneStrategy) { return this; } - public CfaConfig build(final CFA cfa, - final CFA.Loc errLoc) { + public CfaConfig build( + final CFA cfa, final CFA.Loc errLoc) { if (domain == Domain.EXPL) { return (new ExplStrategy(cfa)).buildConfig(errLoc); } - if (domain == Domain.PRED_BOOL || domain == Domain.PRED_CART + if (domain == Domain.PRED_BOOL + || domain == Domain.PRED_CART || domain == Domain.PRED_SPLIT) { return (new PredStrategy(cfa)).buildConfig(errLoc); } @@ -166,18 +169,53 @@ public enum Domain { public enum Refinement { FW_BIN_ITP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceFwBinItpChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createItpSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceFwBinItpChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createItpSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, BW_BIN_ITP { + }, + BW_BIN_ITP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceBwBinItpChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createItpSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createItpSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, SEQ_ITP { + }, + SEQ_ITP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceSeqItpChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createItpSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceSeqItpChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createItpSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } }, MULTI_SEQ { @@ -187,60 +225,229 @@ public StopCriterion getStopCriterion() { } @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return MultiExprTraceRefiner.create(ExprTraceSeqItpChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createItpSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return MultiExprTraceRefiner.create( + ExprTraceSeqItpChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createItpSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } }, UNSAT_CORE { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceUnsatCoreChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getVarsRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceUnsatCoreChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createUCSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getVarsRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, UCB { + }, + UCB { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceUCBChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceUCBChecker.create( + True(), + True(), + builderStrategy.getRefinementSolverFactory().createUCSolver()), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } }, NWT_WP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withoutIT().withSP().withoutLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withoutIT() + .withSP() + .withoutLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_SP { + }, + NWT_SP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withoutIT().withWP().withoutLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withoutIT() + .withWP() + .withoutLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_WP_LV { + }, + NWT_WP_LV { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withoutIT().withWP().withLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withoutIT() + .withWP() + .withLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_SP_LV { + }, + NWT_SP_LV { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withoutIT().withSP().withLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withoutIT() + .withSP() + .withLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_IT_WP { + }, + NWT_IT_WP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withIT().withWP().withoutLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withIT() + .withWP() + .withoutLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_IT_SP { + }, + NWT_IT_SP { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withIT().withSP().withoutLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withIT() + .withSP() + .withoutLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_IT_WP_LV { + }, + NWT_IT_WP_LV { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withIT().withWP().withLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withIT() + .withWP() + .withLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } - }, NWT_IT_SP_LV { + }, + NWT_IT_SP_LV { @Override - public Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy) { - return SingleExprTraceRefiner.create(ExprTraceNewtonChecker.create(True(), True(), builderStrategy.getRefinementSolverFactory().createUCSolver()).withIT().withSP().withLV(), builderStrategy.getPrecGranularity().createRefiner(builderStrategy.getItpRefToPrec()), builderStrategy.getPruneStrategy(), builderStrategy.getLogger()); + public + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy) { + return SingleExprTraceRefiner.create( + ExprTraceNewtonChecker.create( + True(), + True(), + builderStrategy + .getRefinementSolverFactory() + .createUCSolver()) + .withIT() + .withSP() + .withLV(), + builderStrategy + .getPrecGranularity() + .createRefiner(builderStrategy.getItpRefToPrec()), + builderStrategy.getPruneStrategy(), + builderStrategy.getLogger()); } }; @@ -248,24 +455,25 @@ public StopCriterion getStopCriterion() { return StopCriterions.firstCex(); } - public abstract Refiner, CfaAction, CfaPrec

> getRefiner(BuilderStrategy builderStrategy); - + public abstract + ArgRefiner, CfaAction, CfaPrec

> getRefiner( + BuilderStrategy builderStrategy); } public enum Search { BFS { @Override public ArgNodeComparator getComp(final CFA cfa, final CFA.Loc errLoc) { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.bfs()); + return ArgNodeComparators.combine( + ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()); } }, DFS { @Override public ArgNodeComparator getComp(final CFA cfa, final CFA.Loc errLoc) { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.dfs()); + return ArgNodeComparators.combine( + ArgNodeComparators.targetFirst(), ArgNodeComparators.dfs()); } }, @@ -277,7 +485,6 @@ public ArgNodeComparator getComp(final CFA cfa, final CFA.Loc errLoc) { }; public abstract ArgNodeComparator getComp(CFA cfa, CFA.Loc errLoc); - } public enum PredSplit { @@ -302,8 +509,9 @@ public

CfaPrec

createPrec(final P innerPrec) { } @Override - public PrecRefiner, A, CfaPrec

, R> createRefiner( - final RefutationToPrec refToPrec) { + public + PrecRefiner, A, CfaPrec

, R> createRefiner( + final RefutationToPrec refToPrec) { return GlobalCfaPrecRefiner.create(refToPrec); } @@ -320,8 +528,9 @@ public

CfaPrec

createPrec(final P innerPrec) { } @Override - public PrecRefiner, A, CfaPrec

, R> createRefiner( - final RefutationToPrec refToPrec) { + public + PrecRefiner, A, CfaPrec

, R> createRefiner( + final RefutationToPrec refToPrec) { return LocalCfaPrecRefiner.create(refToPrec); } @@ -333,8 +542,10 @@ public CfaPrec assumePrecs(CFA cfa) { public abstract

CfaPrec

createPrec(P innerPrec); - public abstract PrecRefiner, A, CfaPrec

, R> createRefiner( - RefutationToPrec refToPrec); + public abstract < + S extends ExprState, A extends Action, P extends Prec, R extends Refutation> + PrecRefiner, A, CfaPrec

, R> createRefiner( + RefutationToPrec refToPrec); public abstract CfaPrec assumePrecs(CFA cfa); } @@ -358,19 +569,37 @@ public CfaLts getLts(CFA.Loc errorLoc) { } public enum InitPrec { - EMPTY, ALLVARS, ALLASSUMES + EMPTY, + ALLVARS, + ALLASSUMES } public abstract class BuilderStrategy { - protected static final String UNSUPPORTED_CONFIG_VALUE = "Builder strategy %s does not support configuration value %s as %s"; + protected static final String UNSUPPORTED_CONFIG_VALUE = + "Builder strategy %s does not support configuration value %s as %s"; protected final CFA cfa; @SuppressWarnings("java:S1699") protected BuilderStrategy(CFA cfa) { - checkState(getSupportedDomains().contains(domain), UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), domain, "domain"); - checkState(getSupportedRefinements().contains(refinement), UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), refinement, "refinement"); - checkState(getSupportedInitPrecs().contains(initPrec), UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), initPrec, "initial precision"); + checkState( + getSupportedDomains().contains(domain), + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + domain, + "domain"); + checkState( + getSupportedRefinements().contains(refinement), + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + refinement, + "refinement"); + checkState( + getSupportedInitPrecs().contains(initPrec), + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + initPrec, + "initial precision"); this.cfa = cfa; } @@ -389,7 +618,10 @@ public CfaAnalysis getAnalysis() { public abstract RefutationToPrec getItpRefToPrec(); public RefutationToPrec getVarsRefToPrec() { - throw new UnsupportedOperationException(String.format("Builder strategy %s can not provide Vars refutation to precision", getClass().getSimpleName())); + throw new UnsupportedOperationException( + String.format( + "Builder strategy %s can not provide Vars refutation to precision", + getClass().getSimpleName())); } protected SolverFactory getRefinementSolverFactory() { @@ -421,22 +653,30 @@ public CfaLts getLts() { public CfaConfig, CfaAction, CfaPrec

> buildConfig(CFA.Loc errLoc) { final Predicate> target = new CfaErrorlocPredicate<>(errLoc); final Analysis, CfaAction, CfaPrec

> analysis = getAnalysis(); - final ArgBuilder, CfaAction, CfaPrec

> argBuilder = ArgBuilder.create( - getLts(errLoc), analysis, target, - true); - final Abstractor, CfaAction, CfaPrec

> abstractor = BasicAbstractor.builder( - argBuilder) - .waitlist(PriorityWaitlist.create(search.getComp(cfa, errLoc))) - .stopCriterion(refinement.getStopCriterion()) - .logger(logger).build(); - final Refiner, CfaAction, CfaPrec

> refiner = refinement.getRefiner(this); - final SafetyChecker, CfaAction>, Trace, CfaAction>, CfaPrec

> checker = CegarChecker.create( - abstractor, refiner, - logger); + final ArgBuilder, CfaAction, CfaPrec

> argBuilder = + ArgBuilder.create(getLts(errLoc), analysis, target, true); + final ArgAbstractor, CfaAction, CfaPrec

> abstractor = + BasicArgAbstractor.builder(argBuilder) + .waitlist(PriorityWaitlist.create(search.getComp(cfa, errLoc))) + .stopCriterion(refinement.getStopCriterion()) + .logger(logger) + .build(); + final ArgRefiner, CfaAction, CfaPrec

> refiner = + refinement.getRefiner(this); + final SafetyChecker< + ARG, CfaAction>, Trace, CfaAction>, CfaPrec

> + checker = ArgCegarChecker.create(abstractor, refiner, logger); return CfaConfig.create(checker, createInitPrec()); } - public MultiAnalysisSide, S, CfaState, CfaAction, CfaPrec

, CfaPrec> getMultiSide() { + public MultiAnalysisSide< + CfaState, + S, + CfaState, + CfaAction, + CfaPrec

, + CfaPrec> + getMultiSide() { return new MultiAnalysisSide<>( getAnalysis(), CfaControlInitFuncKt.cfaControlInitFunc(cfa.getInitLoc()), @@ -470,7 +710,8 @@ public Set getSupportedInitPrecs() { @Override public Analysis getDataAnalysis() { - return ExplStmtAnalysis.create(abstractionSolverFactory.createSolver(), True(), maxEnum); + return ExplStmtAnalysis.create( + abstractionSolverFactory.createSolver(), True(), maxEnum); } @Override @@ -489,7 +730,12 @@ public CfaPrec createInitPrec() { case EMPTY -> precGranularity.createPrec(ExplPrec.empty()); case ALLVARS -> precGranularity.createPrec(ExplPrec.of(cfa.getVars())); default -> - throw new UnsupportedOperationException(String.format(UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), initPrec, "initial precision")); + throw new UnsupportedOperationException( + String.format( + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + initPrec, + "initial precision")); }; } } @@ -520,8 +766,7 @@ public Set getSupportedRefinements() { Refinement.NWT_IT_SP, Refinement.NWT_IT_WP, Refinement.NWT_IT_SP_LV, - Refinement.NWT_IT_WP_LV - ); + Refinement.NWT_IT_WP_LV); } @Override @@ -546,9 +791,13 @@ public CfaPrec createInitPrec() { case EMPTY -> precGranularity.createPrec(PredPrec.of()); case ALLASSUMES -> precGranularity.assumePrecs(cfa); default -> - throw new UnsupportedOperationException(String.format(UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), initPrec, "initial precision")); + throw new UnsupportedOperationException( + String.format( + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + initPrec, + "initial precision")); }; } } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java index a7eb473efd..a6cb49bb43 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java @@ -15,31 +15,23 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; -import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.Prec; -import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.algorithm.arg.ARG; +import hu.bme.mit.theta.analysis.algorithm.Witness; /** - * Common interface for the abstractor component. It can create an initial ARG and check an ARG with + * Common interface for the abstractor component. It can create an initial witness and check a witness with * a given precision. */ -public interface Abstractor { +public interface Abstractor

{ /** - * Create initial ARG. - * - * @return + * Create initial witness */ - ARG createArg(); + W createWitness(); /** - * Check ARG with given precision. - * - * @param arg - * @param prec - * @return + * Check witness with given precision */ - AbstractorResult check(ARG arg, P prec); + AbstractorResult check(W witness, P prec); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgAbstractor.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgAbstractor.java new file mode 100644 index 0000000000..67890b8a3a --- /dev/null +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgAbstractor.java @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.analysis.algorithm.cegar; + +import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Prec; +import hu.bme.mit.theta.analysis.State; +import hu.bme.mit.theta.analysis.algorithm.arg.ARG; + +/** + * Common interface for the abstractor component. It can create an initial ARG and check an ARG with + * a given precision. + */ +public interface ArgAbstractor + extends Abstractor> {} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java new file mode 100644 index 0000000000..06260c732c --- /dev/null +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java @@ -0,0 +1,48 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.analysis.algorithm.cegar; + +import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Prec; +import hu.bme.mit.theta.analysis.State; +import hu.bme.mit.theta.analysis.Trace; +import hu.bme.mit.theta.analysis.algorithm.arg.ARG; +import hu.bme.mit.theta.analysis.utils.ArgVisualizer; +import hu.bme.mit.theta.common.logging.Logger; +import hu.bme.mit.theta.common.logging.NullLogger; + +/** + * Counterexample-Guided Abstraction Refinement (CEGAR) loop implementation, + * that uses an Abstractor to explore the abstract state space and a Refiner to + * check counterexamples and refine them if needed. It also provides certain + * statistics about its execution. + */ +public final class ArgCegarChecker { + + private ArgCegarChecker() { + } + + public static CegarChecker, Trace> create( + final ArgAbstractor abstractor, final ArgRefiner refiner) { + return create(abstractor, refiner, NullLogger.getInstance()); + } + + public static CegarChecker, Trace> create( + final ArgAbstractor abstractor, final ArgRefiner refiner, final Logger logger) { + return CegarChecker.create(abstractor, refiner, logger, ArgVisualizer.getDefault()); + } + +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java new file mode 100644 index 0000000000..2683a2fd0f --- /dev/null +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.analysis.algorithm.cegar; + +import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Prec; +import hu.bme.mit.theta.analysis.State; +import hu.bme.mit.theta.analysis.Trace; +import hu.bme.mit.theta.analysis.algorithm.arg.ARG; + +/** + * Common interface for refiners. It takes an ARG and a precision, checks if the counterexample in + * the ARG is feasible and if not, it refines the precision and may also prune the ARG. + */ +public interface ArgRefiner extends Refiner, Trace> { +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicAbstractor.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java similarity index 91% rename from subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicAbstractor.java rename to subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java index 42eb1487e1..050ae32ce3 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicAbstractor.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java @@ -41,7 +41,7 @@ /** * Basic implementation for the abstractor, relying on an ArgBuilder. */ -public class BasicAbstractor implements Abstractor { +public class BasicArgAbstractor implements ArgAbstractor { protected final ArgBuilder argBuilder; protected final Function projection; @@ -49,8 +49,8 @@ public class BasicAbstractor protected final StopCriterion stopCriterion; protected final Logger logger; - protected BasicAbstractor(final ArgBuilder argBuilder, final Function projection, - final Waitlist> waitlist, final StopCriterion stopCriterion, final Logger logger) { + protected BasicArgAbstractor(final ArgBuilder argBuilder, final Function projection, + final Waitlist> waitlist, final StopCriterion stopCriterion, final Logger logger) { this.argBuilder = checkNotNull(argBuilder); this.projection = checkNotNull(projection); this.waitlist = checkNotNull(waitlist); @@ -64,7 +64,7 @@ public static Builder createArg() { + public ARG createWitness() { return argBuilder.createArg(); } @@ -174,8 +174,8 @@ public Builder logger(final Logger logger) { return this; } - public BasicAbstractor build() { - return new BasicAbstractor<>(argBuilder, projection, waitlist, stopCriterion, logger); + public BasicArgAbstractor build() { + return new BasicArgAbstractor<>(argBuilder, projection, waitlist, stopCriterion, logger); } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java index af69cd7121..fa811afc42 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java @@ -17,19 +17,18 @@ import com.google.common.base.Stopwatch; import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.Trace; -import hu.bme.mit.theta.analysis.algorithm.SafetyResult; -import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; +import hu.bme.mit.theta.analysis.algorithm.SafetyResult; +import hu.bme.mit.theta.analysis.algorithm.Witness; import hu.bme.mit.theta.analysis.runtimemonitor.MonitorCheckpoint; -import hu.bme.mit.theta.analysis.utils.ArgVisualizer; +import hu.bme.mit.theta.analysis.utils.WitnessVisualizer; import hu.bme.mit.theta.common.Utils; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.common.logging.NullLogger; - import hu.bme.mit.theta.common.visualization.writer.JSONWriter; import hu.bme.mit.theta.common.visualization.writer.WebDebuggerLogger; @@ -43,42 +42,44 @@ * check counterexamples and refine them if needed. It also provides certain * statistics about its execution. */ -public final class CegarChecker implements SafetyChecker, Trace, P> { +public final class CegarChecker implements SafetyChecker { - private final Abstractor abstractor; - private final Refiner refiner; + private final Abstractor abstractor; + private final Refiner refiner; private final Logger logger; - private final ARG arg; // TODO I don't think putting the ARG up here from check below causes any issues, but keep it in mind, that it might + private final W witness; + private final WitnessVisualizer witnessVisualizer; - private CegarChecker(final Abstractor abstractor, final Refiner refiner, final Logger logger) { + private CegarChecker(final Abstractor abstractor, final Refiner refiner, final Logger logger, final WitnessVisualizer witnessVisualizer) { this.abstractor = checkNotNull(abstractor); this.refiner = checkNotNull(refiner); this.logger = checkNotNull(logger); - arg = abstractor.createArg(); + witness = abstractor.createWitness(); + this.witnessVisualizer = checkNotNull(witnessVisualizer); } - public static CegarChecker create( - final Abstractor abstractor, final Refiner refiner) { - return new CegarChecker<>(abstractor, refiner, NullLogger.getInstance()); + public static CegarChecker create( + final Abstractor abstractor, final Refiner refiner, final WitnessVisualizer witnessVisualizer) { + return create(abstractor, refiner, NullLogger.getInstance(), witnessVisualizer); } - public static CegarChecker create( - final Abstractor abstractor, final Refiner refiner, final Logger logger) { - return new CegarChecker<>(abstractor, refiner, logger); + public static CegarChecker create( + final Abstractor abstractor, final Refiner refiner, final Logger logger, final WitnessVisualizer witnessVisualizer) { + return new CegarChecker<>(abstractor, refiner, logger, witnessVisualizer); } - public ARG getArg() { - return arg; + public W getWitness() { + return witness; } @Override - public SafetyResult, Trace> check(final P initPrec) { + public SafetyResult check(final P initPrec) { logger.write(Level.INFO, "Configuration: %s%n", this); final Stopwatch stopwatch = Stopwatch.createStarted(); long abstractorTime = 0; long refinerTime = 0; - RefinerResult refinerResult = null; - AbstractorResult abstractorResult = null; + RefinerResult refinerResult = null; + AbstractorResult abstractorResult; P prec = initPrec; int iteration = 0; WebDebuggerLogger wdl = WebDebuggerLogger.getInstance(); @@ -88,12 +89,12 @@ public SafetyResult, Trace> check(final P initPrec) { logger.write(Level.MAINSTEP, "Iteration %d%n", iteration); logger.write(Level.MAINSTEP, "| Checking abstraction...%n"); final long abstractorStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); - abstractorResult = abstractor.check(arg, prec); + abstractorResult = abstractor.check(witness, prec); abstractorTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - abstractorStartTime; logger.write(Level.MAINSTEP, "| Checking abstraction done, result: %s%n", abstractorResult); if (WebDebuggerLogger.enabled()) { - String argGraph = JSONWriter.getInstance().writeString(ArgVisualizer.getDefault().visualize(arg)); + String argGraph = JSONWriter.getInstance().writeString(witnessVisualizer.visualize(witness)); String precString = prec.toString(); wdl.addIteration(iteration, argGraph, precString); } @@ -104,7 +105,7 @@ public SafetyResult, Trace> check(final P initPrec) { P lastPrec = prec; logger.write(Level.MAINSTEP, "| Refining abstraction...%n"); final long refinerStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); - refinerResult = refiner.refine(arg, prec); + refinerResult = refiner.refine(witness, prec); refinerTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - refinerStartTime; logger.write(Level.MAINSTEP, "Refining abstraction done, result: %s%n", refinerResult); @@ -123,16 +124,16 @@ public SafetyResult, Trace> check(final P initPrec) { } while (!abstractorResult.isSafe() && !refinerResult.isUnsafe()); stopwatch.stop(); - SafetyResult, Trace> cegarResult = null; + SafetyResult cegarResult = null; final CegarStatistics stats = new CegarStatistics(stopwatch.elapsed(TimeUnit.MILLISECONDS), abstractorTime, refinerTime, iteration); - assert abstractorResult.isSafe() || (refinerResult != null && refinerResult.isUnsafe()); + assert abstractorResult.isSafe() || refinerResult.isUnsafe(); if (abstractorResult.isSafe()) { - cegarResult = SafetyResult.safe(arg, stats); + cegarResult = SafetyResult.safe(witness, stats); } else if (refinerResult.isUnsafe()) { - cegarResult = SafetyResult.unsafe(refinerResult.asUnsafe().getCex(), arg, stats); + cegarResult = SafetyResult.unsafe(refinerResult.asUnsafe().getCex(), witness, stats); } assert cegarResult != null; diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java index 0bbfe07f1d..6eca5d7c21 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java @@ -16,23 +16,19 @@ package hu.bme.mit.theta.analysis.algorithm.cegar; import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.algorithm.arg.ARG; +import hu.bme.mit.theta.analysis.algorithm.Witness; /** - * Common interface for refiners. It takes an ARG and a precision, checks if the counterexample in - * the ARG is feasible and if not, it refines the precision and may also prune the ARG. + * Common interface for refiners. It takes a witness and a precision, checks if the counterexample in + * the witness is feasible and if not, it refines the precision */ -public interface Refiner { +public interface Refiner { /** - * Checks if the counterexample in the ARG is feasible. If not, refines the precision and prunes - * the ARG. - * - * @param arg - * @param prec - * @return + * Checks if the counterexample in the witness is feasible. If not, refines the precision */ - RefinerResult refine(ARG arg, P prec); + RefinerResult refine(W witness, P prec); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java index bbce8b5451..a4be30781e 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java @@ -15,30 +15,29 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; -import static com.google.common.base.Preconditions.checkNotNull; - import hu.bme.mit.theta.analysis.Action; +import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.common.Utils; +import static com.google.common.base.Preconditions.checkNotNull; + /** * Represents the result of the Refiner class that can be either spurious or unsafe. In the former * case it also contains the refined precision and in the latter case the feasible counterexample. */ -public abstract class RefinerResult { +public abstract class RefinerResult { - private RefinerResult() { + protected RefinerResult() { } /** * Create a new spurious result. * * @param refinedPrec Refined precision - * @return */ - public static Spurious spurious( + public static Spurious spurious( final P refinedPrec) { return new Spurious<>(refinedPrec); } @@ -47,10 +46,9 @@ public static Spurious Unsafe unsafe( - final Trace cex) { + public static Unsafe unsafe( + final C cex) { return new Unsafe<>(cex); } @@ -58,15 +56,15 @@ public static Unsafe asSpurious(); + public abstract Spurious asSpurious(); - public abstract Unsafe asUnsafe(); + public abstract Unsafe asUnsafe(); /** * Represents the spurious result with a refined precision. */ - public static final class Spurious - extends RefinerResult { + public static final class Spurious + extends RefinerResult { private final P refinedPrec; @@ -89,12 +87,12 @@ public boolean isUnsafe() { } @Override - public Spurious asSpurious() { + public Spurious asSpurious() { return this; } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { throw new ClassCastException( "Cannot cast " + Spurious.class.getSimpleName() + " to " + Unsafe.class.getSimpleName()); @@ -111,16 +109,16 @@ public String toString() { /** * Represents the unsafe result with a feasible counterexample. */ - public static final class Unsafe extends - RefinerResult { + public static final class Unsafe extends + RefinerResult { - private final Trace cex; + private final C cex; - private Unsafe(final Trace cex) { + private Unsafe(final C cex) { this.cex = checkNotNull(cex); } - public Trace getCex() { + public C getCex() { return cex; } @@ -135,14 +133,14 @@ public boolean isUnsafe() { } @Override - public Spurious asSpurious() { + public Spurious asSpurious() { throw new ClassCastException( "Cannot cast " + Unsafe.class.getSimpleName() + " to " + Spurious.class.getSimpleName()); } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { return this; } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java index 8f2f499547..f1f7430241 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java @@ -16,9 +16,10 @@ package hu.bme.mit.theta.analysis.expr.refinement; import hu.bme.mit.theta.analysis.Prec; +import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; import hu.bme.mit.theta.analysis.algorithm.cegar.RefinerResult; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; @@ -29,15 +30,15 @@ import java.util.Set; import java.util.stream.Collectors; -public final class AasporRefiner implements Refiner { +public final class AasporRefiner implements ArgRefiner { - private final Refiner refiner; + private final ArgRefiner refiner; private final PruneStrategy pruneStrategy; private final Map, Set> ignoredVarRegistry; - private AasporRefiner(final Refiner refiner, + private AasporRefiner(final ArgRefiner refiner, final PruneStrategy pruneStrategy, final Map, Set> ignoredVarRegistry) { this.refiner = refiner; @@ -46,14 +47,14 @@ private AasporRefiner(final Refiner refiner, } public static AasporRefiner create( - final Refiner refiner, final PruneStrategy pruneStrategy, + final ArgRefiner refiner, final PruneStrategy pruneStrategy, final Map, Set> ignoredVarRegistry) { return new AasporRefiner<>(refiner, pruneStrategy, ignoredVarRegistry); } @Override - public RefinerResult refine(final ARG arg, final P prec) { - final RefinerResult result = refiner.refine(arg, prec); + public RefinerResult> refine(final ARG arg, final P prec) { + final RefinerResult> result = refiner.refine(arg, prec); if (result.isUnsafe() || pruneStrategy != PruneStrategy.LAZY) return result; final P newPrec = result.asSpurious().getRefinedPrec(); diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java index 72c516adef..b2cee796d0 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java @@ -20,7 +20,7 @@ import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode; import hu.bme.mit.theta.analysis.algorithm.arg.ArgTrace; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; import hu.bme.mit.theta.analysis.algorithm.cegar.RefinerResult; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; @@ -34,7 +34,7 @@ import static com.google.common.base.Preconditions.checkNotNull; public final class MultiExprTraceRefiner - implements Refiner { + implements ArgRefiner { private final ExprTraceChecker exprTraceChecker; private final PrecRefiner precRefiner; @@ -76,17 +76,17 @@ public static refine(final ARG arg, final P prec) { + public RefinerResult> refine(final ARG arg, final P prec) { checkNotNull(arg); checkNotNull(prec); assert !arg.isSafe() : "ARG must be unsafe"; - final List> cexs = arg.getCexs().collect(Collectors.toList()); - final List> traces = arg.getCexs().map(ArgTrace::toTrace).collect(Collectors.toList()); + final List> cexs = arg.getCexs().toList(); + final List> traces = arg.getCexs().map(ArgTrace::toTrace).toList(); assert traces.size() == cexs.size(); logger.write(Level.INFO, "| | Number of traces: %d%n", traces.size()); - assert traces.size() > 0 : "No counterexample in ARG"; + assert !traces.isEmpty() : "No counterexample in ARG"; logger.write(Level.SUBSTEP, "| | Checking traces..."); final List> cexStatuses = new ArrayList<>(traces.size()); @@ -106,7 +106,7 @@ public RefinerResult refine(final ARG arg, final P prec) { assert cexStatuses.size() == cexs.size(); logger.write(Level.SUBSTEP, "done, result: all infeasible%n"); final List refutations = cexStatuses.stream().map(s -> s.asInfeasible().getRefutation()) - .collect(Collectors.toList()); + .toList(); assert refutations.size() == cexs.size(); final List> nodesToPrune = new ArrayList<>(traces.size()); @@ -120,7 +120,7 @@ public RefinerResult refine(final ARG arg, final P prec) { for (int i = 0; i < nodesToPrune.size(); ++i) { final ArgNode node = nodesToPrune.get(i); - if (node.properAncestors().anyMatch(a -> nodesToPrune.contains(a))) { + if (node.properAncestors().anyMatch(nodesToPrune::contains)) { skip.set(i, true); } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java index ac06cf2a87..126f4212f4 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java @@ -20,7 +20,7 @@ import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode; import hu.bme.mit.theta.analysis.algorithm.arg.ArgTrace; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; import hu.bme.mit.theta.analysis.algorithm.cegar.RefinerResult; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; @@ -37,7 +37,7 @@ * ExprActions) using an ExprTraceChecker and a PrecRefiner. */ public class SingleExprTraceRefiner - implements Refiner { + implements ArgRefiner { protected final ExprTraceChecker exprTraceChecker; protected final PrecRefiner precRefiner; protected final PruneStrategy pruneStrategy; @@ -78,7 +78,7 @@ public static refine(final ARG arg, final P prec) { + public RefinerResult> refine(final ARG arg, final P prec) { checkNotNull(arg); checkNotNull(prec); assert !arg.isSafe() : "ARG must be unsafe"; diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java index 9992e5a3e7..c4c82eeb74 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java @@ -36,7 +36,7 @@ import hu.bme.mit.theta.common.visualization.LineStyle; import hu.bme.mit.theta.common.visualization.NodeAttributes; -public final class ArgVisualizer { +public final class ArgVisualizer implements WitnessVisualizer> { private static final LineStyle COVER_EDGE_STYLE = LineStyle.DASHED; private static final LineStyle SUCC_EDGE_STYLE = LineStyle.NORMAL; @@ -53,8 +53,8 @@ public final class ArgVisualizer { private static class LazyHolderDefault { - static final ArgVisualizer INSTANCE = new ArgVisualizer<>(s -> s.toString(), - a -> a.toString()); + static final ArgVisualizer INSTANCE = new ArgVisualizer<>(Object::toString, + Object::toString); } private static class LazyHolderStructureOnly { @@ -81,6 +81,7 @@ public static ArgVisualizer getStructureOnly() { return LazyHolderStructureOnly.INSTANCE; } + @Override public Graph visualize(final ARG arg) { final Graph graph = new Graph(ARG_ID, ARG_LABEL); diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java new file mode 100644 index 0000000000..bd1a9d8234 --- /dev/null +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java @@ -0,0 +1,26 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package hu.bme.mit.theta.analysis.utils; + +import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.common.visualization.Graph; + +public interface WitnessVisualizer { + + Graph visualize(W witness); + +} diff --git a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/config/StmtMultiConfigBuilder.kt b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/config/StmtMultiConfigBuilder.kt index 2e7f57a91a..e0d8173455 100644 --- a/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/config/StmtMultiConfigBuilder.kt +++ b/subprojects/common/analysis/src/main/kotlin/hu/bme/mit/theta/analysis/multi/config/StmtMultiConfigBuilder.kt @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.analysis.multi.config import hu.bme.mit.theta.analysis.Prec import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor import hu.bme.mit.theta.analysis.expr.ExprState import hu.bme.mit.theta.analysis.expr.StmtAction import hu.bme.mit.theta.analysis.expr.refinement.* @@ -39,117 +38,264 @@ import hu.bme.mit.theta.solver.SolverFactory import hu.bme.mit.theta.solver.UCSolver import java.util.function.Predicate -sealed class StmtMultiConfigBuilder( - private val product: MultiBuilderResultPOJO, ExprMultiState, StmtMultiAction, StmtMultiLts>, - val prop: Expr, - val target: Predicate>, - private val lRefToPrec: RefutationToPrec, - private val rRefToPrec: RefutationToPrec, - private val dRefToPrec: RefutationToPrec, - private val lInitPrec: LPrec, - private val rInitPrec: RPrec, - private val dInitPrec: DataPrec, - val solverFactory: SolverFactory, - val logger: Logger, - val pruneStrategy: PruneStrategy = PruneStrategy.FULL +sealed class StmtMultiConfigBuilder< + LState : ExprState, + RState : ExprState, + DataState : ExprState, + LControl : ExprState, + RControl : ExprState, + LAction : StmtAction, + RAction : StmtAction, + R : Refutation, + LPrec : Prec, + RPrec : Prec, + DataPrec : Prec, + LControlPrec : Prec, + RControlPrec : Prec, +>( + private val product: + MultiBuilderResultPOJO< + LState, + RState, + DataState, + LControl, + RControl, + LAction, + RAction, + LPrec, + RPrec, + DataPrec, + LControlPrec, + RControlPrec, + ExprMultiState, + ExprMultiState, + StmtMultiAction, + StmtMultiLts, + >, + val prop: Expr, + val target: Predicate>, + private val lRefToPrec: RefutationToPrec, + private val rRefToPrec: RefutationToPrec, + private val dRefToPrec: RefutationToPrec, + private val lInitPrec: LPrec, + private val rInitPrec: RPrec, + private val dInitPrec: DataPrec, + val solverFactory: SolverFactory, + val logger: Logger, + val pruneStrategy: PruneStrategy = PruneStrategy.FULL, ) { - abstract fun getTraceChecker(): ExprTraceChecker + abstract fun getTraceChecker(): ExprTraceChecker - fun build(): MultiConfig, StmtMultiAction> { - val argBuilder = ArgBuilder.create(product.lts, product.side.analysis, target) - val abstractor = BasicAbstractor.builder(argBuilder).build() - val traceChecker = getTraceChecker() - val precRefiner = - JoiningPrecRefiner.create, StmtMultiAction, MultiPrec, R>( - RefToMultiPrec(lRefToPrec, rRefToPrec, dRefToPrec) - ) - val refiner = SingleExprTraceRefiner.create(traceChecker, precRefiner, pruneStrategy, logger) - return MultiConfig(CegarChecker.create(abstractor, refiner), MultiPrec(lInitPrec, rInitPrec, dInitPrec)) - } + fun build(): + MultiConfig< + DataState, + LControl, + RControl, + LAction, + RAction, + LPrec, + RPrec, + DataPrec, + ExprMultiState, + StmtMultiAction, + > { + val argBuilder = ArgBuilder.create(product.lts, product.side.analysis, target) + val abstractor = BasicArgAbstractor.builder(argBuilder).build() + val traceChecker = getTraceChecker() + val precRefiner = + JoiningPrecRefiner.create< + ExprMultiState, + StmtMultiAction, + MultiPrec, + R, + >( + RefToMultiPrec(lRefToPrec, rRefToPrec, dRefToPrec) + ) + val refiner = SingleExprTraceRefiner.create(traceChecker, precRefiner, pruneStrategy, logger) + return MultiConfig( + ArgCegarChecker.create(abstractor, refiner), + MultiPrec(lInitPrec, rInitPrec, dInitPrec), + ) + } - class ItpStmtMultiConfigBuilder( - product: MultiBuilderResultPOJO, ExprMultiState, StmtMultiAction, StmtMultiLts>, - prop: Expr, - target: Predicate>, - lRefToPrec: RefutationToPrec, - rRefToPrec: RefutationToPrec, - dRefToPrec: RefutationToPrec, - lInitPrec: LPrec, - rInitPrec: RPrec, - dInitPrec: DataPrec, - solverFactory: SolverFactory, - logger: Logger, - pruneStrategy: PruneStrategy = PruneStrategy.FULL, - private val traceCheckerType: TraceCheckerType = TraceCheckerType.SEQ_ITP - ) : StmtMultiConfigBuilder( - product, - prop, - target, - lRefToPrec, - rRefToPrec, - dRefToPrec, - lInitPrec, - rInitPrec, - dInitPrec, - solverFactory, - logger, - pruneStrategy + class ItpStmtMultiConfigBuilder< + LState : ExprState, + RState : ExprState, + DataState : ExprState, + LControl : ExprState, + RControl : ExprState, + LAction : StmtAction, + RAction : StmtAction, + LPrec : Prec, + RPrec : Prec, + DataPrec : Prec, + LControlPrec : Prec, + RControlPrec : Prec, + >( + product: + MultiBuilderResultPOJO< + LState, + RState, + DataState, + LControl, + RControl, + LAction, + RAction, + LPrec, + RPrec, + DataPrec, + LControlPrec, + RControlPrec, + ExprMultiState, + ExprMultiState, + StmtMultiAction, + StmtMultiLts, + >, + prop: Expr, + target: Predicate>, + lRefToPrec: RefutationToPrec, + rRefToPrec: RefutationToPrec, + dRefToPrec: RefutationToPrec, + lInitPrec: LPrec, + rInitPrec: RPrec, + dInitPrec: DataPrec, + solverFactory: SolverFactory, + logger: Logger, + pruneStrategy: PruneStrategy = PruneStrategy.FULL, + private val traceCheckerType: TraceCheckerType = TraceCheckerType.SEQ_ITP, + ) : + StmtMultiConfigBuilder< + LState, + RState, + DataState, + LControl, + RControl, + LAction, + RAction, + ItpRefutation, + LPrec, + RPrec, + DataPrec, + LControlPrec, + RControlPrec, + >( + product, + prop, + target, + lRefToPrec, + rRefToPrec, + dRefToPrec, + lInitPrec, + rInitPrec, + dInitPrec, + solverFactory, + logger, + pruneStrategy, ) { - enum class TraceCheckerType( - val generator: (init: Expr, target: Expr, solver: ItpSolver) -> ExprTraceChecker - ) { - - SEQ_ITP(ExprTraceSeqItpChecker::create), FW_BIN(ExprTraceFwBinItpChecker::create), BW_BIN( - ExprTraceBwBinItpChecker::create - ) - } + enum class TraceCheckerType( + val generator: + (init: Expr, target: Expr, solver: ItpSolver) -> ExprTraceChecker< + ItpRefutation + > + ) { - override fun getTraceChecker(): ExprTraceChecker = traceCheckerType.generator( - BoolExprs.True(), prop, solverFactory.createItpSolver() - ) + SEQ_ITP(ExprTraceSeqItpChecker::create), + FW_BIN(ExprTraceFwBinItpChecker::create), + BW_BIN(ExprTraceBwBinItpChecker::create), } - class VarsStmtMultiConfigBuilder( - product: MultiBuilderResultPOJO, ExprMultiState, StmtMultiAction, StmtMultiLts>, - prop: Expr, - target: Predicate>, - lRefToPrec: RefutationToPrec, - rRefToPrec: RefutationToPrec, - dRefToPrec: RefutationToPrec, - lInitPrec: LPrec, - rInitPrec: RPrec, - dInitPrec: DataPrec, - solverFactory: SolverFactory, - logger: Logger, - pruneStrategy: PruneStrategy = PruneStrategy.FULL, - private val traceCheckerType: TraceCheckerType = TraceCheckerType.UNSAT_CORE - ) : StmtMultiConfigBuilder( - product, - prop, - target, - lRefToPrec, - rRefToPrec, - dRefToPrec, - lInitPrec, - rInitPrec, - dInitPrec, - solverFactory, - logger, - pruneStrategy - ) { + override fun getTraceChecker(): ExprTraceChecker = + traceCheckerType.generator(BoolExprs.True(), prop, solverFactory.createItpSolver()) + } - enum class TraceCheckerType( - val generator: (init: Expr, target: Expr, solver: UCSolver) -> ExprTraceChecker - ) { + class VarsStmtMultiConfigBuilder< + LState : ExprState, + RState : ExprState, + DataState : ExprState, + LControl : ExprState, + RControl : ExprState, + LAction : StmtAction, + RAction : StmtAction, + LPrec : Prec, + RPrec : Prec, + DataPrec : Prec, + LControlPrec : Prec, + RControlPrec : Prec, + >( + product: + MultiBuilderResultPOJO< + LState, + RState, + DataState, + LControl, + RControl, + LAction, + RAction, + LPrec, + RPrec, + DataPrec, + LControlPrec, + RControlPrec, + ExprMultiState, + ExprMultiState, + StmtMultiAction, + StmtMultiLts, + >, + prop: Expr, + target: Predicate>, + lRefToPrec: RefutationToPrec, + rRefToPrec: RefutationToPrec, + dRefToPrec: RefutationToPrec, + lInitPrec: LPrec, + rInitPrec: RPrec, + dInitPrec: DataPrec, + solverFactory: SolverFactory, + logger: Logger, + pruneStrategy: PruneStrategy = PruneStrategy.FULL, + private val traceCheckerType: TraceCheckerType = TraceCheckerType.UNSAT_CORE, + ) : + StmtMultiConfigBuilder< + LState, + RState, + DataState, + LControl, + RControl, + LAction, + RAction, + VarsRefutation, + LPrec, + RPrec, + DataPrec, + LControlPrec, + RControlPrec, + >( + product, + prop, + target, + lRefToPrec, + rRefToPrec, + dRefToPrec, + lInitPrec, + rInitPrec, + dInitPrec, + solverFactory, + logger, + pruneStrategy, + ) { - UNSAT_CORE(ExprTraceUnsatCoreChecker::create) - } + enum class TraceCheckerType( + val generator: + (init: Expr, target: Expr, solver: UCSolver) -> ExprTraceChecker< + VarsRefutation + > + ) { - override fun getTraceChecker(): ExprTraceChecker = traceCheckerType.generator( - BoolExprs.True(), prop, solverFactory.createUCSolver() - ) + UNSAT_CORE(ExprTraceUnsatCoreChecker::create) } + override fun getTraceChecker(): ExprTraceChecker = + traceCheckerType.generator(BoolExprs.True(), prop, solverFactory.createUCSolver()) + } } diff --git a/subprojects/sts/sts-analysis/src/main/java/hu/bme/mit/theta/sts/analysis/config/StsConfigBuilder.java b/subprojects/sts/sts-analysis/src/main/java/hu/bme/mit/theta/sts/analysis/config/StsConfigBuilder.java index 397a4a4ef8..7e946253e9 100644 --- a/subprojects/sts/sts-analysis/src/main/java/hu/bme/mit/theta/sts/analysis/config/StsConfigBuilder.java +++ b/subprojects/sts/sts-analysis/src/main/java/hu/bme/mit/theta/sts/analysis/config/StsConfigBuilder.java @@ -15,16 +15,18 @@ */ package hu.bme.mit.theta.sts.analysis.config; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; + import hu.bme.mit.theta.analysis.*; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators.ArgNodeComparator; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions; import hu.bme.mit.theta.analysis.expl.ExplAnalysis; import hu.bme.mit.theta.analysis.expl.ExplPrec; @@ -66,19 +68,23 @@ import hu.bme.mit.theta.sts.analysis.initprec.StsEmptyInitPrec; import hu.bme.mit.theta.sts.analysis.initprec.StsInitPrec; import hu.bme.mit.theta.sts.analysis.initprec.StsPropInitPrec; - import java.util.function.Predicate; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; - public final class StsConfigBuilder { public enum Domain { - EXPL, PRED_BOOL, PRED_CART, PRED_SPLIT + EXPL, + PRED_BOOL, + PRED_CART, + PRED_SPLIT } public enum Refinement { - FW_BIN_ITP, BW_BIN_ITP, SEQ_ITP, MULTI_SEQ, UNSAT_CORE + FW_BIN_ITP, + BW_BIN_ITP, + SEQ_ITP, + MULTI_SEQ, + UNSAT_CORE } public enum Search { @@ -91,7 +97,6 @@ public enum Search { private Search(final ArgNodeComparator comparator) { this.comparator = comparator; } - } public enum PredSplit { @@ -109,14 +114,14 @@ private PredSplit(final ExprSplitter splitter) { } public enum InitPrec { - EMPTY(new StsEmptyInitPrec()), PROP(new StsPropInitPrec()); + EMPTY(new StsEmptyInitPrec()), + PROP(new StsPropInitPrec()); public final StsInitPrec builder; private InitPrec(final StsInitPrec builder) { this.builder = builder; } - } private Logger logger = NullLogger.getInstance(); @@ -128,8 +133,8 @@ private InitPrec(final StsInitPrec builder) { private InitPrec initPrec = InitPrec.EMPTY; private PruneStrategy pruneStrategy = PruneStrategy.LAZY; - public StsConfigBuilder(final Domain domain, final Refinement refinement, - final SolverFactory solverFactory) { + public StsConfigBuilder( + final Domain domain, final Refinement refinement, final SolverFactory solverFactory) { this.domain = domain; this.refinement = refinement; this.solverFactory = solverFactory; @@ -168,63 +173,80 @@ public StsConfigBuilder pruneStrategy(final PruneStrategy pruneStrategy) { if (domain == Domain.EXPL) { final Solver analysisSolver = solverFactory.createSolver(); final Predicate target = new ExplStatePredicate(negProp, analysisSolver); - final Analysis analysis = ExplAnalysis.create( - analysisSolver, init); - final ArgBuilder argBuilder = ArgBuilder.create(lts, - analysis, target, - true); - final Abstractor abstractor = BasicAbstractor.builder( - argBuilder) - .waitlist(PriorityWaitlist.create(search.comparator)) - .stopCriterion(refinement == Refinement.MULTI_SEQ ? StopCriterions.fullExploration() - : StopCriterions.firstCex()) - .logger(logger).build(); - - Refiner refiner = null; + final Analysis analysis = + ExplAnalysis.create(analysisSolver, init); + final ArgBuilder argBuilder = + ArgBuilder.create(lts, analysis, target, true); + final ArgAbstractor abstractor = + BasicArgAbstractor.builder(argBuilder) + .waitlist(PriorityWaitlist.create(search.comparator)) + .stopCriterion( + refinement == Refinement.MULTI_SEQ + ? StopCriterions.fullExploration() + : StopCriterions.firstCex()) + .logger(logger) + .build(); + + ArgRefiner refiner = null; switch (refinement) { case FW_BIN_ITP: - refiner = SingleExprTraceRefiner.create( - ExprTraceFwBinItpChecker.create(init, negProp, - solverFactory.createItpSolver()), - JoiningPrecRefiner.create(new ItpRefToExplPrec()), pruneStrategy, logger); + refiner = + SingleExprTraceRefiner.create( + ExprTraceFwBinItpChecker.create( + init, negProp, solverFactory.createItpSolver()), + JoiningPrecRefiner.create(new ItpRefToExplPrec()), + pruneStrategy, + logger); break; case BW_BIN_ITP: - refiner = SingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(init, negProp, - solverFactory.createItpSolver()), - JoiningPrecRefiner.create(new ItpRefToExplPrec()), pruneStrategy, logger); + refiner = + SingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + init, negProp, solverFactory.createItpSolver()), + JoiningPrecRefiner.create(new ItpRefToExplPrec()), + pruneStrategy, + logger); break; case SEQ_ITP: - refiner = SingleExprTraceRefiner.create( - ExprTraceSeqItpChecker.create(init, negProp, - solverFactory.createItpSolver()), - JoiningPrecRefiner.create(new ItpRefToExplPrec()), pruneStrategy, logger); + refiner = + SingleExprTraceRefiner.create( + ExprTraceSeqItpChecker.create( + init, negProp, solverFactory.createItpSolver()), + JoiningPrecRefiner.create(new ItpRefToExplPrec()), + pruneStrategy, + logger); break; case MULTI_SEQ: - refiner = MultiExprTraceRefiner.create( - ExprTraceSeqItpChecker.create(init, negProp, - solverFactory.createItpSolver()), - JoiningPrecRefiner.create(new ItpRefToExplPrec()), pruneStrategy, logger); + refiner = + MultiExprTraceRefiner.create( + ExprTraceSeqItpChecker.create( + init, negProp, solverFactory.createItpSolver()), + JoiningPrecRefiner.create(new ItpRefToExplPrec()), + pruneStrategy, + logger); break; case UNSAT_CORE: - refiner = SingleExprTraceRefiner.create( - ExprTraceUnsatCoreChecker.create(init, negProp, - solverFactory.createUCSolver()), - JoiningPrecRefiner.create(new VarsRefToExplPrec()), pruneStrategy, logger); + refiner = + SingleExprTraceRefiner.create( + ExprTraceUnsatCoreChecker.create( + init, negProp, solverFactory.createUCSolver()), + JoiningPrecRefiner.create(new VarsRefToExplPrec()), + pruneStrategy, + logger); break; default: throw new UnsupportedOperationException( domain + " domain does not support " + refinement + " refinement."); } - final SafetyChecker, Trace, ExplPrec> checker = CegarChecker.create( - abstractor, refiner, - logger); + final SafetyChecker, Trace, ExplPrec> + checker = ArgCegarChecker.create(abstractor, refiner, logger); final ExplPrec prec = initPrec.builder.createExpl(sts); return StsConfig.create(checker, prec); - } else if (domain == Domain.PRED_BOOL || domain == Domain.PRED_CART + } else if (domain == Domain.PRED_BOOL + || domain == Domain.PRED_CART || domain == Domain.PRED_SPLIT) { final Solver analysisSolver = solverFactory.createSolver(); PredAbstractor predAbstractor = null; @@ -242,55 +264,65 @@ public StsConfigBuilder pruneStrategy(final PruneStrategy pruneStrategy) { throw new UnsupportedOperationException(domain + " domain is not supported."); } final Predicate target = new ExprStatePredicate(negProp, analysisSolver); - final Analysis analysis = PredAnalysis.create( - analysisSolver, predAbstractor, - init); - final ArgBuilder argBuilder = ArgBuilder.create(lts, - analysis, target, - true); - final Abstractor abstractor = BasicAbstractor.builder( - argBuilder) - .waitlist(PriorityWaitlist.create(search.comparator)) - .stopCriterion(refinement == Refinement.MULTI_SEQ ? StopCriterions.fullExploration() - : StopCriterions.firstCex()) - .logger(logger).build(); + final Analysis analysis = + PredAnalysis.create(analysisSolver, predAbstractor, init); + final ArgBuilder argBuilder = + ArgBuilder.create(lts, analysis, target, true); + final ArgAbstractor abstractor = + BasicArgAbstractor.builder(argBuilder) + .waitlist(PriorityWaitlist.create(search.comparator)) + .stopCriterion( + refinement == Refinement.MULTI_SEQ + ? StopCriterions.fullExploration() + : StopCriterions.firstCex()) + .logger(logger) + .build(); ExprTraceChecker exprTraceChecker = null; switch (refinement) { case FW_BIN_ITP: - exprTraceChecker = ExprTraceFwBinItpChecker.create(init, negProp, - solverFactory.createItpSolver()); + exprTraceChecker = + ExprTraceFwBinItpChecker.create( + init, negProp, solverFactory.createItpSolver()); break; case BW_BIN_ITP: - exprTraceChecker = ExprTraceBwBinItpChecker.create(init, negProp, - solverFactory.createItpSolver()); + exprTraceChecker = + ExprTraceBwBinItpChecker.create( + init, negProp, solverFactory.createItpSolver()); break; case SEQ_ITP: - exprTraceChecker = ExprTraceSeqItpChecker.create(init, negProp, - solverFactory.createItpSolver()); + exprTraceChecker = + ExprTraceSeqItpChecker.create( + init, negProp, solverFactory.createItpSolver()); break; case MULTI_SEQ: - exprTraceChecker = ExprTraceSeqItpChecker.create(init, negProp, - solverFactory.createItpSolver()); + exprTraceChecker = + ExprTraceSeqItpChecker.create( + init, negProp, solverFactory.createItpSolver()); break; default: throw new UnsupportedOperationException( domain + " domain does not support " + refinement + " refinement."); } - Refiner refiner; + ArgRefiner refiner; if (refinement == Refinement.MULTI_SEQ) { - refiner = MultiExprTraceRefiner.create(exprTraceChecker, - JoiningPrecRefiner.create(new ItpRefToPredPrec(predSplit.splitter)), - pruneStrategy, logger); + refiner = + MultiExprTraceRefiner.create( + exprTraceChecker, + JoiningPrecRefiner.create(new ItpRefToPredPrec(predSplit.splitter)), + pruneStrategy, + logger); } else { - refiner = SingleExprTraceRefiner.create(exprTraceChecker, - JoiningPrecRefiner.create(new ItpRefToPredPrec(predSplit.splitter)), - pruneStrategy, logger); + refiner = + SingleExprTraceRefiner.create( + exprTraceChecker, + JoiningPrecRefiner.create(new ItpRefToPredPrec(predSplit.splitter)), + pruneStrategy, + logger); } - final SafetyChecker, Trace, PredPrec> checker = CegarChecker.create( - abstractor, refiner, - logger); + final SafetyChecker, Trace, PredPrec> + checker = ArgCegarChecker.create(abstractor, refiner, logger); final PredPrec prec = initPrec.builder.createPred(sts); return StsConfig.create(checker, prec); diff --git a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java index db171f2718..4f2f998af5 100644 --- a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java +++ b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java @@ -24,9 +24,9 @@ import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; import hu.bme.mit.theta.analysis.expl.ExplAnalysis; import hu.bme.mit.theta.analysis.expl.ExplPrec; import hu.bme.mit.theta.analysis.expl.ExplState; @@ -110,7 +110,7 @@ public void test() { final ArgBuilder argBuilder = ArgBuilder.create(lts, analysis, target); - final Abstractor abstractor = BasicAbstractor.builder( + final ArgAbstractor abstractor = BasicArgAbstractor.builder( argBuilder) .waitlist(PriorityWaitlist.create(ArgNodeComparators.bfs())).logger(logger).build(); @@ -122,7 +122,7 @@ public void test() { .create(exprTraceChecker, JoiningPrecRefiner.create(new VarsRefToExplPrec()), PruneStrategy.LAZY, logger); - final SafetyChecker, Trace, ExplPrec> checker = CegarChecker.create( + final SafetyChecker, Trace, ExplPrec> checker = ArgCegarChecker.create( abstractor, refiner, logger); final SafetyResult, Trace> safetyStatus = checker.check(prec); diff --git a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java index 5eea722540..bed9497f54 100644 --- a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java +++ b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java @@ -44,9 +44,9 @@ import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.analysis.expr.ExprStatePredicate; @@ -104,7 +104,7 @@ public void testPredPrec() { final ArgBuilder argBuilder = ArgBuilder.create(lts, analysis, target); - final Abstractor abstractor = BasicAbstractor.builder( + final ArgAbstractor abstractor = BasicArgAbstractor.builder( argBuilder).logger(logger) .build(); @@ -117,7 +117,7 @@ public void testPredPrec() { JoiningPrecRefiner.create(new ItpRefToPredPrec(ExprSplitters.atoms())), PruneStrategy.LAZY, logger); - final SafetyChecker, Trace, PredPrec> checker = CegarChecker.create( + final SafetyChecker, Trace, PredPrec> checker = ArgCegarChecker.create( abstractor, refiner, logger); final SafetyResult, Trace> safetyStatus = checker.check(prec); diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt deleted file mode 100644 index d17f15fda1..0000000000 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAbstractor.kt +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2024 Budapest University of Technology and Economics - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package hu.bme.mit.theta.xcfa.analysis - -import com.google.common.base.Preconditions -import hu.bme.mit.theta.analysis.Action -import hu.bme.mit.theta.analysis.Prec -import hu.bme.mit.theta.analysis.State -import hu.bme.mit.theta.analysis.algorithm.arg.ARG -import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder -import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode -import hu.bme.mit.theta.analysis.algorithm.cegar.AbstractorResult -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor -import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion -import hu.bme.mit.theta.analysis.reachedset.Partition -import hu.bme.mit.theta.analysis.waitlist.Waitlist -import hu.bme.mit.theta.common.logging.Logger -import java.util.function.Function - -class XcfaAbstractor( - argBuilder: ArgBuilder, - projection: Function?, - waitlist: Waitlist>, - stopCriterion: StopCriterion, - logger: Logger, -) : BasicAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) { - - override fun check(arg: ARG, prec: P): AbstractorResult { - logger.write(Logger.Level.DETAIL, "| | Precision: %s%n", prec) - - if (!arg.isInitialized) { - logger.write(Logger.Level.SUBSTEP, "| | (Re)initializing ARG...") - argBuilder.init(arg, prec) - logger.write(Logger.Level.SUBSTEP, "done%n") - } - - assert(arg.isInitialized) - - logger.write( - Logger.Level.INFO, "| | Starting ARG: %d nodes, %d incomplete, %d unsafe%n", arg.nodes.count(), - arg.incompleteNodes.count(), arg.unsafeNodes.count() - ) - logger.write(Logger.Level.SUBSTEP, "| | Building ARG...") - - val reachedSet: Partition, *> = Partition.of { n: ArgNode -> - projection.apply(n.state) - } - waitlist.clear() - - reachedSet.addAll(arg.nodes) - waitlist.addAll(arg.incompleteNodes) - - if (!stopCriterion.canStop(arg)) { - while (!waitlist.isEmpty) { - val node = waitlist.remove() - var newNodes: Collection>? = emptyList() - if ((node.state as XcfaState<*>).xcfa!!.isInlined) { - close(node, reachedSet[node]) - } else { - val expandProcedureCall = (node.state as XcfaState<*>) in (prec as XcfaPrec

).noPop - closePop(node, reachedSet[node], !expandProcedureCall) - } - if (!node.isSubsumed && !node.isTarget) { - newNodes = argBuilder.expand(node, prec) - reachedSet.addAll(newNodes) - waitlist.addAll(newNodes) - } - if (stopCriterion.canStop(arg, newNodes)) break - } - } - - logger.write(Logger.Level.SUBSTEP, "done%n") - logger.write( - Logger.Level.INFO, "| | Finished ARG: %d nodes, %d incomplete, %d unsafe%n", arg.nodes.count(), - arg.incompleteNodes.count(), arg.unsafeNodes.count() - ) - - waitlist.clear() // Optimization - - return if (arg.isSafe) { - Preconditions.checkState(arg.isComplete, "Returning incomplete ARG as safe") - AbstractorResult.safe() - } else { - AbstractorResult.unsafe() - } - } - - fun closePop(node: ArgNode, candidates: Collection>, popCovered: Boolean) { - if (!node.isLeaf) { - return - } - for (candidate in candidates) { - if (candidate.mayCover(node)) { - var onlyStackCovers = false - (node.state as XcfaState<*>).processes.forEach { (pid: Int, proc: XcfaProcessState) -> - if (proc != (candidate.state as XcfaState<*>).processes[pid]) { - if (popCovered) proc.popped = proc.locs.pop() - onlyStackCovers = true - } - } - if (!onlyStackCovers) { - node.cover(candidate) - } - return - } - } - } - - companion object { - - fun builder( - argBuilder: ArgBuilder): BasicAbstractor.Builder { - return Builder(argBuilder) - } - } - - class Builder(argBuilder: ArgBuilder) - : BasicAbstractor.Builder(argBuilder) { - - override fun build(): BasicAbstractor { - return XcfaAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) - } - } -} diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt index 64bd2e3d62..f923d0e6f0 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaAnalysis.kt @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis import hu.bme.mit.theta.analysis.* import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion import hu.bme.mit.theta.analysis.expl.ExplInitFunc import hu.bme.mit.theta.analysis.expl.ExplPrec @@ -54,251 +53,364 @@ import java.util.* import java.util.function.Predicate open class XcfaAnalysis( - private val corePartialOrd: PartialOrd>>, - private val coreInitFunc: InitFunc>, XcfaPrec

>, - private var coreTransFunc: TransFunc>, XcfaAction, XcfaPrec

>, + private val corePartialOrd: PartialOrd>>, + private val coreInitFunc: InitFunc>, XcfaPrec

>, + private var coreTransFunc: TransFunc>, XcfaAction, XcfaPrec

>, ) : Analysis>, XcfaAction, XcfaPrec

> { - init { - ConeOfInfluence.coreTransFunc = transFunc as TransFunc>, XcfaAction, XcfaPrec> - coreTransFunc = ConeOfInfluence.transFunc as TransFunc>, XcfaAction, XcfaPrec

> - } + init { + ConeOfInfluence.coreTransFunc = + transFunc as TransFunc>, XcfaAction, XcfaPrec> + coreTransFunc = + ConeOfInfluence.transFunc as TransFunc>, XcfaAction, XcfaPrec

> + } + + override fun getPartialOrd(): PartialOrd>> = corePartialOrd + + override fun getInitFunc(): InitFunc>, XcfaPrec

> = coreInitFunc - override fun getPartialOrd(): PartialOrd>> = corePartialOrd - override fun getInitFunc(): InitFunc>, XcfaPrec

> = coreInitFunc - override fun getTransFunc(): TransFunc>, XcfaAction, XcfaPrec

> = coreTransFunc + override fun getTransFunc(): TransFunc>, XcfaAction, XcfaPrec

> = + coreTransFunc } /// Common private var tempCnt: Int = 0 -fun getCoreXcfaLts() = LTS>, XcfaAction> { s -> - s.processes.map { proc -> + +fun getCoreXcfaLts() = + LTS>, XcfaAction> { s -> + s.processes + .map { proc -> if (proc.value.locs.peek().final) { - listOf(XcfaAction(proc.key, - XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), SequenceLabel(listOf( + listOf( + XcfaAction( + proc.key, + XcfaEdge( + proc.value.locs.peek(), + proc.value.locs.peek(), + SequenceLabel( + listOf( proc.value.paramStmts.peek().second, ReturnLabel(proc.value.returnStmts.peek()), - ))), nextCnt = s.sGlobal.nextCnt)) + ) + ), + ), + nextCnt = s.sGlobal.nextCnt, + ) + ) } else if (!proc.value.paramsInitialized) { - listOf(XcfaAction(proc.key, XcfaEdge(proc.value.locs.peek(), proc.value.locs.peek(), - proc.value.paramStmts.peek().first), nextCnt = s.sGlobal.nextCnt)) + listOf( + XcfaAction( + proc.key, + XcfaEdge( + proc.value.locs.peek(), + proc.value.locs.peek(), + proc.value.paramStmts.peek().first, + ), + nextCnt = s.sGlobal.nextCnt, + ) + ) } else { - proc.value.locs.peek().outgoingEdges.map { edge -> - val newLabel = edge.label.changeVars(proc.value.varLookup.peek()) - val flatLabels = newLabel.getFlatLabels() - if (flatLabels.any { it is InvokeLabel || it is StartLabel }) { - val newNewLabel = SequenceLabel(flatLabels.map { label -> - if (label is InvokeLabel) { - val procedure = s.xcfa?.procedures?.find { proc -> proc.name == label.name } - ?: error("No such method ${label.name}.") - val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() - SequenceLabel(listOf(procedure.params.withIndex() - .filter { it.value.second != ParamDirection.OUT }.map { iVal -> - val originalVar = iVal.value.first - val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, - originalVar.type) - lookup[originalVar] = tempVar + proc.value.locs.peek().outgoingEdges.map { edge -> + val newLabel = edge.label.changeVars(proc.value.varLookup.peek()) + val flatLabels = newLabel.getFlatLabels() + if (flatLabels.any { it is InvokeLabel || it is StartLabel }) { + val newNewLabel = + SequenceLabel( + flatLabels.map { label -> + if (label is InvokeLabel) { + val procedure = + s.xcfa?.procedures?.find { proc -> proc.name == label.name } + ?: error("No such method ${label.name}.") + val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() + SequenceLabel( + listOf( + procedure.params + .withIndex() + .filter { it.value.second != ParamDirection.OUT } + .map { iVal -> + val originalVar = iVal.value.first + val tempVar = + Var("tmp${tempCnt++}_" + originalVar.name, originalVar.type) + lookup[originalVar] = tempVar + StmtLabel( + Stmts.Assign( + TypeUtils.cast(tempVar, tempVar.type), + TypeUtils.cast(label.params[iVal.index], tempVar.type), + ), + metadata = label.metadata, + ) + }, + listOf(label.copy(tempLookup = lookup)), + ) + .flatten() + ) + } else if (label is StartLabel) { + val procedure = + s.xcfa?.procedures?.find { proc -> proc.name == label.name } + ?: error("No such method ${label.name}.") + val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() + SequenceLabel( + listOf( + procedure.params + .withIndex() + .filter { it.value.second != ParamDirection.OUT } + .mapNotNull { iVal -> + val originalVar = iVal.value.first + val tempVar = + Var("tmp${tempCnt++}_" + originalVar.name, originalVar.type) + lookup[originalVar] = tempVar + val trial = + Try.attempt { StmtLabel( - Stmts.Assign( - TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type)), - metadata = label.metadata) - }, listOf(label.copy(tempLookup = lookup))).flatten()) - } else if (label is StartLabel) { - val procedure = s.xcfa?.procedures?.find { proc -> proc.name == label.name } - ?: error("No such method ${label.name}.") - val lookup: MutableMap, VarDecl<*>> = LinkedHashMap() - SequenceLabel(listOf(procedure.params.withIndex() - .filter { it.value.second != ParamDirection.OUT }.mapNotNull { iVal -> - val originalVar = iVal.value.first - val tempVar = Var("tmp${tempCnt++}_" + originalVar.name, - originalVar.type) - lookup[originalVar] = tempVar - val trial = Try.attempt { - StmtLabel( - Stmts.Assign( - TypeUtils.cast(tempVar, tempVar.type), - TypeUtils.cast(label.params[iVal.index], tempVar.type)), - metadata = label.metadata) - } - if (trial.isSuccess) { - trial.asSuccess().value - } else { - null - } - }, listOf(label.copy(tempLookup = lookup))).flatten()) - } else label - }) - XcfaAction(proc.key, edge.withLabel(newNewLabel), nextCnt = s.sGlobal.nextCnt) - } else - XcfaAction(proc.key, edge.withLabel(newLabel), nextCnt = s.sGlobal.nextCnt) - } + Stmts.Assign( + TypeUtils.cast(tempVar, tempVar.type), + TypeUtils.cast(label.params[iVal.index], tempVar.type), + ), + metadata = label.metadata, + ) + } + if (trial.isSuccess) { + trial.asSuccess().value + } else { + null + } + }, + listOf(label.copy(tempLookup = lookup)), + ) + .flatten() + ) + } else label + } + ) + XcfaAction(proc.key, edge.withLabel(newNewLabel), nextCnt = s.sGlobal.nextCnt) + } else XcfaAction(proc.key, edge.withLabel(newLabel), nextCnt = s.sGlobal.nextCnt) + } } - }.flatten().toSet() -} + } + .flatten() + .toSet() + } fun getXcfaLts(): LTS>, XcfaAction> { - val lts = getCoreXcfaLts() - return LTS>, XcfaAction> { s -> - lts.getEnabledActionsFor(s).filter { !s.apply(it).first.bottom }.toSet() - } + val lts = getCoreXcfaLts() + return LTS>, XcfaAction> { s -> + lts.getEnabledActionsFor(s).filter { !s.apply(it).first.bottom }.toSet() + } } enum class ErrorDetection { - ERROR_LOCATION, - DATA_RACE, - OVERFLOW, - NO_ERROR + ERROR_LOCATION, + DATA_RACE, + OVERFLOW, + NO_ERROR, } fun getXcfaErrorPredicate( - errorDetection: ErrorDetection): Predicate>> = when (errorDetection) { + errorDetection: ErrorDetection +): Predicate>> = + when (errorDetection) { ErrorDetection.ERROR_LOCATION -> - Predicate>> { s -> s.processes.any { it.value.locs.peek().error } } + Predicate>> { s -> + s.processes.any { it.value.locs.peek().error } + } ErrorDetection.DATA_RACE -> { - Predicate>> { s -> - val xcfa = s.xcfa!! - for (process1 in s.processes) - for (process2 in s.processes) - if (process1.key != process2.key) - for (edge1 in process1.value.locs.peek().outgoingEdges) - for (edge2 in process2.value.locs.peek().outgoingEdges) { - val mutexes1 = s.mutexes.filterValues { it == process1.key }.keys - val mutexes2 = s.mutexes.filterValues { it == process2.key }.keys - val globalVars1 = edge1.getGlobalVarsWithNeededMutexes(xcfa, mutexes1) - val globalVars2 = edge2.getGlobalVarsWithNeededMutexes(xcfa, mutexes2) - for (v1 in globalVars1) - for (v2 in globalVars2) - if (v1.varDecl == v2.varDecl) - if (v1.access.isWritten || v2.access.isWritten) - if ((v1.mutexes intersect v2.mutexes).isEmpty()) - return@Predicate true - } - false - } + Predicate>> { s -> + val xcfa = s.xcfa!! + for (process1 in s.processes) for (process2 in s.processes) if ( + process1.key != process2.key + ) + for (edge1 in process1.value.locs.peek().outgoingEdges) for (edge2 in + process2.value.locs.peek().outgoingEdges) { + val mutexes1 = s.mutexes.filterValues { it == process1.key }.keys + val mutexes2 = s.mutexes.filterValues { it == process2.key }.keys + val globalVars1 = edge1.getGlobalVarsWithNeededMutexes(xcfa, mutexes1) + val globalVars2 = edge2.getGlobalVarsWithNeededMutexes(xcfa, mutexes2) + for (v1 in globalVars1) for (v2 in globalVars2) if (v1.varDecl == v2.varDecl) + if (v1.access.isWritten || v2.access.isWritten) + if ((v1.mutexes intersect v2.mutexes).isEmpty()) return@Predicate true + } + false + } } - ErrorDetection.NO_ERROR, ErrorDetection.OVERFLOW -> Predicate>> { false } -} + ErrorDetection.NO_ERROR, + ErrorDetection.OVERFLOW -> Predicate>> { false } + } fun getPartialOrder(partialOrd: PartialOrd>) = - PartialOrd>> { s1, s2 -> - s1.processes == s2.processes && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes && partialOrd.isLeq( - s1.sGlobal, s2.sGlobal) - } + PartialOrd>> { s1, s2 -> + s1.processes == s2.processes && + s1.bottom == s2.bottom && + s1.mutexes == s2.mutexes && + partialOrd.isLeq(s1.sGlobal, s2.sGlobal) + } -private fun stackIsLeq(s1: XcfaState>, - s2: XcfaState>) = s2.processes.keys.all { pid -> +private fun stackIsLeq(s1: XcfaState>, s2: XcfaState>) = + s2.processes.keys.all { pid -> s1.processes[pid]?.let { ps1 -> - val ps2 = s2.processes.getValue(pid) - ps1.locs.peek() == ps2.locs.peek() && ps1.paramsInitialized && ps2.paramsInitialized + val ps2 = s2.processes.getValue(pid) + ps1.locs.peek() == ps2.locs.peek() && ps1.paramsInitialized && ps2.paramsInitialized } ?: false -} + } fun getStackPartialOrder(partialOrd: PartialOrd>) = - PartialOrd>> { s1, s2 -> - s1.processes.size == s2.processes.size && stackIsLeq(s1, - s2) && s1.bottom == s2.bottom && s1.mutexes == s2.mutexes - && partialOrd.isLeq(s1.withGeneralizedVars(), s2.withGeneralizedVars()) - } + PartialOrd>> { s1, s2 -> + s1.processes.size == s2.processes.size && + stackIsLeq(s1, s2) && + s1.bottom == s2.bottom && + s1.mutexes == s2.mutexes && + partialOrd.isLeq(s1.withGeneralizedVars(), s2.withGeneralizedVars()) + } private fun >, P : XcfaPrec> getXcfaArgBuilder( - analysis: Analysis, - lts: LTS>, XcfaAction>, - errorDetection: ErrorDetection) - : ArgBuilder = - ArgBuilder.create( - lts, - analysis, - getXcfaErrorPredicate(errorDetection) - ) + analysis: Analysis, + lts: LTS>, XcfaAction>, + errorDetection: ErrorDetection, +): ArgBuilder = + ArgBuilder.create(lts, analysis, getXcfaErrorPredicate(errorDetection)) fun >, P : XcfaPrec> getXcfaAbstractor( - analysis: Analysis, - waitlist: Waitlist<*>, - stopCriterion: StopCriterion<*, *>, - logger: Logger, - lts: LTS>, XcfaAction>, - errorDetection: ErrorDetection -): Abstractor>, XcfaAction, out XcfaPrec> = - XcfaAbstractor.builder(getXcfaArgBuilder(analysis, lts, errorDetection)) - .waitlist(waitlist as Waitlist>) // TODO: can we do this nicely? - .stopCriterion(stopCriterion as StopCriterion).logger(logger) - .projection { - if (it.xcfa!!.isInlined) it.processes - else it.processes.map { (_, p) -> p.locs.peek() } - } - .build() // TODO: can we do this nicely? + analysis: Analysis, + waitlist: Waitlist<*>, + stopCriterion: StopCriterion<*, *>, + logger: Logger, + lts: LTS>, XcfaAction>, + errorDetection: ErrorDetection, +): ArgAbstractor>, XcfaAction, out XcfaPrec> = + XcfaArgAbstractor.builder(getXcfaArgBuilder(analysis, lts, errorDetection)) + .waitlist(waitlist as Waitlist>) // TODO: can we do this nicely? + .stopCriterion(stopCriterion as StopCriterion) + .logger(logger) + .projection { + if (it.xcfa!!.isInlined) it.processes else it.processes.map { (_, p) -> p.locs.peek() } + } + .build() // TODO: can we do this nicely? /// EXPL -private fun getExplXcfaInitFunc(xcfa: XCFA, - solver: Solver): (XcfaPrec>) -> List>> { - val processInitState = xcfa.initProcedures.mapIndexed { i, it -> +private fun getExplXcfaInitFunc( + xcfa: XCFA, + solver: Solver, +): (XcfaPrec>) -> List>> { + val processInitState = + xcfa.initProcedures + .mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) - }.toMap() - return { p -> - ExplInitFunc.create(solver, True()).getPtrInitFunc().getInitStates(p.p) - .map { XcfaState(xcfa, processInitState, it) } + Pair( + i, + XcfaProcessState( + initLocStack, + prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))), + ), + ) + } + .toMap() + return { p -> + ExplInitFunc.create(solver, True()).getPtrInitFunc().getInitStates(p.p).map { + XcfaState(xcfa, processInitState, it) } + } } -private fun getExplXcfaTransFunc(solver: Solver, maxEnum: Int, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { - val explTransFunc = (ExplStmtTransFunc.create(solver, - maxEnum) as TransFunc).getPtrTransFunc(isHavoc) - return { s, a, p -> - val (newSt, newAct) = s.apply(a) - explTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( - listOf(s.processes.map { it.value.varLookup }.flatten(), - listOf(getTempLookup(a.label))).flatten())).map { newSt.withState(it) } - } +private fun getExplXcfaTransFunc( + solver: Solver, + maxEnum: Int, + isHavoc: Boolean, +): (XcfaState>, XcfaAction, XcfaPrec>) -> List< + XcfaState> + > { + val explTransFunc = + (ExplStmtTransFunc.create(solver, maxEnum) as TransFunc) + .getPtrTransFunc(isHavoc) + return { s, a, p -> + val (newSt, newAct) = s.apply(a) + explTransFunc + .getSuccStates( + newSt.sGlobal, + newAct, + p.p.addVars( + listOf(s.processes.map { it.value.varLookup }.flatten(), listOf(getTempLookup(a.label))) + .flatten() + ), + ) + .map { newSt.withState(it) } + } } -class ExplXcfaAnalysis(xcfa: XCFA, solver: Solver, maxEnum: Int, - partialOrd: PartialOrd>>, isHavoc: Boolean) : - XcfaAnalysis>( - corePartialOrd = partialOrd, - coreInitFunc = getExplXcfaInitFunc(xcfa, solver), - coreTransFunc = getExplXcfaTransFunc(solver, maxEnum, isHavoc) - ) +class ExplXcfaAnalysis( + xcfa: XCFA, + solver: Solver, + maxEnum: Int, + partialOrd: PartialOrd>>, + isHavoc: Boolean, +) : + XcfaAnalysis>( + corePartialOrd = partialOrd, + coreInitFunc = getExplXcfaInitFunc(xcfa, solver), + coreTransFunc = getExplXcfaTransFunc(solver, maxEnum, isHavoc), + ) /// PRED -private fun getPredXcfaInitFunc(xcfa: XCFA, - predAbstractor: PredAbstractor): (XcfaPrec>) -> List>> { - val processInitState = xcfa.initProcedures.mapIndexed { i, it -> +private fun getPredXcfaInitFunc( + xcfa: XCFA, + predAbstractor: PredAbstractor, +): (XcfaPrec>) -> List>> { + val processInitState = + xcfa.initProcedures + .mapIndexed { i, it -> val initLocStack: LinkedList = LinkedList() initLocStack.add(it.first.initLoc) - Pair(i, XcfaProcessState(initLocStack, prefix = "T$i", - varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))))) - }.toMap() - return { p -> - PredInitFunc.create(predAbstractor, True()).getPtrInitFunc().getInitStates(p.p) - .map { XcfaState(xcfa, processInitState, it) } + Pair( + i, + XcfaProcessState( + initLocStack, + prefix = "T$i", + varLookup = LinkedList(listOf(createLookup(it.first, "T$i", ""))), + ), + ) + } + .toMap() + return { p -> + PredInitFunc.create(predAbstractor, True()).getPtrInitFunc().getInitStates(p.p).map { + XcfaState(xcfa, processInitState, it) } + } } -private fun getPredXcfaTransFunc(predAbstractor: PredAbstractors.PredAbstractor, isHavoc: Boolean): - (XcfaState>, XcfaAction, XcfaPrec>) -> List>> { - val predTransFunc = (PredTransFunc.create( - predAbstractor) as TransFunc).getPtrTransFunc(isHavoc) - return { s, a, p -> - val (newSt, newAct) = s.apply(a) - predTransFunc.getSuccStates(newSt.sGlobal, newAct, p.p.addVars( - s.processes.map { it.value.foldVarLookup() + getTempLookup(a.label) } - )).map { newSt.withState(it) } - } +private fun getPredXcfaTransFunc( + predAbstractor: PredAbstractors.PredAbstractor, + isHavoc: Boolean, +): (XcfaState>, XcfaAction, XcfaPrec>) -> List< + XcfaState> + > { + val predTransFunc = + (PredTransFunc.create(predAbstractor) as TransFunc) + .getPtrTransFunc(isHavoc) + return { s, a, p -> + val (newSt, newAct) = s.apply(a) + predTransFunc + .getSuccStates( + newSt.sGlobal, + newAct, + p.p.addVars(s.processes.map { it.value.foldVarLookup() + getTempLookup(a.label) }), + ) + .map { newSt.withState(it) } + } } -class PredXcfaAnalysis(xcfa: XCFA, solver: Solver, predAbstractor: PredAbstractor, - partialOrd: PartialOrd>>, isHavoc: Boolean) : - XcfaAnalysis>( - corePartialOrd = partialOrd, - coreInitFunc = getPredXcfaInitFunc(xcfa, predAbstractor), - coreTransFunc = getPredXcfaTransFunc(predAbstractor, isHavoc) - ) +class PredXcfaAnalysis( + xcfa: XCFA, + solver: Solver, + predAbstractor: PredAbstractor, + partialOrd: PartialOrd>>, + isHavoc: Boolean, +) : + XcfaAnalysis>( + corePartialOrd = partialOrd, + coreInitFunc = getPredXcfaInitFunc(xcfa, predAbstractor), + coreTransFunc = getPredXcfaTransFunc(predAbstractor, isHavoc), + ) diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaArgAbstractor.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaArgAbstractor.kt new file mode 100644 index 0000000000..bc2d2b816c --- /dev/null +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaArgAbstractor.kt @@ -0,0 +1,143 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xcfa.analysis + +import com.google.common.base.Preconditions +import hu.bme.mit.theta.analysis.Action +import hu.bme.mit.theta.analysis.Prec +import hu.bme.mit.theta.analysis.State +import hu.bme.mit.theta.analysis.algorithm.arg.ARG +import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder +import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode +import hu.bme.mit.theta.analysis.algorithm.cegar.AbstractorResult +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion +import hu.bme.mit.theta.analysis.reachedset.Partition +import hu.bme.mit.theta.analysis.waitlist.Waitlist +import hu.bme.mit.theta.common.logging.Logger +import java.util.function.Function + +class XcfaArgAbstractor( + argBuilder: ArgBuilder, + projection: Function?, + waitlist: Waitlist>, + stopCriterion: StopCriterion, + logger: Logger, +) : BasicArgAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) { + + override fun check(arg: ARG, prec: P): AbstractorResult { + logger.write(Logger.Level.DETAIL, "| | Precision: %s%n", prec) + + if (!arg.isInitialized) { + logger.write(Logger.Level.SUBSTEP, "| | (Re)initializing ARG...") + argBuilder.init(arg, prec) + logger.write(Logger.Level.SUBSTEP, "done%n") + } + + assert(arg.isInitialized) + + logger.write( + Logger.Level.INFO, + "| | Starting ARG: %d nodes, %d incomplete, %d unsafe%n", + arg.nodes.count(), + arg.incompleteNodes.count(), + arg.unsafeNodes.count(), + ) + logger.write(Logger.Level.SUBSTEP, "| | Building ARG...") + + val reachedSet: Partition, *> = + Partition.of { n: ArgNode -> projection.apply(n.state) } + waitlist.clear() + + reachedSet.addAll(arg.nodes) + waitlist.addAll(arg.incompleteNodes) + + if (!stopCriterion.canStop(arg)) { + while (!waitlist.isEmpty) { + val node = waitlist.remove() + var newNodes: Collection>? = emptyList() + if ((node.state as XcfaState<*>).xcfa!!.isInlined) { + close(node, reachedSet[node]) + } else { + val expandProcedureCall = (node.state as XcfaState<*>) in (prec as XcfaPrec

).noPop + closePop(node, reachedSet[node], !expandProcedureCall) + } + if (!node.isSubsumed && !node.isTarget) { + newNodes = argBuilder.expand(node, prec) + reachedSet.addAll(newNodes) + waitlist.addAll(newNodes) + } + if (stopCriterion.canStop(arg, newNodes)) break + } + } + + logger.write(Logger.Level.SUBSTEP, "done%n") + logger.write( + Logger.Level.INFO, + "| | Finished ARG: %d nodes, %d incomplete, %d unsafe%n", + arg.nodes.count(), + arg.incompleteNodes.count(), + arg.unsafeNodes.count(), + ) + + waitlist.clear() // Optimization + + return if (arg.isSafe) { + Preconditions.checkState(arg.isComplete, "Returning incomplete ARG as safe") + AbstractorResult.safe() + } else { + AbstractorResult.unsafe() + } + } + + fun closePop(node: ArgNode, candidates: Collection>, popCovered: Boolean) { + if (!node.isLeaf) { + return + } + for (candidate in candidates) { + if (candidate.mayCover(node)) { + var onlyStackCovers = false + (node.state as XcfaState<*>).processes.forEach { (pid: Int, proc: XcfaProcessState) -> + if (proc != (candidate.state as XcfaState<*>).processes[pid]) { + if (popCovered) proc.popped = proc.locs.pop() + onlyStackCovers = true + } + } + if (!onlyStackCovers) { + node.cover(candidate) + } + return + } + } + } + + companion object { + + fun builder( + argBuilder: ArgBuilder + ): BasicArgAbstractor.Builder { + return Builder(argBuilder) + } + } + + class Builder(argBuilder: ArgBuilder) : + BasicArgAbstractor.Builder(argBuilder) { + + override fun build(): BasicArgAbstractor { + return XcfaArgAbstractor(argBuilder, projection, waitlist, stopCriterion, logger) + } + } +} diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt index ad0a385e5d..93410e0641 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt @@ -64,7 +64,7 @@ class XcfaSingleExprTraceRefiner, prec: P?): RefinerResult { + fun refineTemp(arg: ARG, prec: P?): RefinerResult> { Preconditions.checkNotNull(arg) Preconditions.checkNotNull(prec) assert(!arg.isSafe) { "ARG must be unsafe" } @@ -118,7 +118,7 @@ class XcfaSingleExprTraceRefiner, prec: P?): RefinerResult { + override fun refine(arg: ARG, prec: P?): RefinerResult> { Preconditions.checkNotNull(arg) Preconditions.checkNotNull

(prec) assert(!arg.isSafe) { "ARG must be unsafe" } diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt index b4aa758303..a04508f9cf 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaExplAnalysisTest.kt @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis -import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner +import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions import hu.bme.mit.theta.analysis.expl.* import hu.bme.mit.theta.analysis.expr.refinement.* @@ -39,255 +38,309 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* +import java.util.* +import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import java.util.* -import kotlin.random.Random - class XcfaExplAnalysisTest { + companion object { - companion object { - - private val seed = 1001 - - @JvmStatic - fun data(): Collection> { - return listOf( - arrayOf("/00assignment.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/01function.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/02functionparam.c", SafetyResult<*, *>::isSafe), - arrayOf("/03nondetfunction.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/04multithread.c", SafetyResult<*, *>::isUnsafe), - ) - } - } - - @ParameterizedTest - @MethodSource("data") - fun testNoporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing NOPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val analysis = ExplXcfaAnalysis( - xcfa, - Z3LegacySolverFactory.getInstance().createSolver(), - 1, - getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), false - ) - - val lts = getXcfaLts() - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testSporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing SPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val analysis = ExplXcfaAnalysis( - xcfa, - Z3LegacySolverFactory.getInstance().createSolver(), - 1, - getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), false - ) - - val lts = XcfaSporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testDporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - XcfaDporLts.random = Random(seed) - println("Testing DPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val analysis = ExplXcfaAnalysis( - xcfa, - Z3LegacySolverFactory.getInstance().createSolver(), - 1, - XcfaDporLts.getPartialOrder(getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd())), false - ) - - val lts = XcfaDporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - lts.waitlist, - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - ConsoleLogger( - Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testAasporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing AASPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val analysis = ExplXcfaAnalysis( - xcfa, - Z3LegacySolverFactory.getInstance().createSolver(), - 1, - getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), false - ) - - val lts = XcfaAasporLts(xcfa, mutableMapOf()) - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner, ExplPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToExplPrec())) - val atomicNodePruner = AtomicNodePruner>, XcfaAction>() - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testAadporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - XcfaDporLts.random = Random(seed) - println("Testing AADPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val analysis = ExplXcfaAnalysis( - xcfa, - Z3LegacySolverFactory.getInstance().createSolver(), - 1, - XcfaDporLts.getPartialOrder(getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd())), false - ) - - val lts = XcfaAadporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - lts.waitlist, - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner(ItpRefToPtrPrec(ItpRefToExplPrec())) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) - - + private val seed = 1001 - Assertions.assertTrue(verdict(safetyResult)) + @JvmStatic + fun data(): Collection> { + return listOf( + arrayOf("/00assignment.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/01function.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/02functionparam.c", SafetyResult<*, *>::isSafe), + arrayOf("/03nondetfunction.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/04multithread.c", SafetyResult<*, *>::isUnsafe), + ) } -} \ No newline at end of file + } + + @ParameterizedTest + @MethodSource("data") + fun testNoporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing NOPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val analysis = + ExplXcfaAnalysis( + xcfa, + Z3LegacySolverFactory.getInstance().createSolver(), + 1, + getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), + false, + ) + + val lts = getXcfaLts() + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, ExplPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testSporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing SPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val analysis = + ExplXcfaAnalysis( + xcfa, + Z3LegacySolverFactory.getInstance().createSolver(), + 1, + getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), + false, + ) + + val lts = XcfaSporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, ExplPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testDporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + XcfaDporLts.random = Random(seed) + println("Testing DPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val analysis = + ExplXcfaAnalysis( + xcfa, + Z3LegacySolverFactory.getInstance().createSolver(), + 1, + XcfaDporLts.getPartialOrder(getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd())), + false, + ) + + val lts = XcfaDporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + lts.waitlist, + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, ExplPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + ConsoleLogger(Logger.Level.DETAIL), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testAasporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing AASPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val analysis = + ExplXcfaAnalysis( + xcfa, + Z3LegacySolverFactory.getInstance().createSolver(), + 1, + getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd()), + false, + ) + + val lts = XcfaAasporLts(xcfa, mutableMapOf()) + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner, ExplPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) + val atomicNodePruner = AtomicNodePruner>, XcfaAction>() + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + atomicNodePruner, + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = + ArgCegarChecker.create( + abstractor, + AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf()), + ) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testAadporExpl(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + XcfaDporLts.random = Random(seed) + println("Testing AADPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val analysis = + ExplXcfaAnalysis( + xcfa, + Z3LegacySolverFactory.getInstance().createSolver(), + 1, + XcfaDporLts.getPartialOrder(getPartialOrder(ExplOrd.getInstance().getPtrPartialOrd())), + false, + ) + + val lts = XcfaAadporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + lts.waitlist, + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner(ItpRefToPtrPrec(ItpRefToExplPrec())) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } +} diff --git a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt index e398b5ed07..a10e82f096 100644 --- a/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt +++ b/subprojects/xcfa/xcfa-analysis/src/test/java/hu/bme/mit/theta/xcfa/analysis/XcfaPredAnalysisTest.kt @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis -import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner +import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions import hu.bme.mit.theta.analysis.expr.refinement.* import hu.bme.mit.theta.analysis.pred.* @@ -39,262 +38,316 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory import hu.bme.mit.theta.xcfa.analysis.coi.ConeOfInfluence import hu.bme.mit.theta.xcfa.analysis.coi.XcfaCoiMultiThread import hu.bme.mit.theta.xcfa.analysis.por.* +import java.util.* +import kotlin.random.Random import org.junit.jupiter.api.Assertions import org.junit.jupiter.params.ParameterizedTest import org.junit.jupiter.params.provider.MethodSource -import java.util.* -import kotlin.random.Random - class XcfaPredAnalysisTest { + companion object { - companion object { - - private val seed = 1001; - - @JvmStatic - fun data(): Collection> { - return listOf( - arrayOf("/00assignment.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/01function.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/02functionparam.c", SafetyResult<*, *>::isSafe), - arrayOf("/03nondetfunction.c", SafetyResult<*, *>::isUnsafe), - arrayOf("/04multithread.c", SafetyResult<*, *>::isUnsafe), - ) - } - } - - @ParameterizedTest - @MethodSource("data") - fun testNoporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing NOPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val solver = Z3LegacySolverFactory.getInstance().createSolver() - val analysis = PredXcfaAnalysis( - xcfa, - solver, - PredAbstractors.cartesianAbstractor(solver), - getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), - false - ) - - val lts = getXcfaLts() - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testSporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing SPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val solver = Z3LegacySolverFactory.getInstance().createSolver() - val analysis = PredXcfaAnalysis( - xcfa, - solver, - PredAbstractors.cartesianAbstractor(solver), - getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), false - ) - - val lts = XcfaSporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testDporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - XcfaDporLts.random = Random(seed) - println("Testing DPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val solver = Z3LegacySolverFactory.getInstance().createSolver() - val analysis = PredXcfaAnalysis( - xcfa, - solver, - PredAbstractors.cartesianAbstractor(solver), - XcfaDporLts.getPartialOrder(getPartialOrder(PredOrd.create(solver).getPtrPartialOrd())), false - ) - - val lts = XcfaDporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - lts.waitlist, - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner>, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - ConsoleLogger( - Logger.Level.DETAIL)) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testAasporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - println("Testing AASPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val solver = Z3LegacySolverFactory.getInstance().createSolver() - val analysis = PredXcfaAnalysis( - xcfa, - solver, - PredAbstractors.cartesianAbstractor(solver), - getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), false - ) - - val lts = XcfaAasporLts(xcfa, mutableMapOf()) - - val abstractor = getXcfaAbstractor(analysis, - PriorityWaitlist.create( - ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs())), - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner, PredPrec, ItpRefutation>( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) - val atomicNodePruner = AtomicNodePruner>, XcfaAction>() - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, NullLogger.getInstance(), - atomicNodePruner) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf())) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) - - - - Assertions.assertTrue(verdict(safetyResult)) - } - - @ParameterizedTest - @MethodSource("data") - fun testAadporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { - XcfaDporLts.random = Random(seed) - println("Testing AADPOR on $filepath...") - val stream = javaClass.getResourceAsStream(filepath) - val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first - ConeOfInfluence = XcfaCoiMultiThread(xcfa) - - val solver = Z3LegacySolverFactory.getInstance().createSolver() - val analysis = PredXcfaAnalysis( - xcfa, - solver, - PredAbstractors.cartesianAbstractor(solver), - XcfaDporLts.getPartialOrder(getPartialOrder(PredOrd.create(solver).getPtrPartialOrd())), false - ) - - val lts = XcfaAadporLts(xcfa) - - val abstractor = getXcfaAbstractor(analysis, - lts.waitlist, - StopCriterions.firstCex>, XcfaAction>(), - ConsoleLogger(Logger.Level.DETAIL), - lts, - ErrorDetection.ERROR_LOCATION) as Abstractor>, XcfaAction, XcfaPrec>> - - val precRefiner = XcfaPrecRefiner( - ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole()))) - - val refiner = - XcfaSingleExprTraceRefiner.create( - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), - Z3LegacySolverFactory.getInstance().createItpSolver()), - precRefiner, PruneStrategy.FULL, - NullLogger.getInstance()) as Refiner>, XcfaAction, XcfaPrec>> - - val cegarChecker = - CegarChecker.create(abstractor, refiner) - - val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) - - + private val seed = 1001 - Assertions.assertTrue(verdict(safetyResult)) + @JvmStatic + fun data(): Collection> { + return listOf( + arrayOf("/00assignment.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/01function.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/02functionparam.c", SafetyResult<*, *>::isSafe), + arrayOf("/03nondetfunction.c", SafetyResult<*, *>::isUnsafe), + arrayOf("/04multithread.c", SafetyResult<*, *>::isUnsafe), + ) } -} \ No newline at end of file + } + + @ParameterizedTest + @MethodSource("data") + fun testNoporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing NOPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val solver = Z3LegacySolverFactory.getInstance().createSolver() + val analysis = + PredXcfaAnalysis( + xcfa, + solver, + PredAbstractors.cartesianAbstractor(solver), + getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), + false, + ) + + val lts = getXcfaLts() + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testSporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing SPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val solver = Z3LegacySolverFactory.getInstance().createSolver() + val analysis = + PredXcfaAnalysis( + xcfa, + solver, + PredAbstractors.cartesianAbstractor(solver), + getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), + false, + ) + + val lts = XcfaSporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testDporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + XcfaDporLts.random = Random(seed) + println("Testing DPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val solver = Z3LegacySolverFactory.getInstance().createSolver() + val analysis = + PredXcfaAnalysis( + xcfa, + solver, + PredAbstractors.cartesianAbstractor(solver), + XcfaDporLts.getPartialOrder(getPartialOrder(PredOrd.create(solver).getPtrPartialOrd())), + false, + ) + + val lts = XcfaDporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + lts.waitlist, + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner>, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + ConsoleLogger(Logger.Level.DETAIL), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testAasporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + println("Testing AASPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val solver = Z3LegacySolverFactory.getInstance().createSolver() + val analysis = + PredXcfaAnalysis( + xcfa, + solver, + PredAbstractors.cartesianAbstractor(solver), + getPartialOrder(PredOrd.create(solver).getPtrPartialOrd()), + false, + ) + + val lts = XcfaAasporLts(xcfa, mutableMapOf()) + + val abstractor = + getXcfaAbstractor( + analysis, + PriorityWaitlist.create( + ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + ), + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) + val atomicNodePruner = AtomicNodePruner>, XcfaAction>() + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + atomicNodePruner, + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = + ArgCegarChecker.create( + abstractor, + AasporRefiner.create(refiner, PruneStrategy.FULL, mutableMapOf()), + ) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } + + @ParameterizedTest + @MethodSource("data") + fun testAadporPred(filepath: String, verdict: (SafetyResult<*, *>) -> Boolean) { + XcfaDporLts.random = Random(seed) + println("Testing AADPOR on $filepath...") + val stream = javaClass.getResourceAsStream(filepath) + val xcfa = getXcfaFromC(stream!!, ParseContext(), false, false, NullLogger.getInstance()).first + ConeOfInfluence = XcfaCoiMultiThread(xcfa) + + val solver = Z3LegacySolverFactory.getInstance().createSolver() + val analysis = + PredXcfaAnalysis( + xcfa, + solver, + PredAbstractors.cartesianAbstractor(solver), + XcfaDporLts.getPartialOrder(getPartialOrder(PredOrd.create(solver).getPtrPartialOrd())), + false, + ) + + val lts = XcfaAadporLts(xcfa) + + val abstractor = + getXcfaAbstractor( + analysis, + lts.waitlist, + StopCriterions.firstCex>, XcfaAction>(), + ConsoleLogger(Logger.Level.DETAIL), + lts, + ErrorDetection.ERROR_LOCATION, + ) + as ArgAbstractor>, XcfaAction, XcfaPrec>> + + val precRefiner = + XcfaPrecRefiner( + ItpRefToPtrPrec(ItpRefToPredPrec(ExprSplitters.whole())) + ) + + val refiner = + XcfaSingleExprTraceRefiner.create( + ExprTraceBwBinItpChecker.create( + BoolExprs.True(), + BoolExprs.True(), + Z3LegacySolverFactory.getInstance().createItpSolver(), + ), + precRefiner, + PruneStrategy.FULL, + NullLogger.getInstance(), + ) as ArgRefiner>, XcfaAction, XcfaPrec>> + + val cegarChecker = ArgCegarChecker.create(abstractor, refiner) + + val safetyResult = cegarChecker.check(XcfaPrec(PtrPrec(PredPrec.of(), emptySet()))) + + Assertions.assertTrue(verdict(safetyResult)) + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt index 8c39486021..f8bf86f8d2 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt @@ -23,9 +23,9 @@ import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.arg.ARG -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner import hu.bme.mit.theta.analysis.expr.ExprAction import hu.bme.mit.theta.analysis.expr.ExprState import hu.bme.mit.theta.analysis.expr.refinement.* @@ -43,14 +43,20 @@ import hu.bme.mit.theta.xcfa.cli.params.* import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getCegarChecker(xcfa: XCFA, mcm: MCM, +fun getCegarChecker( + xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { + logger: Logger +): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { val cegarConfig = config.backendConfig.specConfig as CegarConfig - val abstractionSolverFactory: SolverFactory = getSolver(cegarConfig.abstractorConfig.abstractionSolver, - cegarConfig.abstractorConfig.validateAbstractionSolver) - val refinementSolverFactory: SolverFactory = getSolver(cegarConfig.refinerConfig.refinementSolver, - cegarConfig.refinerConfig.validateRefinementSolver) + val abstractionSolverFactory: SolverFactory = getSolver( + cegarConfig.abstractorConfig.abstractionSolver, + cegarConfig.abstractorConfig.validateAbstractionSolver + ) + val refinementSolverFactory: SolverFactory = getSolver( + cegarConfig.refinerConfig.refinementSolver, + cegarConfig.refinerConfig.validateRefinementSolver + ) val ignoredVarRegistry = mutableMapOf, MutableSet>() @@ -59,16 +65,18 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, (cegarConfig.coi.porLts as XcfaDporLts).waitlist } else { PriorityWaitlist.create>, XcfaAction>>( - cegarConfig.abstractorConfig.search.getComp(xcfa)) + cegarConfig.abstractorConfig.search.getComp(xcfa) + ) } val abstractionSolverInstance = abstractionSolverFactory.createSolver() val globalStatePartialOrd: PartialOrd> = cegarConfig.abstractorConfig.domain.partialOrd( - abstractionSolverInstance) as PartialOrd> + abstractionSolverInstance + ) as PartialOrd> val corePartialOrd: PartialOrd>> = if (xcfa.isInlined) getPartialOrder(globalStatePartialOrd) else getStackPartialOrder(globalStatePartialOrd) - val abstractor: Abstractor = cegarConfig.abstractorConfig.domain.abstractor( + val abstractor: ArgAbstractor = cegarConfig.abstractorConfig.domain.abstractor( xcfa, abstractionSolverInstance, cegarConfig.abstractorConfig.maxEnum, @@ -83,7 +91,7 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, corePartialOrd }, cegarConfig.abstractorConfig.havocMemory - ) as Abstractor + ) as ArgAbstractor val ref: ExprTraceChecker = cegarConfig.refinerConfig.refinement.refiner(refinementSolverFactory, cegarConfig.cexMonitor) @@ -91,43 +99,50 @@ fun getCegarChecker(xcfa: XCFA, mcm: MCM, val precRefiner: PrecRefiner = cegarConfig.abstractorConfig.domain.itpPrecRefiner(cegarConfig.refinerConfig.exprSplitter.exprSplitter) as PrecRefiner - val atomicNodePruner: NodePruner = cegarConfig.abstractorConfig.domain.nodePruner as NodePruner - val refiner: Refiner = + val atomicNodePruner: NodePruner = + cegarConfig.abstractorConfig.domain.nodePruner as NodePruner + val refiner: ArgRefiner = if (cegarConfig.refinerConfig.refinement == Refinement.MULTI_SEQ) if (cegarConfig.porLevel == POR.AASPOR) - MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner) + MultiExprTraceRefiner.create( + ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner + ) else MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) else if (cegarConfig.porLevel == POR.AASPOR) - XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner) + XcfaSingleExprTraceRefiner.create( + ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, + atomicNodePruner + ) else XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) val cegarChecker = if (cegarConfig.porLevel == POR.AASPOR) - CegarChecker.create( + ArgCegarChecker.create( abstractor, AasporRefiner.create(refiner, cegarConfig.refinerConfig.pruneStrategy, ignoredVarRegistry), logger ) else - CegarChecker.create(abstractor, refiner, logger) + ArgCegarChecker.create(abstractor, refiner, logger) // initialize monitors MonitorCheckpoint.reset() if (cegarConfig.cexMonitor == CexMonitorOptions.CHECK) { - val cm = CexMonitor(logger, cegarChecker.arg) + val cm = CexMonitor(logger, cegarChecker.witness) MonitorCheckpoint.register(cm, "CegarChecker.unsafeARG") } return object : SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { override fun check( - prec: XcfaPrec<*>?): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { + prec: XcfaPrec<*>? + ): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { return cegarChecker.check( - prec) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> + prec + ) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> } override fun check(): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt index ac5b3d3236..8f1695855c 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/params/ParamValues.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.params import com.google.gson.reflect.TypeToken @@ -23,7 +22,7 @@ import hu.bme.mit.theta.analysis.Prec import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators.ArgNodeComparator -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions import hu.bme.mit.theta.analysis.expl.ExplPrec @@ -55,309 +54,386 @@ import hu.bme.mit.theta.xcfa.model.XCFA import java.lang.reflect.Type enum class InputType { - C, - LLVM, - JSON, - DSL, - CHC, - LITMUS, + C, + LLVM, + JSON, + DSL, + CHC, + LITMUS, } enum class Backend { - CEGAR, - BOUNDED, - CHC, - OC, - LAZY, - PORTFOLIO, - NONE, + CEGAR, + BOUNDED, + CHC, + OC, + LAZY, + PORTFOLIO, + NONE, } enum class POR( - val getLts: (XCFA, MutableMap, MutableSet>) -> LTS>, XcfaAction>, - val isDynamic: Boolean, - val isAbstractionAware: Boolean + val getLts: + (XCFA, MutableMap, MutableSet>) -> LTS< + XcfaState>, + XcfaAction, + >, + val isDynamic: Boolean, + val isAbstractionAware: Boolean, ) { - NOPOR({ _, _ -> getXcfaLts() }, false, false), - SPOR({ xcfa, _ -> XcfaSporLts(xcfa) }, false, false), - AASPOR({ xcfa, registry -> XcfaAasporLts(xcfa, registry) }, false, true), - DPOR({ xcfa, _ -> XcfaDporLts(xcfa) }, true, false), - AADPOR({ xcfa, _ -> XcfaAadporLts(xcfa) }, true, true) + NOPOR({ _, _ -> getXcfaLts() }, false, false), + SPOR({ xcfa, _ -> XcfaSporLts(xcfa) }, false, false), + AASPOR({ xcfa, registry -> XcfaAasporLts(xcfa, registry) }, false, true), + DPOR({ xcfa, _ -> XcfaDporLts(xcfa) }, true, false), + AADPOR({ xcfa, _ -> XcfaAadporLts(xcfa) }, true, true), } enum class Strategy { - DIRECT, - SERVER, - SERVER_DEBUG, - PORTFOLIO + DIRECT, + SERVER, + SERVER_DEBUG, + PORTFOLIO, } // TODO partial orders nicely enum class Domain( - val abstractor: ( - xcfa: XCFA, - solver: Solver, - maxEnum: Int, - waitlist: Waitlist>, XcfaAction>>, - stopCriterion: StopCriterion>, XcfaAction>, - logger: Logger, - lts: LTS>, XcfaAction>, - errorDetectionType: ErrorDetection, - partialOrd: PartialOrd>>, - isHavoc: Boolean - ) -> Abstractor, - val itpPrecRefiner: (exprSplitter: ExprSplitter) -> PrecRefiner, - val initPrec: (XCFA, InitPrec) -> XcfaPrec>, - val partialOrd: (Solver) -> PartialOrd>, - val nodePruner: NodePruner, - val stateType: Type + val abstractor: + ( + xcfa: XCFA, + solver: Solver, + maxEnum: Int, + waitlist: Waitlist>, XcfaAction>>, + stopCriterion: StopCriterion>, XcfaAction>, + logger: Logger, + lts: LTS>, XcfaAction>, + errorDetectionType: ErrorDetection, + partialOrd: PartialOrd>>, + isHavoc: Boolean, + ) -> ArgAbstractor, + val itpPrecRefiner: + (exprSplitter: ExprSplitter) -> PrecRefiner< + out ExprState, + out ExprAction, + out Prec, + out Refutation, + >, + val initPrec: (XCFA, InitPrec) -> XcfaPrec>, + val partialOrd: (Solver) -> PartialOrd>, + val nodePruner: NodePruner, + val stateType: Type, ) { - EXPL( - abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), d, - e, f, g, h) - }, - itpPrecRefiner = { - XcfaPrecRefiner, ExplPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToExplPrec())) - }, - initPrec = { x, ip -> ip.explPrec(x) }, - partialOrd = { PartialOrd { s1, s2 -> s1.isLeq(s2) }.getPtrPartialOrd() }, - nodePruner = AtomicNodePruner>, XcfaAction>(), - stateType = TypeToken.get(ExplState::class.java).type - ), - PRED_BOOL( - abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) - }, - itpPrecRefiner = { a -> - XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) - }, - initPrec = { x, ip -> ip.predPrec(x) }, - partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, - nodePruner = AtomicNodePruner>, XcfaAction>(), - stateType = TypeToken.get(PredState::class.java).type - ), - PRED_CART( - abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.cartesianAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) - }, - itpPrecRefiner = { a -> - XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) - }, - initPrec = { x, ip -> ip.predPrec(x) }, - partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, - nodePruner = AtomicNodePruner>, XcfaAction>(), - stateType = TypeToken.get(PredState::class.java).type - ), - PRED_SPLIT( - abstractor = { a, b, c, d, e, f, g, h, i, j -> - getXcfaAbstractor(PredXcfaAnalysis(a, b, PredAbstractors.booleanSplitAbstractor(b), - i as PartialOrd>>, j), d, e, f, g, h) - }, - itpPrecRefiner = { a -> - XcfaPrecRefiner, PredPrec, ItpRefutation>(ItpRefToPtrPrec(ItpRefToPredPrec(a))) - }, - initPrec = { x, ip -> ip.predPrec(x) }, - partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, - nodePruner = AtomicNodePruner>, XcfaAction>(), - stateType = TypeToken.get(PredState::class.java).type - ), + EXPL( + abstractor = { a, b, c, d, e, f, g, h, i, j -> + getXcfaAbstractor( + ExplXcfaAnalysis(a, b, c, i as PartialOrd>>, j), + d, + e, + f, + g, + h, + ) + }, + itpPrecRefiner = { + XcfaPrecRefiner, ExplPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToExplPrec()) + ) + }, + initPrec = { x, ip -> ip.explPrec(x) }, + partialOrd = { PartialOrd { s1, s2 -> s1.isLeq(s2) }.getPtrPartialOrd() }, + nodePruner = AtomicNodePruner>, XcfaAction>(), + stateType = TypeToken.get(ExplState::class.java).type, + ), + PRED_BOOL( + abstractor = { a, b, c, d, e, f, g, h, i, j -> + getXcfaAbstractor( + PredXcfaAnalysis( + a, + b, + PredAbstractors.booleanAbstractor(b), + i as PartialOrd>>, + j, + ), + d, + e, + f, + g, + h, + ) + }, + itpPrecRefiner = { a -> + XcfaPrecRefiner, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(a)) + ) + }, + initPrec = { x, ip -> ip.predPrec(x) }, + partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, + nodePruner = AtomicNodePruner>, XcfaAction>(), + stateType = TypeToken.get(PredState::class.java).type, + ), + PRED_CART( + abstractor = { a, b, c, d, e, f, g, h, i, j -> + getXcfaAbstractor( + PredXcfaAnalysis( + a, + b, + PredAbstractors.cartesianAbstractor(b), + i as PartialOrd>>, + j, + ), + d, + e, + f, + g, + h, + ) + }, + itpPrecRefiner = { a -> + XcfaPrecRefiner, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(a)) + ) + }, + initPrec = { x, ip -> ip.predPrec(x) }, + partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, + nodePruner = AtomicNodePruner>, XcfaAction>(), + stateType = TypeToken.get(PredState::class.java).type, + ), + PRED_SPLIT( + abstractor = { a, b, c, d, e, f, g, h, i, j -> + getXcfaAbstractor( + PredXcfaAnalysis( + a, + b, + PredAbstractors.booleanSplitAbstractor(b), + i as PartialOrd>>, + j, + ), + d, + e, + f, + g, + h, + ) + }, + itpPrecRefiner = { a -> + XcfaPrecRefiner, PredPrec, ItpRefutation>( + ItpRefToPtrPrec(ItpRefToPredPrec(a)) + ) + }, + initPrec = { x, ip -> ip.predPrec(x) }, + partialOrd = { solver -> PredOrd.create(solver).getPtrPartialOrd() }, + nodePruner = AtomicNodePruner>, XcfaAction>(), + stateType = TypeToken.get(PredState::class.java).type, + ), } enum class Refinement( - val refiner: (solverFactory: SolverFactory, monitorOption: CexMonitorOptions) -> ExprTraceChecker, - val stopCriterion: StopCriterion>, XcfaAction>, + val refiner: + (solverFactory: SolverFactory, monitorOption: CexMonitorOptions) -> ExprTraceChecker< + out Refutation + >, + val stopCriterion: StopCriterion>, XcfaAction>, ) { - FW_BIN_ITP( - refiner = { s, _ -> - ExprTraceFwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) - }, - stopCriterion = StopCriterions.firstCex(), - ), - BW_BIN_ITP( - refiner = { s, _ -> - ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) - }, - stopCriterion = StopCriterions.firstCex() - ), - SEQ_ITP( - refiner = { s, _ -> - ExprTraceSeqItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) - }, - stopCriterion = StopCriterions.firstCex() - ), - MULTI_SEQ( - refiner = { s, m -> - if (m == CexMonitorOptions.CHECK) error("CexMonitor is not implemented for MULTI_SEQ") - ExprTraceSeqItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) - }, - stopCriterion = StopCriterions.fullExploration() - ), - UNSAT_CORE( - refiner = { s, _ -> - ExprTraceUnsatCoreChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - }, - stopCriterion = StopCriterions.firstCex() - ), - UCB( - refiner = { s, _ -> - ExprTraceUCBChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - }, - stopCriterion = StopCriterions.firstCex() - ), - - NWT_SP( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withoutIT().withSP().withoutLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_WP( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withoutIT().withWP().withoutLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_SP_LV( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withoutIT().withSP().withLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_WP_LV( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withoutIT().withWP().withLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_IT_WP( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withIT().withWP().withoutLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_IT_SP( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withIT().withSP().withoutLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_IT_WP_LV( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withIT().withWP().withLV() - }, - stopCriterion = StopCriterions.firstCex() - ), - NWT_IT_SP_LV( - refiner = { s, _ -> - ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) - .withIT().withSP().withLV() - }, - stopCriterion = StopCriterions.firstCex() - ) + FW_BIN_ITP( + refiner = { s, _ -> + ExprTraceFwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) + }, + stopCriterion = StopCriterions.firstCex(), + ), + BW_BIN_ITP( + refiner = { s, _ -> + ExprTraceBwBinItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) + }, + stopCriterion = StopCriterions.firstCex(), + ), + SEQ_ITP( + refiner = { s, _ -> + ExprTraceSeqItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) + }, + stopCriterion = StopCriterions.firstCex(), + ), + MULTI_SEQ( + refiner = { s, m -> + if (m == CexMonitorOptions.CHECK) error("CexMonitor is not implemented for MULTI_SEQ") + ExprTraceSeqItpChecker.create(BoolExprs.True(), BoolExprs.True(), s.createItpSolver()) + }, + stopCriterion = StopCriterions.fullExploration(), + ), + UNSAT_CORE( + refiner = { s, _ -> + ExprTraceUnsatCoreChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + }, + stopCriterion = StopCriterions.firstCex(), + ), + UCB( + refiner = { s, _ -> + ExprTraceUCBChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_SP( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withoutIT() + .withSP() + .withoutLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_WP( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withoutIT() + .withWP() + .withoutLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_SP_LV( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withoutIT() + .withSP() + .withLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_WP_LV( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withoutIT() + .withWP() + .withLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_IT_WP( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withIT() + .withWP() + .withoutLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_IT_SP( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withIT() + .withSP() + .withoutLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_IT_WP_LV( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withIT() + .withWP() + .withLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), + NWT_IT_SP_LV( + refiner = { s, _ -> + ExprTraceNewtonChecker.create(BoolExprs.True(), BoolExprs.True(), s.createUCSolver()) + .withIT() + .withSP() + .withLV() + }, + stopCriterion = StopCriterions.firstCex(), + ), } - enum class ExprSplitterOptions(val exprSplitter: ExprSplitter) { - WHOLE(ExprSplitters.whole()), - CONJUNCTS(ExprSplitters.conjuncts()), - ATOMS(ExprSplitters.atoms()); + WHOLE(ExprSplitters.whole()), + CONJUNCTS(ExprSplitters.conjuncts()), + ATOMS(ExprSplitters.atoms()), } enum class Search { - BFS { + BFS { - override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.bfs()) - } - }, - DFS { + override fun getComp(cfa: XCFA): ArgNodeComparator { + return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.bfs()) + } + }, + DFS { - override fun getComp(cfa: XCFA): ArgNodeComparator { - return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), - ArgNodeComparators.dfs()) - } - }, - ERR { + override fun getComp(cfa: XCFA): ArgNodeComparator { + return ArgNodeComparators.combine(ArgNodeComparators.targetFirst(), ArgNodeComparators.dfs()) + } + }, + ERR { - override fun getComp(cfa: XCFA): ArgNodeComparator { - return XcfaDistToErrComparator(cfa) - } - }; + override fun getComp(cfa: XCFA): ArgNodeComparator { + return XcfaDistToErrComparator(cfa) + } + }; - abstract fun getComp(cfa: XCFA): ArgNodeComparator + abstract fun getComp(cfa: XCFA): ArgNodeComparator } enum class InitPrec( - val explPrec: (xcfa: XCFA) -> XcfaPrec>, - val predPrec: (xcfa: XCFA) -> XcfaPrec>, + val explPrec: (xcfa: XCFA) -> XcfaPrec>, + val predPrec: (xcfa: XCFA) -> XcfaPrec>, ) { - EMPTY( - explPrec = { XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet())) }, - predPrec = { XcfaPrec(PtrPrec(PredPrec.of(), emptySet())) } - ), - ALLVARS( - explPrec = { xcfa -> XcfaPrec(PtrPrec(ExplPrec.of(xcfa.collectVars()), emptySet())) }, - predPrec = { error("ALLVARS is not interpreted for the predicate domain.") } - ), - ALLGLOBALS( - explPrec = { xcfa -> XcfaPrec(PtrPrec(ExplPrec.of(xcfa.vars.map { it.wrappedVar }), emptySet())) }, - predPrec = { error("ALLGLOBALS is not interpreted for the predicate domain.") } - ), - ALLASSUMES( - explPrec = { xcfa -> - XcfaPrec( - PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet())) - }, - predPrec = { xcfa -> XcfaPrec(PtrPrec(PredPrec.of(xcfa.collectAssumes()), emptySet())) }, - ), - + EMPTY( + explPrec = { XcfaPrec(PtrPrec(ExplPrec.empty(), emptySet())) }, + predPrec = { XcfaPrec(PtrPrec(PredPrec.of(), emptySet())) }, + ), + ALLVARS( + explPrec = { xcfa -> XcfaPrec(PtrPrec(ExplPrec.of(xcfa.collectVars()), emptySet())) }, + predPrec = { error("ALLVARS is not interpreted for the predicate domain.") }, + ), + ALLGLOBALS( + explPrec = { xcfa -> + XcfaPrec(PtrPrec(ExplPrec.of(xcfa.vars.map { it.wrappedVar }), emptySet())) + }, + predPrec = { error("ALLGLOBALS is not interpreted for the predicate domain.") }, + ), + ALLASSUMES( + explPrec = { xcfa -> + XcfaPrec(PtrPrec(ExplPrec.of(xcfa.collectAssumes().flatMap(ExprUtils::getVars)), emptySet())) + }, + predPrec = { xcfa -> XcfaPrec(PtrPrec(PredPrec.of(xcfa.collectAssumes()), emptySet())) }, + ), } enum class ConeOfInfluenceMode( - val getLts: (XCFA, MutableMap, MutableSet>, POR) -> LTS>, XcfaAction> + val getLts: + (XCFA, MutableMap, MutableSet>, POR) -> LTS< + XcfaState>, + XcfaAction, + > ) { - NO_COI({ xcfa, ivr, por -> - por.getLts(xcfa, ivr).also { NO_COI.porLts = it } - }), - COI({ xcfa, ivr, por -> - ConeOfInfluence.coreLts = por.getLts(xcfa, ivr).also { COI.porLts = it } - ConeOfInfluence.lts - }), - POR_COI({ xcfa, ivr, por -> - ConeOfInfluence.coreLts = getXcfaLts() - if (por.isAbstractionAware) XcfaAasporCoiLts(xcfa, ivr, ConeOfInfluence.lts) - else XcfaSporCoiLts(xcfa, ConeOfInfluence.lts) - }), - POR_COI_POR({ xcfa, ivr, por -> - ConeOfInfluence.coreLts = por.getLts(xcfa, ivr).also { POR_COI_POR.porLts = it } - if (por.isAbstractionAware) XcfaAasporCoiLts(xcfa, ivr, ConeOfInfluence.lts) - else XcfaSporCoiLts(xcfa, ConeOfInfluence.lts) - }) - ; + NO_COI({ xcfa, ivr, por -> por.getLts(xcfa, ivr).also { NO_COI.porLts = it } }), + COI({ xcfa, ivr, por -> + ConeOfInfluence.coreLts = por.getLts(xcfa, ivr).also { COI.porLts = it } + ConeOfInfluence.lts + }), + POR_COI({ xcfa, ivr, por -> + ConeOfInfluence.coreLts = getXcfaLts() + if (por.isAbstractionAware) XcfaAasporCoiLts(xcfa, ivr, ConeOfInfluence.lts) + else XcfaSporCoiLts(xcfa, ConeOfInfluence.lts) + }), + POR_COI_POR({ xcfa, ivr, por -> + ConeOfInfluence.coreLts = por.getLts(xcfa, ivr).also { POR_COI_POR.porLts = it } + if (por.isAbstractionAware) XcfaAasporCoiLts(xcfa, ivr, ConeOfInfluence.lts) + else XcfaSporCoiLts(xcfa, ConeOfInfluence.lts) + }); - var porLts: LTS>, XcfaAction>? = null + var porLts: LTS>, XcfaAction>? = null } // TODO CexMonitor: disable for multi_seq // TODO add new monitor to xsts cli enum class CexMonitorOptions { - CHECK, - DISABLE + CHECK, + DISABLE, } diff --git a/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/config/XstsConfigBuilder.java b/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/config/XstsConfigBuilder.java index 35b38b2a27..016d828fcb 100644 --- a/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/config/XstsConfigBuilder.java +++ b/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/config/XstsConfigBuilder.java @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.analysis.config; +import static com.google.common.base.Preconditions.checkState; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; + import hu.bme.mit.theta.analysis.*; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarChecker; -import hu.bme.mit.theta.analysis.algorithm.cegar.Refiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterion; import hu.bme.mit.theta.analysis.algorithm.cegar.abstractor.StopCriterions; import hu.bme.mit.theta.analysis.expl.*; @@ -60,16 +62,12 @@ import hu.bme.mit.theta.xsts.analysis.initprec.*; import hu.bme.mit.theta.xsts.analysis.util.XstsCombineExtractUtilsKt; import hu.bme.mit.theta.xsts.analysis.util.XstsControlInitFuncKt; - import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Function; import java.util.function.Predicate; -import static com.google.common.base.Preconditions.checkState; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; - public class XstsConfigBuilder { //////////// CEGAR configuration //////////// @@ -94,20 +92,26 @@ public enum Domain { public enum Refinement { FW_BIN_ITP { @Override - public ExprTraceChecker getItpExprTraceChecker(Expr init, Expr target, ItpSolver solver) { + public ExprTraceChecker getItpExprTraceChecker( + Expr init, Expr target, ItpSolver solver) { return ExprTraceFwBinItpChecker.create(init, target, solver); } - }, BW_BIN_ITP { + }, + BW_BIN_ITP { @Override - public ExprTraceChecker getItpExprTraceChecker(Expr init, Expr target, ItpSolver solver) { + public ExprTraceChecker getItpExprTraceChecker( + Expr init, Expr target, ItpSolver solver) { return ExprTraceBwBinItpChecker.create(init, target, solver); } - }, SEQ_ITP { + }, + SEQ_ITP { @Override - public ExprTraceChecker getItpExprTraceChecker(Expr init, Expr target, ItpSolver solver) { + public ExprTraceChecker getItpExprTraceChecker( + Expr init, Expr target, ItpSolver solver) { return ExprTraceSeqItpChecker.create(init, target, solver); } - }, UNSAT_CORE, + }, + UNSAT_CORE, MULTI_SEQ { @Override public StopCriterion getStopCriterion() { @@ -115,19 +119,20 @@ public StopCriterion getStopCriterion() { } @Override - public ExprTraceChecker getItpExprTraceChecker(Expr init, Expr target, ItpSolver solver) { + public ExprTraceChecker getItpExprTraceChecker( + Expr init, Expr target, ItpSolver solver) { return ExprTraceSeqItpChecker.create(init, target, solver); } @Override - public Refiner, XstsAction, P> - createRefiner( - ExprTraceChecker traceChecker, - RefutationToPrec refToPrec, - PruneStrategy pruneStrategy, - Logger logger - ) { - return MultiExprTraceRefiner.create(traceChecker, JoiningPrecRefiner.create(refToPrec), pruneStrategy, logger); + public + ArgRefiner, XstsAction, P> createRefiner( + ExprTraceChecker traceChecker, + RefutationToPrec refToPrec, + PruneStrategy pruneStrategy, + Logger logger) { + return MultiExprTraceRefiner.create( + traceChecker, JoiningPrecRefiner.create(refToPrec), pruneStrategy, logger); } }; @@ -136,23 +141,22 @@ public StopCriterion getStopCriterion() { } public ExprTraceChecker getItpExprTraceChecker( - final Expr init, - final Expr target, - final ItpSolver solver - ) { - throw new UnsupportedOperationException(String.format("%s domain can't provide trace checker of ItpRefutation", this.getClass().getSimpleName())); + final Expr init, final Expr target, final ItpSolver solver) { + throw new UnsupportedOperationException( + String.format( + "%s domain can't provide trace checker of ItpRefutation", + this.getClass().getSimpleName())); + } + + public + ArgRefiner, XstsAction, P> createRefiner( + ExprTraceChecker traceChecker, + RefutationToPrec refToPrec, + PruneStrategy pruneStrategy, + Logger logger) { + return SingleExprTraceRefiner.create( + traceChecker, JoiningPrecRefiner.create(refToPrec), pruneStrategy, logger); } - - public Refiner, XstsAction, P> - createRefiner( - ExprTraceChecker traceChecker, - RefutationToPrec refToPrec, - PruneStrategy pruneStrategy, - Logger logger - ) { - return SingleExprTraceRefiner.create(traceChecker, JoiningPrecRefiner.create(refToPrec), pruneStrategy, logger); - } - } public enum Search { @@ -165,7 +169,6 @@ public enum Search { Search(final ArgNodeComparators.ArgNodeComparator comparator) { this.comparator = comparator; } - } public enum PredSplit { @@ -196,7 +199,6 @@ public enum InitPrec { InitPrec(final XstsInitPrec builder) { this.builder = builder; } - } public enum AutoExpl { @@ -214,7 +216,8 @@ public enum AutoExpl { } public enum OptimizeStmts { - ON, OFF + ON, + OFF } private Logger logger = NullLogger.getInstance(); @@ -230,8 +233,11 @@ public enum OptimizeStmts { private OptimizeStmts optimizeStmts = OptimizeStmts.ON; private AutoExpl autoExpl = AutoExpl.NEWOPERANDS; - public XstsConfigBuilder(final Domain domain, final Refinement refinement, - final SolverFactory abstractionSolverFactory, final SolverFactory refinementSolverFactory) { + public XstsConfigBuilder( + final Domain domain, + final Refinement refinement, + final SolverFactory abstractionSolverFactory, + final SolverFactory refinementSolverFactory) { this.domain = domain; this.refinement = refinement; this.abstractionSolverFactory = abstractionSolverFactory; @@ -282,12 +288,15 @@ public XstsConfigBuilder autoExpl(final AutoExpl autoExpl) { if (domain == Domain.EXPL) { return (new ExplStrategy(xsts)).buildConfig(); } - if (domain == Domain.PRED_BOOL || domain == Domain.PRED_CART + if (domain == Domain.PRED_BOOL + || domain == Domain.PRED_CART || domain == Domain.PRED_SPLIT) { return (new PredStrategy(xsts)).buildConfig(); } - if (domain == Domain.EXPL_PRED_BOOL || domain == Domain.EXPL_PRED_CART - || domain == Domain.EXPL_PRED_SPLIT || domain == Domain.EXPL_PRED_COMBINED) { + if (domain == Domain.EXPL_PRED_BOOL + || domain == Domain.EXPL_PRED_CART + || domain == Domain.EXPL_PRED_SPLIT + || domain == Domain.EXPL_PRED_COMBINED) { return (new ProdStrategy(xsts)).buildConfig(); } throw new UnsupportedOperationException(domain + " domain is not supported."); @@ -295,15 +304,26 @@ public XstsConfigBuilder autoExpl(final AutoExpl autoExpl) { public abstract class BuilderStrategy { - protected static final String UNSUPPORTED_CONFIG_VALUE = "Builder strategy %s does not support configuration value %s as %s"; + protected static final String UNSUPPORTED_CONFIG_VALUE = + "Builder strategy %s does not support configuration value %s as %s"; protected final XSTS xsts; protected final Solver abstractionSolver; protected final Expr negProp; @SuppressWarnings("java:S1699") protected BuilderStrategy(XSTS xsts) { - checkState(getSupportedDomains().contains(domain), UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), domain, "domain"); - checkState(getSupportedRefinements().contains(refinement), UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), refinement, "refinement"); + checkState( + getSupportedDomains().contains(domain), + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + domain, + "domain"); + checkState( + getSupportedRefinements().contains(refinement), + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + refinement, + "refinement"); this.xsts = xsts; abstractionSolver = abstractionSolverFactory.createSolver(); negProp = Not(xsts.getProp()); @@ -336,7 +356,7 @@ public XstsAnalysis getAnalysis() { public abstract RefutationToPrec getItpRefToPrec(); - public Refiner, XstsAction, P> getRefiner() { + public ArgRefiner, XstsAction, P> getRefiner() { return refinement.createRefiner( refinement.getItpExprTraceChecker( xsts.getInitFormula(), @@ -353,22 +373,22 @@ XstsConfig, XstsAction, P> buildConfig() { final LTS, XstsAction> lts = getLts(); final Predicate> target = getPredicate(); final Analysis, XstsAction, P> analysis = getAnalysis(); - final ArgBuilder, XstsAction, P> argBuilder = ArgBuilder.create( - lts, analysis, target, - true); - final Abstractor, XstsAction, P> abstractor = BasicAbstractor.builder( - argBuilder) - .waitlist(PriorityWaitlist.create(search.comparator)) - .stopCriterion(refinement.getStopCriterion()) - .logger(logger).build(); - final Refiner, XstsAction, P> refiner = getRefiner(); - final SafetyChecker, XstsAction>, Trace, XstsAction>, P> checker = CegarChecker.create( - abstractor, refiner, - logger); + final ArgBuilder, XstsAction, P> argBuilder = + ArgBuilder.create(lts, analysis, target, true); + final ArgAbstractor, XstsAction, P> abstractor = + BasicArgAbstractor.builder(argBuilder) + .waitlist(PriorityWaitlist.create(search.comparator)) + .stopCriterion(refinement.getStopCriterion()) + .logger(logger) + .build(); + final ArgRefiner, XstsAction, P> refiner = getRefiner(); + final SafetyChecker, XstsAction>, Trace, XstsAction>, P> + checker = ArgCegarChecker.create(abstractor, refiner, logger); return XstsConfig.create(checker, getInitPrec()); } - public MultiAnalysisSide, S, XstsState, XstsAction, P, UnitPrec> getMultiSide() { + public MultiAnalysisSide, S, XstsState, XstsAction, P, UnitPrec> + getMultiSide() { return new MultiAnalysisSide<>( getAnalysis(), XstsControlInitFuncKt.xstsControlInitFunc(), @@ -377,7 +397,6 @@ public MultiAnalysisSide, S, XstsState, XstsAction, P, U XstsCombineExtractUtilsKt::xstsExtractDataState, XstsCombineExtractUtilsKt::xstsExtractControlPrec); } - } public class ExplStrategy extends BuilderStrategy { @@ -394,8 +413,12 @@ Set getSupportedRefinements() { public ExplStrategy(XSTS xsts) { super(xsts); - checkState(domain == Domain.EXPL, - UNSUPPORTED_CONFIG_VALUE, this.getClass().getSimpleName(), domain, "domain"); + checkState( + domain == Domain.EXPL, + UNSUPPORTED_CONFIG_VALUE, + this.getClass().getSimpleName(), + domain, + "domain"); } @Override @@ -419,12 +442,16 @@ public RefutationToPrec getItpRefToPrec() { } @Override - public Refiner, XstsAction, ExplPrec> getRefiner() { + public ArgRefiner, XstsAction, ExplPrec> getRefiner() { if (refinement == Refinement.UNSAT_CORE) { return SingleExprTraceRefiner.create( - ExprTraceUnsatCoreChecker.create(xsts.getInitFormula(), negProp, + ExprTraceUnsatCoreChecker.create( + xsts.getInitFormula(), + negProp, refinementSolverFactory.createUCSolver()), - JoiningPrecRefiner.create(new VarsRefToExplPrec()), pruneStrategy, logger); + JoiningPrecRefiner.create(new VarsRefToExplPrec()), + pruneStrategy, + logger); } return super.getRefiner(); } @@ -433,7 +460,6 @@ public Refiner, XstsAction, ExplPrec> getRefiner() { public ExplPrec getInitPrec() { return initPrec.builder.createExpl(xsts); } - } public class PredStrategy extends BuilderStrategy { @@ -444,13 +470,24 @@ Set getSupportedDomains() { @Override Set getSupportedRefinements() { - return new HashSet<>(List.of(Refinement.FW_BIN_ITP, Refinement.BW_BIN_ITP, Refinement.SEQ_ITP, Refinement.MULTI_SEQ)); + return new HashSet<>( + List.of( + Refinement.FW_BIN_ITP, + Refinement.BW_BIN_ITP, + Refinement.SEQ_ITP, + Refinement.MULTI_SEQ)); } public PredStrategy(XSTS xsts) { super(xsts); - checkState(domain == Domain.PRED_BOOL || domain == Domain.PRED_SPLIT || domain == Domain.PRED_CART, - UNSUPPORTED_CONFIG_VALUE, this.getClass().getSimpleName(), domain, "domain"); + checkState( + domain == Domain.PRED_BOOL + || domain == Domain.PRED_SPLIT + || domain == Domain.PRED_CART, + UNSUPPORTED_CONFIG_VALUE, + this.getClass().getSimpleName(), + domain, + "domain"); } @Override @@ -482,55 +519,80 @@ public PredPrec getInitPrec() { } } - public class ProdStrategy extends BuilderStrategy, Prod2Prec> { + public class ProdStrategy + extends BuilderStrategy< + Prod2State, Prod2Prec> { @Override Set getSupportedDomains() { - return new HashSet<>(List.of(Domain.EXPL_PRED_BOOL, Domain.EXPL_PRED_CART, Domain.EXPL_PRED_SPLIT, Domain.EXPL_PRED_COMBINED)); + return new HashSet<>( + List.of( + Domain.EXPL_PRED_BOOL, + Domain.EXPL_PRED_CART, + Domain.EXPL_PRED_SPLIT, + Domain.EXPL_PRED_COMBINED)); } @Override Set getSupportedRefinements() { - return new HashSet<>(List.of(Refinement.FW_BIN_ITP, Refinement.BW_BIN_ITP, Refinement.SEQ_ITP, Refinement.MULTI_SEQ)); + return new HashSet<>( + List.of( + Refinement.FW_BIN_ITP, + Refinement.BW_BIN_ITP, + Refinement.SEQ_ITP, + Refinement.MULTI_SEQ)); } public ProdStrategy(XSTS xsts) { super(xsts); - checkState(domain == Domain.EXPL_PRED_BOOL || domain == Domain.EXPL_PRED_SPLIT - || domain == Domain.EXPL_PRED_CART || domain == Domain.EXPL_PRED_COMBINED, - UNSUPPORTED_CONFIG_VALUE, this.getClass().getSimpleName(), domain, "domain"); - checkState(refinement != Refinement.UNSAT_CORE, UNSUPPORTED_CONFIG_VALUE, getClass().getSimpleName(), refinement, "refinement"); + checkState( + domain == Domain.EXPL_PRED_BOOL + || domain == Domain.EXPL_PRED_SPLIT + || domain == Domain.EXPL_PRED_CART + || domain == Domain.EXPL_PRED_COMBINED, + UNSUPPORTED_CONFIG_VALUE, + this.getClass().getSimpleName(), + domain, + "domain"); + checkState( + refinement != Refinement.UNSAT_CORE, + UNSUPPORTED_CONFIG_VALUE, + getClass().getSimpleName(), + refinement, + "refinement"); } @Override StmtOptimizer> getLtsOptimizer() { - return Prod2ExplPredStmtOptimizer.create( - ExplStmtOptimizer.getInstance() - ); + return Prod2ExplPredStmtOptimizer.create(ExplStmtOptimizer.getInstance()); } @Override public Predicate>> getPredicate() { - return new XstsStatePredicate<>( - new ExprStatePredicate(negProp, abstractionSolver)); + return new XstsStatePredicate<>(new ExprStatePredicate(negProp, abstractionSolver)); } @Override - public Analysis, StmtAction, Prod2Prec> getDataAnalysis() { - if (domain == Domain.EXPL_PRED_BOOL || domain == Domain.EXPL_PRED_CART + public Analysis, StmtAction, Prod2Prec> + getDataAnalysis() { + if (domain == Domain.EXPL_PRED_BOOL + || domain == Domain.EXPL_PRED_CART || domain == Domain.EXPL_PRED_SPLIT) { - final PredAbstractors.PredAbstractor predAbstractor = domain.predAbstractorFunction.apply(abstractionSolver); + final PredAbstractors.PredAbstractor predAbstractor = + domain.predAbstractorFunction.apply(abstractionSolver); return Prod2Analysis.create( ExplStmtAnalysis.create(abstractionSolver, xsts.getInitFormula(), maxEnum), - PredAnalysis.create(abstractionSolver, predAbstractor, xsts.getInitFormula()), + PredAnalysis.create( + abstractionSolver, predAbstractor, xsts.getInitFormula()), Prod2ExplPredPreStrengtheningOperator.create(), Prod2ExplPredStrengtheningOperator.create(abstractionSolver)); } else { - final Prod2ExplPredAbstractors.Prod2ExplPredAbstractor prodAbstractor = Prod2ExplPredAbstractors.booleanAbstractor( - abstractionSolver); + final Prod2ExplPredAbstractors.Prod2ExplPredAbstractor prodAbstractor = + Prod2ExplPredAbstractors.booleanAbstractor(abstractionSolver); return Prod2ExplPredAnalysis.create( ExplAnalysis.create(abstractionSolver, xsts.getInitFormula()), - PredAnalysis.create(abstractionSolver, + PredAnalysis.create( + abstractionSolver, PredAbstractors.booleanAbstractor(abstractionSolver), xsts.getInitFormula()), Prod2ExplPredStrengtheningOperator.create(abstractionSolver), @@ -548,7 +610,5 @@ public RefutationToPrec, ItpRefutation> getItpRefT public Prod2Prec getInitPrec() { return initPrec.builder.createProd2ExplPred(xsts); } - } - -} \ No newline at end of file +} diff --git a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java index 592abd7ad5..6bbc845a97 100644 --- a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java +++ b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java @@ -31,8 +31,8 @@ import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.unit.UnitAnalysis; import hu.bme.mit.theta.analysis.unit.UnitPrec; import hu.bme.mit.theta.analysis.unit.UnitState; @@ -79,11 +79,11 @@ public void test() throws FileNotFoundException, IOException { lts, analysis, s -> false); - final Abstractor, XtaAction, UnitPrec> abstractor = BasicAbstractor.builder( + final ArgAbstractor, XtaAction, UnitPrec> abstractor = BasicArgAbstractor.builder( argBuilder) .projection(s -> s.getLocs()).build(); - final ARG, XtaAction> arg = abstractor.createArg(); + final ARG, XtaAction> arg = abstractor.createWitness(); abstractor.check(arg, UnitPrec.getInstance()); System.out.println( diff --git a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java index 437049b128..111e451934 100644 --- a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java +++ b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java @@ -32,8 +32,8 @@ import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; -import hu.bme.mit.theta.analysis.algorithm.cegar.Abstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.expl.ExplState; import hu.bme.mit.theta.analysis.impl.PrecMappingAnalysis; import hu.bme.mit.theta.analysis.prod2.Prod2Analysis; @@ -91,10 +91,10 @@ public void test() throws FileNotFoundException, IOException { final ArgBuilder>, XtaAction, ZonePrec> argBuilder = ArgBuilder .create(lts, analysis, s -> false); - final Abstractor>, XtaAction, ZonePrec> abstractor = BasicAbstractor + final ArgAbstractor>, XtaAction, ZonePrec> abstractor = BasicArgAbstractor .builder(argBuilder).projection(s -> s.getLocs()).build(); - final ARG>, XtaAction> arg = abstractor.createArg(); + final ARG>, XtaAction> arg = abstractor.createWitness(); abstractor.check(arg, prec); System.out.println(arg.getNodes().collect(Collectors.toSet())); From ad7ff95d0e7afadb9921bb67b903c095dc213582 Mon Sep 17 00:00:00 2001 From: RipplB Date: Sat, 12 Oct 2024 08:33:57 +0200 Subject: [PATCH 39/40] Rename Witness to Proof --- .../impact/CfaPredImpactCheckerTest.java | 45 +- .../java/hu/bme/mit/theta/cfa/cli/CfaCli.java | 217 +++--- .../mit/theta/analysis/algorithm/Checker.java | 5 +- .../{EmptyWitness.java => EmptyProof.java} | 10 +- .../algorithm/{Witness.java => Proof.java} | 3 +- .../mit/theta/analysis/algorithm/Result.java | 5 +- .../analysis/algorithm/SafetyChecker.java | 12 +- .../analysis/algorithm/SafetyResult.java | 85 +-- .../mit/theta/analysis/algorithm/arg/ARG.java | 74 +-- .../algorithm/bounded/BoundedChecker.kt | 405 ++++++------ .../analysis/algorithm/cegar/Abstractor.java | 21 +- .../algorithm/cegar/BasicArgAbstractor.java | 47 +- .../algorithm/cegar/CegarChecker.java | 50 +- .../analysis/algorithm/cegar/Refiner.java | 6 +- .../analysis/algorithm/chc/HornChecker.kt | 83 +-- .../mcm/analysis/FiniteStateChecker.kt | 91 ++- .../analysis/algorithm/mdd/MddChecker.java | 163 +++-- .../mdd/{MddWitness.java => MddProof.java} | 10 +- .../theta/analysis/utils/ArgVisualizer.java | 97 ++- ...ssVisualizer.java => ProofVisualizer.java} | 8 +- .../algorithm/mdd/MddCheckerTest.java | 159 +++-- .../theta/grammar/gson/SafetyResultAdapter.kt | 114 ++-- .../mit/theta/sts/analysis/StsExplTest.java | 85 ++- .../theta/sts/analysis/StsMddCheckerTest.java | 93 ++- .../mit/theta/sts/analysis/StsPredTest.java | 89 ++- .../java/hu/bme/mit/theta/sts/cli/StsCli.java | 187 ++++-- .../theta/xcfa/analysis/oc/XcfaOcChecker.kt | 615 +++++++++--------- .../bme/mit/theta/xcfa/cli/ExecuteConfig.kt | 588 +++++++++-------- .../cli/checkers/ConfigToBoundedChecker.kt | 63 +- .../xcfa/cli/checkers/ConfigToCegarChecker.kt | 214 +++--- .../xcfa/cli/checkers/ConfigToHornChecker.kt | 52 +- .../xcfa/cli/checkers/ConfigToOcChecker.kt | 30 +- .../xcfa/cli/checkers/InProcessChecker.kt | 250 +++---- .../mit/theta/xcfa/cli/XcfaCliProofTest.kt | 136 ++++ .../mit/theta/xcfa/cli/XcfaCliWitnessTest.kt | 130 ---- .../xsts/analysis/mdd/XstsMddChecker.java | 157 +++-- .../xsts/analysis/XstsMddCheckerTest.java | 215 +++--- .../bme/mit/theta/xsts/cli/XstsCliBounded.kt | 168 +++-- .../hu/bme/mit/theta/xsts/cli/XstsCliCegar.kt | 144 ++-- .../hu/bme/mit/theta/xsts/cli/XstsCliMdd.kt | 98 ++- .../xta/analysis/LazyXtaCheckerTest.java | 60 +- .../theta/xta/analysis/XtaAnalysisTest.java | 67 +- .../xta/analysis/XtaZoneAnalysisTest.java | 75 +-- .../java/hu/bme/mit/theta/xta/cli/XtaCli.java | 77 ++- 44 files changed, 2904 insertions(+), 2399 deletions(-) rename subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/{EmptyWitness.java => EmptyProof.java} (78%) rename subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/{Witness.java => Proof.java} (95%) rename subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/{MddWitness.java => MddProof.java} (81%) rename subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/{WitnessVisualizer.java => ProofVisualizer.java} (83%) create mode 100644 subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt delete mode 100644 subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt diff --git a/subprojects/cfa/cfa-analysis/src/test/java/hu/bme/mit/theta/cfa/analysis/impact/CfaPredImpactCheckerTest.java b/subprojects/cfa/cfa-analysis/src/test/java/hu/bme/mit/theta/cfa/analysis/impact/CfaPredImpactCheckerTest.java index 4204a3785d..111600967f 100644 --- a/subprojects/cfa/cfa-analysis/src/test/java/hu/bme/mit/theta/cfa/analysis/impact/CfaPredImpactCheckerTest.java +++ b/subprojects/cfa/cfa-analysis/src/test/java/hu/bme/mit/theta/cfa/analysis/impact/CfaPredImpactCheckerTest.java @@ -17,60 +17,65 @@ import static org.junit.Assert.assertTrue; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; - import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.algorithm.SafetyResult; -import hu.bme.mit.theta.analysis.pred.PredState; -import hu.bme.mit.theta.cfa.analysis.CfaAction; -import hu.bme.mit.theta.cfa.analysis.CfaState; -import hu.bme.mit.theta.solver.Solver; -import org.junit.Test; - import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgChecker; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; +import hu.bme.mit.theta.analysis.pred.PredState; import hu.bme.mit.theta.analysis.unit.UnitPrec; import hu.bme.mit.theta.analysis.utils.ArgVisualizer; import hu.bme.mit.theta.cfa.CFA; +import hu.bme.mit.theta.cfa.analysis.CfaAction; +import hu.bme.mit.theta.cfa.analysis.CfaState; import hu.bme.mit.theta.cfa.analysis.lts.CfaLbeLts; import hu.bme.mit.theta.cfa.dsl.CfaDslManager; import hu.bme.mit.theta.common.visualization.writer.GraphvizWriter; import hu.bme.mit.theta.solver.ItpSolver; +import hu.bme.mit.theta.solver.Solver; import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import org.junit.Test; public final class CfaPredImpactCheckerTest { @Test public void test() throws FileNotFoundException, IOException { // Arrange - final CFA cfa = CfaDslManager.createCfa( - new FileInputStream("src/test/resources/counter5_true.cfa")); + final CFA cfa = + CfaDslManager.createCfa( + new FileInputStream("src/test/resources/counter5_true.cfa")); final Solver abstractionSolver = Z3LegacySolverFactory.getInstance().createSolver(); final ItpSolver refinementSolver = Z3LegacySolverFactory.getInstance().createItpSolver(); - final PredImpactChecker checker = PredImpactChecker.create( - CfaLbeLts.of(cfa.getErrorLoc().get()), cfa.getInitLoc(), - l -> l.equals(cfa.getErrorLoc().get()), abstractionSolver, refinementSolver); + final PredImpactChecker checker = + PredImpactChecker.create( + CfaLbeLts.of(cfa.getErrorLoc().get()), + cfa.getInitLoc(), + l -> l.equals(cfa.getErrorLoc().get()), + abstractionSolver, + refinementSolver); // Act - final SafetyResult, CfaAction>, Trace, CfaAction>> status = checker.check( - UnitPrec.getInstance()); + final SafetyResult< + ARG, CfaAction>, Trace, CfaAction>> + status = checker.check(UnitPrec.getInstance()); // Assert assertTrue(status.isSafe()); - final ARG arg = status.getWitness(); + final ARG arg = status.getProof(); arg.minimize(); final ArgChecker argChecker = ArgChecker.create(abstractionSolver); assertTrue(argChecker.isWellLabeled(arg)); System.out.println( - GraphvizWriter.getInstance().writeString(ArgVisualizer.getDefault().visualize(arg))); + GraphvizWriter.getInstance() + .writeString(ArgVisualizer.getDefault().visualize(arg))); } -} \ No newline at end of file +} diff --git a/subprojects/cfa/cfa-cli/src/main/java/hu/bme/mit/theta/cfa/cli/CfaCli.java b/subprojects/cfa/cfa-cli/src/main/java/hu/bme/mit/theta/cfa/cli/CfaCli.java index 024911743e..eda6c15702 100644 --- a/subprojects/cfa/cfa-cli/src/main/java/hu/bme/mit/theta/cfa/cli/CfaCli.java +++ b/subprojects/cfa/cfa-cli/src/main/java/hu/bme/mit/theta/cfa/cli/CfaCli.java @@ -15,6 +15,8 @@ */ package hu.bme.mit.theta.cfa.cli; +import static com.google.common.base.Preconditions.checkNotNull; + import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; @@ -27,8 +29,6 @@ import hu.bme.mit.theta.analysis.algorithm.bounded.MonolithicExpr; import hu.bme.mit.theta.analysis.algorithm.cegar.CegarStatistics; import hu.bme.mit.theta.analysis.expl.ExplState; -import hu.bme.mit.theta.analysis.expr.ExprAction; -import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.analysis.expr.refinement.PruneStrategy; import hu.bme.mit.theta.cfa.CFA; import hu.bme.mit.theta.cfa.analysis.CfaAction; @@ -37,14 +37,7 @@ import hu.bme.mit.theta.cfa.analysis.CfaTraceConcretizer; import hu.bme.mit.theta.cfa.analysis.config.CfaConfig; import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.Algorithm; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.Domain; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.Encoding; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.InitPrec; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.PrecGranularity; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.PredSplit; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.Refinement; -import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.Search; +import hu.bme.mit.theta.cfa.analysis.config.CfaConfigBuilder.*; import hu.bme.mit.theta.cfa.analysis.utils.CfaVisualizer; import hu.bme.mit.theta.cfa.dsl.CfaDslManager; import hu.bme.mit.theta.common.CliUtils; @@ -62,28 +55,21 @@ import hu.bme.mit.theta.solver.smtlib.SmtLibSolverManager; import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; import hu.bme.mit.theta.solver.z3legacy.Z3SolverManager; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.nio.file.Path; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * A command line interface for running a CEGAR configuration on a CFA. - */ +/** A command line interface for running a CEGAR configuration on a CFA. */ public class CfaCli { private static final String JAR_NAME = "theta-cfa-cli.jar"; private final String[] args; private final TableWriter writer; - @Parameter(names = {"--algorithm"}, description = "Algorithm") + + @Parameter( + names = {"--algorithm"}, + description = "Algorithm") Algorithm algorithm = Algorithm.CEGAR; @Parameter(names = "--domain", description = "Abstract domain") @@ -95,16 +81,34 @@ public class CfaCli { @Parameter(names = "--search", description = "Search strategy") Search search = Search.BFS; - @Parameter(names = "--predsplit", description = "Predicate splitting (for predicate abstraction)") + @Parameter( + names = "--predsplit", + description = "Predicate splitting (for predicate abstraction)") PredSplit predSplit = PredSplit.WHOLE; - @Parameter(names = "--solver", description = "Sets the underlying SMT solver to use for both the abstraction and the refinement process. Enter in format :, see theta-smtlib-cli.jar for more details. Enter \"Z3\" to use the legacy z3 solver.") + @Parameter( + names = "--solver", + description = + "Sets the underlying SMT solver to use for both the abstraction and the" + + " refinement process. Enter in format :, see" + + " theta-smtlib-cli.jar for more details. Enter \"Z3\" to use the legacy" + + " z3 solver.") String solver = "Z3"; - @Parameter(names = "--abstraction-solver", description = "Sets the underlying SMT solver to use for the abstraction process. Enter in format :, see theta-smtlib-cli.jar for more details. Enter \"Z3\" to use the legacy z3 solver.") + @Parameter( + names = "--abstraction-solver", + description = + "Sets the underlying SMT solver to use for the abstraction process. Enter in" + + " format :, see theta-smtlib-cli.jar for" + + " more details. Enter \"Z3\" to use the legacy z3 solver.") String abstractionSolver; - @Parameter(names = "--refinement-solver", description = "Sets the underlying SMT solver to use for the refinement process. Enter in format :, see theta-smtlib-cli.jar for more details. Enter \"Z3\" to use the legacy z3 solver.") + @Parameter( + names = "--refinement-solver", + description = + "Sets the underlying SMT solver to use for the refinement process. Enter in" + + " format :, see theta-smtlib-cli.jar for" + + " more details. Enter \"Z3\" to use the legacy z3 solver.") String refinementSolver; @Parameter(names = "--home", description = "The path of the solver registry") @@ -122,13 +126,17 @@ public class CfaCli { @Parameter(names = "--encoding", description = "Block encoding") Encoding encoding = Encoding.LBE; - @Parameter(names = "--maxenum", description = "Maximal number of explicitly enumerated successors (0: unlimited)") + @Parameter( + names = "--maxenum", + description = "Maximal number of explicitly enumerated successors (0: unlimited)") Integer maxEnum = 10; @Parameter(names = "--initprec", description = "Initial precision of abstraction") InitPrec initPrec = InitPrec.EMPTY; - @Parameter(names = "--prunestrategy", description = "Strategy for pruning the ARG after refinement") + @Parameter( + names = "--prunestrategy", + description = "Strategy for pruning the ARG after refinement") PruneStrategy pruneStrategy = PruneStrategy.LAZY; @Parameter(names = "--loglevel", description = "Detailedness of logging") @@ -140,13 +148,20 @@ public class CfaCli { @Parameter(names = "--cex", description = "Write concrete counterexample to a file") String cexfile = null; - @Parameter(names = "--header", description = "Print only a header (for benchmarks)", help = true) + @Parameter( + names = "--header", + description = "Print only a header (for benchmarks)", + help = true) boolean headerOnly = false; - @Parameter(names = "--visualize", description = "Visualize CFA to this file without running the algorithm") + @Parameter( + names = "--visualize", + description = "Visualize CFA to this file without running the algorithm") String visualize = null; - @Parameter(names = "--metrics", description = "Print metrics about the CFA without running the algorithm") + @Parameter( + names = "--metrics", + description = "Print metrics about the CFA without running the algorithm") boolean metrics = false; @Parameter(names = "--stacktrace", description = "Print full stack trace in case of exception") @@ -241,13 +256,19 @@ private void run() { final SafetyResult> status; if (algorithm == Algorithm.CEGAR) { - final CfaConfig configuration = buildConfiguration(cfa, errLoc, abstractionSolverFactory, refinementSolverFactory); + final CfaConfig configuration = + buildConfiguration( + cfa, errLoc, abstractionSolverFactory, refinementSolverFactory); status = check(configuration); - } else if (algorithm == Algorithm.BMC || algorithm == Algorithm.KINDUCTION || algorithm == Algorithm.IMC) { - final BoundedChecker checker = buildBoundedChecker(cfa, abstractionSolverFactory); + } else if (algorithm == Algorithm.BMC + || algorithm == Algorithm.KINDUCTION + || algorithm == Algorithm.IMC) { + final BoundedChecker checker = + buildBoundedChecker(cfa, abstractionSolverFactory); status = checker.check(null); } else { - throw new UnsupportedOperationException("Algorithm " + algorithm + " not supported"); + throw new UnsupportedOperationException( + "Algorithm " + algorithm + " not supported"); } sw.stop(); @@ -262,8 +283,18 @@ private void run() { } private void printHeader() { - Stream.of("Result", "TimeMs", "AlgoTimeMs", "AbsTimeMs", "RefTimeMs", "Iterations", - "ArgSize", "ArgDepth", "ArgMeanBranchFactor", "CexLen").forEach(writer::cell); + Stream.of( + "Result", + "TimeMs", + "AlgoTimeMs", + "AbsTimeMs", + "RefTimeMs", + "Iterations", + "ArgSize", + "ArgDepth", + "ArgMeanBranchFactor", + "CexLen") + .forEach(writer::cell); writer.newRow(); } @@ -277,67 +308,89 @@ private CFA loadModel() throws Exception { } } - private CfaConfig buildConfiguration(final CFA cfa, final CFA.Loc errLoc, - final SolverFactory abstractionSolverFactory, final SolverFactory refinementSolverFactory) + private CfaConfig buildConfiguration( + final CFA cfa, + final CFA.Loc errLoc, + final SolverFactory abstractionSolverFactory, + final SolverFactory refinementSolverFactory) throws Exception { try { - return new CfaConfigBuilder(domain, refinement, abstractionSolverFactory, - refinementSolverFactory) - .precGranularity(precGranularity).search(search) - .predSplit(predSplit).encoding(encoding).maxEnum(maxEnum).initPrec(initPrec) - .pruneStrategy(pruneStrategy).logger(logger).build(cfa, errLoc); + return new CfaConfigBuilder( + domain, refinement, abstractionSolverFactory, refinementSolverFactory) + .precGranularity(precGranularity) + .search(search) + .predSplit(predSplit) + .encoding(encoding) + .maxEnum(maxEnum) + .initPrec(initPrec) + .pruneStrategy(pruneStrategy) + .logger(logger) + .build(cfa, errLoc); } catch (final Exception ex) { throw new Exception("Could not create configuration: " + ex.getMessage(), ex); } } - private BoundedChecker buildBoundedChecker(final CFA cfa, final SolverFactory abstractionSolverFactory) { + private BoundedChecker buildBoundedChecker( + final CFA cfa, final SolverFactory abstractionSolverFactory) { final MonolithicExpr monolithicExpr = CfaToMonolithicExprKt.toMonolithicExpr(cfa); final BoundedChecker checker; switch (algorithm) { - case BMC -> checker = BoundedCheckerBuilderKt.buildBMC( - monolithicExpr, - abstractionSolverFactory.createSolver(), - val -> CfaToMonolithicExprKt.valToState(cfa, val), - (val1, val2) -> CfaToMonolithicExprKt.valToAction(cfa, val1, val2), - logger - ); - case KINDUCTION -> checker = BoundedCheckerBuilderKt.buildKIND( - monolithicExpr, - abstractionSolverFactory.createSolver(), - abstractionSolverFactory.createSolver(), - val -> CfaToMonolithicExprKt.valToState(cfa, val), - (val1, val2) -> CfaToMonolithicExprKt.valToAction(cfa, val1, val2), - logger - ); - case IMC -> checker = BoundedCheckerBuilderKt.buildIMC( - monolithicExpr, - abstractionSolverFactory.createSolver(), - abstractionSolverFactory.createItpSolver(), - val -> CfaToMonolithicExprKt.valToState(cfa, val), - (val1, val2) -> CfaToMonolithicExprKt.valToAction(cfa, val1, val2), - logger - ); + case BMC -> + checker = + BoundedCheckerBuilderKt.buildBMC( + monolithicExpr, + abstractionSolverFactory.createSolver(), + val -> CfaToMonolithicExprKt.valToState(cfa, val), + (val1, val2) -> + CfaToMonolithicExprKt.valToAction(cfa, val1, val2), + logger); + case KINDUCTION -> + checker = + BoundedCheckerBuilderKt.buildKIND( + monolithicExpr, + abstractionSolverFactory.createSolver(), + abstractionSolverFactory.createSolver(), + val -> CfaToMonolithicExprKt.valToState(cfa, val), + (val1, val2) -> + CfaToMonolithicExprKt.valToAction(cfa, val1, val2), + logger); + case IMC -> + checker = + BoundedCheckerBuilderKt.buildIMC( + monolithicExpr, + abstractionSolverFactory.createSolver(), + abstractionSolverFactory.createItpSolver(), + val -> CfaToMonolithicExprKt.valToState(cfa, val), + (val1, val2) -> + CfaToMonolithicExprKt.valToAction(cfa, val1, val2), + logger); default -> - throw new UnsupportedOperationException("Algorithm " + algorithm + " not supported"); + throw new UnsupportedOperationException( + "Algorithm " + algorithm + " not supported"); } return checker; } - private SafetyResult, ? extends Trace> check(CfaConfig configuration) throws Exception { + private SafetyResult, ? extends Trace> check( + CfaConfig configuration) throws Exception { try { return configuration.check(); } catch (final Exception ex) { String message = ex.getMessage() == null ? "(no message)" : ex.getMessage(); throw new Exception( - "Error while running algorithm: " + ex.getClass().getSimpleName() + " " + message, + "Error while running algorithm: " + + ex.getClass().getSimpleName() + + " " + + message, ex); } } - private void printResult(final SafetyResult> status, final long totalTimeMs) { - final CegarStatistics stats = (CegarStatistics) - status.getStats().orElse(new CegarStatistics(0, 0, 0, 0)); + private void printResult( + final SafetyResult> status, final long totalTimeMs) { + final CegarStatistics stats = + (CegarStatistics) status.getStats().orElse(new CegarStatistics(0, 0, 0, 0)); if (benchmarkMode) { writer.cell(status.isSafe()); writer.cell(totalTimeMs); @@ -345,7 +398,7 @@ private void printResult(final SafetyResult> status, fi writer.cell(stats.getAbstractorTimeMs()); writer.cell(stats.getRefinerTimeMs()); writer.cell(stats.getIterations()); - if (status.getWitness() instanceof ARG arg) { + if (status.getProof() instanceof ARG arg) { writer.cell(arg.size()); writer.cell(arg.getDepth()); writer.cell(arg.getMeanBranchingFactor()); @@ -369,7 +422,10 @@ private void printError(final Throwable ex) { writer.cell("[EX] " + ex.getClass().getSimpleName() + ": " + message); writer.newRow(); } else { - logger.write(Level.RESULT, "%s occurred, message: %s%n", ex.getClass().getSimpleName(), + logger.write( + Level.RESULT, + "%s occurred, message: %s%n", + ex.getClass().getSimpleName(), message); if (stacktrace) { final StringWriter errors = new StringWriter(); @@ -382,9 +438,10 @@ private void printError(final Throwable ex) { } private void writeCex(final SafetyResult.Unsafe status) throws FileNotFoundException { - @SuppressWarnings("unchecked") final Trace, CfaAction> trace = (Trace, CfaAction>) status.getCex(); - final Trace, CfaAction> concrTrace = CfaTraceConcretizer.concretize( - trace, Z3LegacySolverFactory.getInstance()); + @SuppressWarnings("unchecked") + final Trace, CfaAction> trace = (Trace, CfaAction>) status.getCex(); + final Trace, CfaAction> concrTrace = + CfaTraceConcretizer.concretize(trace, Z3LegacySolverFactory.getInstance()); final File file = new File(cexfile); PrintWriter printWriter = null; try { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Checker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Checker.java index e1a86bee69..afed36eab9 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Checker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Checker.java @@ -15,8 +15,7 @@ */ package hu.bme.mit.theta.analysis.algorithm; -public interface Checker { - - Result check(I input); +public interface Checker { + Result check(I input); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyWitness.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyProof.java similarity index 78% rename from subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyWitness.java rename to subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyProof.java index 49794dd84e..1c8d976149 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyWitness.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/EmptyProof.java @@ -15,15 +15,13 @@ */ package hu.bme.mit.theta.analysis.algorithm; -public class EmptyWitness implements Witness { +public class EmptyProof implements Proof { - private final static EmptyWitness empty = new EmptyWitness(); + private static final EmptyProof empty = new EmptyProof(); - private EmptyWitness() { - } + private EmptyProof() {} - public static EmptyWitness getInstance() { + public static EmptyProof getInstance() { return empty; } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Witness.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Proof.java similarity index 95% rename from subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Witness.java rename to subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Proof.java index ff6157e1e3..3668ab6315 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Witness.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Proof.java @@ -15,5 +15,4 @@ */ package hu.bme.mit.theta.analysis.algorithm; -public interface Witness { -} +public interface Proof {} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Result.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Result.java index 0c81bf5836..438edde295 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Result.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/Result.java @@ -17,10 +17,9 @@ import java.util.Optional; -public interface Result { +public interface Result { - W getWitness(); + Pr getProof(); Optional getStats(); - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyChecker.java index 4f13fac64c..c716c1dc24 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyChecker.java @@ -15,19 +15,15 @@ */ package hu.bme.mit.theta.analysis.algorithm; -import hu.bme.mit.theta.analysis.*; -import hu.bme.mit.theta.analysis.algorithm.Checker; -import hu.bme.mit.theta.analysis.algorithm.SafetyResult; -import hu.bme.mit.theta.analysis.algorithm.arg.ARG; +import hu.bme.mit.theta.analysis.Cex; @FunctionalInterface -public interface SafetyChecker extends Checker { +public interface SafetyChecker extends Checker { @Override - SafetyResult check(final I input); + SafetyResult check(final I input); - default SafetyResult check() { + default SafetyResult check() { return check(null); } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyResult.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyResult.java index dfd812ebea..0862dc3079 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyResult.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/SafetyResult.java @@ -15,30 +15,29 @@ */ package hu.bme.mit.theta.analysis.algorithm; +import static com.google.common.base.Preconditions.checkNotNull; + import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.common.Utils; - import java.util.Optional; -import static com.google.common.base.Preconditions.checkNotNull; - -public abstract class SafetyResult implements Result { - private final W witness; +public abstract class SafetyResult implements Result { + private final Pr proof; private final Optional stats; - private SafetyResult(final W witness, final Optional stats) { - this.witness = checkNotNull(witness); + private SafetyResult(final Pr proof, final Optional stats) { + this.proof = checkNotNull(proof); this.stats = checkNotNull(stats); } private SafetyResult() { - this.witness = null; + this.proof = null; this.stats = Optional.empty(); } @Override - public W getWitness() { - return witness; + public Pr getProof() { + return proof; } @Override @@ -46,28 +45,30 @@ public Optional getStats() { return stats; } - public static Safe safe(final W witness) { + public static Safe safe(final Pr witness) { return new Safe<>(witness, Optional.empty()); } - public static Unsafe unsafe(final C cex, final W witness) { + public static Unsafe unsafe( + final C cex, final Pr witness) { return new Unsafe<>(cex, witness, Optional.empty()); } - public static Unknown unknown() { + public static Unknown unknown() { return new Unknown<>(); } - public static Safe safe(final W witness, final Statistics stats) { + public static Safe safe( + final Pr witness, final Statistics stats) { return new Safe<>(witness, Optional.of(stats)); } - public static Unsafe unsafe(final C cex, final W witness, - final Statistics stats) { + public static Unsafe unsafe( + final C cex, final Pr witness, final Statistics stats) { return new Unsafe<>(cex, witness, Optional.of(stats)); } - public static Unknown unknown(final Statistics stats) { + public static Unknown unknown(final Statistics stats) { return new Unknown<>(Optional.of(stats)); } @@ -75,15 +76,15 @@ public static Unknown unknown(final Sta public abstract boolean isUnsafe(); - public abstract Safe asSafe(); + public abstract Safe asSafe(); - public abstract Unsafe asUnsafe(); + public abstract Unsafe asUnsafe(); //// - public static final class Safe extends SafetyResult { - private Safe(final W witness, final Optional stats) { - super(witness, stats); + public static final class Safe extends SafetyResult { + private Safe(final Pr proof, final Optional stats) { + super(proof, stats); } @Override @@ -97,28 +98,32 @@ public boolean isUnsafe() { } @Override - public Safe asSafe() { + public Safe asSafe() { return this; } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { throw new ClassCastException( - "Cannot cast " + Safe.class.getSimpleName() + " to " + Unsafe.class.getSimpleName()); + "Cannot cast " + + Safe.class.getSimpleName() + + " to " + + Unsafe.class.getSimpleName()); } @Override public String toString() { - return Utils.lispStringBuilder(SafetyResult.class.getSimpleName()).add(Safe.class.getSimpleName()) + return Utils.lispStringBuilder(SafetyResult.class.getSimpleName()) + .add(Safe.class.getSimpleName()) .toString(); } } - public static final class Unsafe extends SafetyResult { + public static final class Unsafe extends SafetyResult { private final C cex; - private Unsafe(final C cex, final W witness, final Optional stats) { - super(witness, stats); + private Unsafe(final C cex, final Pr proof, final Optional stats) { + super(proof, stats); this.cex = checkNotNull(cex); } @@ -137,24 +142,29 @@ public boolean isUnsafe() { } @Override - public Safe asSafe() { + public Safe asSafe() { throw new ClassCastException( - "Cannot cast " + Unsafe.class.getSimpleName() + " to " + Safe.class.getSimpleName()); + "Cannot cast " + + Unsafe.class.getSimpleName() + + " to " + + Safe.class.getSimpleName()); } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { return this; } @Override public String toString() { - return Utils.lispStringBuilder(SafetyResult.class.getSimpleName()).add(Unsafe.class.getSimpleName()) - .add("Trace length: " + cex.length()).toString(); + return Utils.lispStringBuilder(SafetyResult.class.getSimpleName()) + .add(Unsafe.class.getSimpleName()) + .add("Trace length: " + cex.length()) + .toString(); } } - public static final class Unknown extends SafetyResult { + public static final class Unknown extends SafetyResult { public Unknown() { super(); @@ -175,12 +185,12 @@ public boolean isUnsafe() { } @Override - public Safe asSafe() { + public Safe asSafe() { return null; } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { return null; } @@ -191,5 +201,4 @@ public String toString() { .toString(); } } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/arg/ARG.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/arg/ARG.java index b43fb37e35..9f2b3c3ae0 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/arg/ARG.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/arg/ARG.java @@ -15,28 +15,22 @@ */ package hu.bme.mit.theta.analysis.algorithm.arg; +import static com.google.common.base.Preconditions.*; +import static java.util.stream.Collectors.toList; + import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.PartialOrd; import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.analysis.algorithm.Proof; import hu.bme.mit.theta.analysis.algorithm.arg.debug.ARGWebDebugger; import hu.bme.mit.theta.common.container.Containers; - import java.util.Collection; import java.util.Optional; import java.util.OptionalInt; import java.util.stream.Stream; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; -import static java.util.stream.Collectors.toList; - -/** - * Represents an abstract reachability graph (ARG). See the related class - * ArgBuilder. - */ -public final class ARG implements Witness { +/** Represents an abstract reachability graph (ARG). See the related class ArgBuilder. */ +public final class ARG implements Proof { private final Collection> initNodes; public boolean initialized; // Set by ArgBuilder @@ -49,7 +43,8 @@ private ARG(final PartialOrd partialOrd) { this.initialized = false; } - public static ARG create(final PartialOrd partialOrd) { + public static ARG create( + final PartialOrd partialOrd) { return new ARG<>(partialOrd); } @@ -75,7 +70,6 @@ public Stream> getIncompleteNodes() { return getInitNodes().flatMap(ArgNode::unexcludedDescendants).filter(n -> !n.isExpanded()); } - PartialOrd getPartialOrd() { return partialOrd; } @@ -83,24 +77,19 @@ PartialOrd getPartialOrd() { //// /** - * Checks if the ARG is complete, i.e., whether it is initialized and all of - * its nodes are complete. + * Checks if the ARG is complete, i.e., whether it is initialized and all of its nodes are + * complete. */ public boolean isComplete() { return isInitialized() && getNodes().allMatch(ArgNode::isComplete); } - /** - * Checks if the ARG is safe, i.e., whether all of its nodes are safe. - */ + /** Checks if the ARG is safe, i.e., whether all of its nodes are safe. */ public boolean isSafe() { return getNodes().allMatch(ArgNode::isSafe); } - /** - * Checks if the ARG is initialized, i.e., all of its initial nodes are - * present. - */ + /** Checks if the ARG is initialized, i.e., all of its initial nodes are present. */ public boolean isInitialized() { return initialized; } @@ -115,8 +104,8 @@ public ArgNode createInitNode(final S initState, final boolean target) { return initNode; } - public ArgNode createSuccNode(final ArgNode node, final A action, final S succState, - final boolean target) { + public ArgNode createSuccNode( + final ArgNode node, final A action, final S succState, final boolean target) { checkNotNull(node); checkNotNull(action); checkNotNull(succState); @@ -133,7 +122,8 @@ private ArgNode createNode(final S state, final int depth, final boolean t return node; } - private ArgEdge createEdge(final ArgNode source, final A action, final ArgNode target) { + private ArgEdge createEdge( + final ArgNode source, final A action, final ArgNode target) { final ArgEdge edge = new ArgEdge<>(source, action, target); source.outEdges.add(edge); target.inEdge = Optional.of(edge); @@ -141,9 +131,7 @@ private ArgEdge createEdge(final ArgNode source, final A action, fin return edge; } - /** - * Removes a node along with its subtree. - */ + /** Removes a node along with its subtree. */ public void prune(final ArgNode node) { checkNotNull(node); checkArgument(node.arg == this, "Node does not belong to this ARG"); @@ -162,17 +150,13 @@ public void prune(final ArgNode node) { node.descendants().forEach(ArgNode::clearCoveredNodes); } - /** - * Prune the whole ARG, making it uninitialized. - */ + /** Prune the whole ARG, making it uninitialized. */ public void pruneAll() { initNodes.clear(); this.initialized = false; } - /** - * Marks the node for reexpanding without pruning it. - */ + /** Marks the node for reexpanding without pruning it. */ public void markForReExpansion(final ArgNode node) { node.expanded = false; } @@ -192,24 +176,19 @@ private void minimizeSubTree(final ArgNode node) { //// - /** - * Gets all counterexamples, i.e., traces leading to target nodes. - */ + /** Gets all counterexamples, i.e., traces leading to target nodes. */ public Stream> getCexs() { return getUnsafeNodes().map(ArgTrace::to); } - /** - * Gets the size of the ARG, i.e., the number of nodes. - */ + /** Gets the size of the ARG, i.e., the number of nodes. */ public long size() { return getNodes().count(); } /** - * Gets the depth of the ARG, i.e., the maximal depth of its nodes. Depth - * starts (at the initial nodes) from 0. Depth is undefined for an empty - * ARG. + * Gets the depth of the ARG, i.e., the maximal depth of its nodes. Depth starts (at the initial + * nodes) from 0. Depth is undefined for an empty ARG. */ public int getDepth() { final OptionalInt maxOpt = getNodes().mapToInt(ArgNode::getDepth).max(); @@ -217,12 +196,11 @@ public int getDepth() { return maxOpt.getAsInt(); } - /** - * Gets the mean branching factor of the expanded nodes. - */ + /** Gets the mean branching factor of the expanded nodes. */ public double getMeanBranchingFactor() { final Stream> nodesToCalculate = getNodes().filter(ArgNode::isExpanded); - final double mean = nodesToCalculate.mapToDouble(n -> n.getOutEdges().count()).average().orElse(0); + final double mean = + nodesToCalculate.mapToDouble(n -> n.getOutEdges().count()).average().orElse(0); return mean; } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedChecker.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedChecker.kt index 72b90fe53f..2c1273f87f 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedChecker.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/bounded/BoundedChecker.kt @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.analysis.algorithm.bounded import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.expr.ExprAction @@ -43,228 +42,246 @@ import java.util.* * @param The state type, must inherit from ExprState. * @param The action type, must inherit from StmtAction. * @param monolithicExpr The monolithic expression to be checked - * @param shouldGiveUp A function determining whether to give up checking based on a given iteration count. Use this - * to implement custom timeout or thread interruption checking subroutines. + * @param shouldGiveUp A function determining whether to give up checking based on a given iteration + * count. Use this to implement custom timeout or thread interruption checking subroutines. * @param bmcSolver The solver for bounded model checking. - * @param bmcEnabled A function determining whether bounded model checking is enabled. Cannot be disabled per-iteration. - * Use the capabilities of the lambda parameter to decide on enabledness based on external factors, - * such as available memory or time limit remaining. + * @param bmcEnabled A function determining whether bounded model checking is enabled. Cannot be + * disabled per-iteration. Use the capabilities of the lambda parameter to decide on enabledness + * based on external factors, such as available memory or time limit remaining. * @param lfPathOnly A function determining whether to consider only loop-free paths. * @param itpSolver The solver for interpolation, used in IMC. * @param imcEnabled A function determining whether IMC is enabled. Can be different per-iteration. * @param indSolver The solver for induction checking in KIND. * @param kindEnabled A function determining whether k-induction (KIND) is enabled. - * @param valToState A function mapping valuations to expression states, used to construct a counterexample. - * @param biValToAction A function mapping pairs of valuations to statements, used to construct a counterexample. + * @param valToState A function mapping valuations to expression states, used to construct a + * counterexample. + * @param biValToAction A function mapping pairs of valuations to statements, used to construct a + * counterexample. * @param logger The logger for logging. */ -class BoundedChecker @JvmOverloads constructor( - private val monolithicExpr: MonolithicExpr, - private val shouldGiveUp: (Int) -> Boolean = { false }, - private val bmcSolver: Solver? = null, - private val bmcEnabled: () -> Boolean = { bmcSolver != null }, - private val lfPathOnly: () -> Boolean = { true }, - private val itpSolver: ItpSolver? = null, - private val imcEnabled: (Int) -> Boolean = { itpSolver != null }, - private val indSolver: Solver? = null, - private val kindEnabled: (Int) -> Boolean = { indSolver != null }, - private val valToState: (Valuation) -> S, - private val biValToAction: (Valuation, Valuation) -> A, - private val logger: Logger, -) : SafetyChecker, UnitPrec> { - - private val vars = monolithicExpr.vars() - private val unfoldedInitExpr = PathUtils.unfold(monolithicExpr.initExpr, VarIndexingFactory.indexing(0)) - private val unfoldedPropExpr = { i: VarIndexing -> PathUtils.unfold(monolithicExpr.propExpr, i) } - private val indices = mutableListOf(monolithicExpr.initOffsetIndex) - private val exprs = mutableListOf>() - private var kindLastIterLookup = 0 - private var iteration = 0 - - init { - check(bmcSolver != itpSolver || bmcSolver == null) { "Use distinct solvers for BMC and IMC!" } - check(bmcSolver != indSolver || bmcSolver == null) { "Use distinct solvers for BMC and KInd!" } - check(itpSolver != indSolver || itpSolver == null) { "Use distinct solvers for IMC and KInd!" } - } - - override fun check(prec: UnitPrec?): SafetyResult> { - - iteration = 0 - - val isBmcEnabled = bmcEnabled() // we don't allow per-iteration setting of bmc enabledness - bmcSolver?.add(unfoldedInitExpr) - - while (!shouldGiveUp(iteration)) { - iteration++ - logger.write(Logger.Level.MAINSTEP, "Starting iteration $iteration\n") - - exprs.add(PathUtils.unfold(monolithicExpr.transExpr, indices.last())) - - indices.add(indices.last().add(monolithicExpr.transOffsetIndex)) - - if (isBmcEnabled) { - bmc()?.let { return it } - } +class BoundedChecker +@JvmOverloads +constructor( + private val monolithicExpr: MonolithicExpr, + private val shouldGiveUp: (Int) -> Boolean = { false }, + private val bmcSolver: Solver? = null, + private val bmcEnabled: () -> Boolean = { bmcSolver != null }, + private val lfPathOnly: () -> Boolean = { true }, + private val itpSolver: ItpSolver? = null, + private val imcEnabled: (Int) -> Boolean = { itpSolver != null }, + private val indSolver: Solver? = null, + private val kindEnabled: (Int) -> Boolean = { indSolver != null }, + private val valToState: (Valuation) -> S, + private val biValToAction: (Valuation, Valuation) -> A, + private val logger: Logger, +) : SafetyChecker, UnitPrec> { + + private val vars = monolithicExpr.vars() + private val unfoldedInitExpr = + PathUtils.unfold(monolithicExpr.initExpr, VarIndexingFactory.indexing(0)) + private val unfoldedPropExpr = { i: VarIndexing -> PathUtils.unfold(monolithicExpr.propExpr, i) } + private val indices = mutableListOf(monolithicExpr.initOffsetIndex) + private val exprs = mutableListOf>() + private var kindLastIterLookup = 0 + private var iteration = 0 + + init { + check(bmcSolver != itpSolver || bmcSolver == null) { "Use distinct solvers for BMC and IMC!" } + check(bmcSolver != indSolver || bmcSolver == null) { "Use distinct solvers for BMC and KInd!" } + check(itpSolver != indSolver || itpSolver == null) { "Use distinct solvers for IMC and KInd!" } + } + + override fun check(prec: UnitPrec?): SafetyResult> { + + iteration = 0 + + val isBmcEnabled = bmcEnabled() // we don't allow per-iteration setting of bmc enabledness + bmcSolver?.add(unfoldedInitExpr) + + while (!shouldGiveUp(iteration)) { + iteration++ + logger.write(Logger.Level.MAINSTEP, "Starting iteration $iteration\n") + + exprs.add(PathUtils.unfold(monolithicExpr.transExpr, indices.last())) + + indices.add(indices.last().add(monolithicExpr.transOffsetIndex)) + + if (isBmcEnabled) { + bmc()?.let { + return it + } + } - if (kindEnabled(iteration)) { - if (!isBmcEnabled) { - error("Bad configuration: induction check should always be preceded by a BMC/SAT check") - } - kind()?.let { return it } - kindLastIterLookup = iteration - } + if (kindEnabled(iteration)) { + if (!isBmcEnabled) { + error("Bad configuration: induction check should always be preceded by a BMC/SAT check") + } + kind()?.let { + return it + } + kindLastIterLookup = iteration + } - if (imcEnabled(iteration)) { - itp()?.let { return it } - } + if (imcEnabled(iteration)) { + itp()?.let { + return it } - return SafetyResult.unknown(BoundedStatistics(iteration)) + } } - - private fun bmc(): SafetyResult>? { - val bmcSolver = this.bmcSolver!! - logger.write(Logger.Level.MAINSTEP, "\tStarting BMC\n") - - bmcSolver.add(exprs.last()) - - if (lfPathOnly()) { // indices contains currIndex as last() - for (indexing in indices) { - if (indexing != indices.last()) { - val allVarsSame = And(vars.map { - Eq(PathUtils.unfold(it.ref, indexing), PathUtils.unfold(it.ref, indices.last())) - }) - bmcSolver.add(Not(allVarsSame)) - } - } - - if (bmcSolver.check().isUnsat) { - logger.write(Logger.Level.MAINSTEP, "Safety proven in BMC step\n") - return SafetyResult.safe(EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } + return SafetyResult.unknown(BoundedStatistics(iteration)) + } + + private fun bmc(): SafetyResult>? { + val bmcSolver = this.bmcSolver!! + logger.write(Logger.Level.MAINSTEP, "\tStarting BMC\n") + + bmcSolver.add(exprs.last()) + + if (lfPathOnly()) { // indices contains currIndex as last() + for (indexing in indices) { + if (indexing != indices.last()) { + val allVarsSame = + And( + vars.map { + Eq(PathUtils.unfold(it.ref, indexing), PathUtils.unfold(it.ref, indices.last())) + } + ) + bmcSolver.add(Not(allVarsSame)) } + } - return WithPushPop(bmcSolver).use { - bmcSolver.add(Not(unfoldedPropExpr(indices.last()))) - - if (bmcSolver.check().isSat) { - val trace = getTrace(bmcSolver.model) - logger.write(Logger.Level.MAINSTEP, "CeX found in BMC step (length ${trace.length()})\n") - SafetyResult.unsafe(trace, EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } else null - } + if (bmcSolver.check().isUnsat) { + logger.write(Logger.Level.MAINSTEP, "Safety proven in BMC step\n") + return SafetyResult.safe(EmptyProof.getInstance(), BoundedStatistics(iteration)) + } } - private fun kind(): SafetyResult>? { - val indSolver = this.indSolver!! + return WithPushPop(bmcSolver).use { + bmcSolver.add(Not(unfoldedPropExpr(indices.last()))) - logger.write(Logger.Level.MAINSTEP, "\tStarting k-induction\n") + if (bmcSolver.check().isSat) { + val trace = getTrace(bmcSolver.model) + logger.write(Logger.Level.MAINSTEP, "CeX found in BMC step (length ${trace.length()})\n") + SafetyResult.unsafe(trace, EmptyProof.getInstance(), BoundedStatistics(iteration)) + } else null + } + } - exprs.subList(kindLastIterLookup, exprs.size).forEach { indSolver.add(it) } - indices.subList(kindLastIterLookup, indices.size - 1).forEach { indSolver.add(unfoldedPropExpr(it)) } + private fun kind(): SafetyResult>? { + val indSolver = this.indSolver!! - return WithPushPop(indSolver).use { - indSolver.add(Not(unfoldedPropExpr(indices.last()))) + logger.write(Logger.Level.MAINSTEP, "\tStarting k-induction\n") - if (indSolver.check().isUnsat) { - logger.write(Logger.Level.MAINSTEP, "Safety proven in k-induction step\n") - SafetyResult.safe(EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } else null - } + exprs.subList(kindLastIterLookup, exprs.size).forEach { indSolver.add(it) } + indices.subList(kindLastIterLookup, indices.size - 1).forEach { + indSolver.add(unfoldedPropExpr(it)) } - private fun itp(): SafetyResult>? { - val itpSolver = this.itpSolver!! - logger.write(Logger.Level.MAINSTEP, "\tStarting IMC\n") - - itpSolver.push() - - val a = itpSolver.createMarker() - val b = itpSolver.createMarker() - val pattern = itpSolver.createBinPattern(a, b) - - itpSolver.push() - - itpSolver.add(a, unfoldedInitExpr) - itpSolver.add(a, exprs[0]) - itpSolver.add(b, exprs.subList(1, exprs.size)) - - if (lfPathOnly()) { // indices contains currIndex as last() - itpSolver.push() - for (indexing in indices) { - if (indexing != indices.last()) { - val allVarsSame = And(vars.map { - Eq(PathUtils.unfold(it.ref, indexing), PathUtils.unfold(it.ref, indices.last())) - }) - itpSolver.add(a, Not(allVarsSame)) - } - } - - if (itpSolver.check().isUnsat) { - itpSolver.pop() - itpSolver.pop() - logger.write(Logger.Level.MAINSTEP, "Safety proven in IMC/BMC step\n") - return SafetyResult.safe(EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } - itpSolver.pop() + return WithPushPop(indSolver).use { + indSolver.add(Not(unfoldedPropExpr(indices.last()))) + + if (indSolver.check().isUnsat) { + logger.write(Logger.Level.MAINSTEP, "Safety proven in k-induction step\n") + SafetyResult.safe(EmptyProof.getInstance(), BoundedStatistics(iteration)) + } else null + } + } + + private fun itp(): SafetyResult>? { + val itpSolver = this.itpSolver!! + logger.write(Logger.Level.MAINSTEP, "\tStarting IMC\n") + + itpSolver.push() + + val a = itpSolver.createMarker() + val b = itpSolver.createMarker() + val pattern = itpSolver.createBinPattern(a, b) + + itpSolver.push() + + itpSolver.add(a, unfoldedInitExpr) + itpSolver.add(a, exprs[0]) + itpSolver.add(b, exprs.subList(1, exprs.size)) + + if (lfPathOnly()) { // indices contains currIndex as last() + itpSolver.push() + for (indexing in indices) { + if (indexing != indices.last()) { + val allVarsSame = + And( + vars.map { + Eq(PathUtils.unfold(it.ref, indexing), PathUtils.unfold(it.ref, indices.last())) + } + ) + itpSolver.add(a, Not(allVarsSame)) } + } - itpSolver.add(b, Not(unfoldedPropExpr(indices.last()))) + if (itpSolver.check().isUnsat) { + itpSolver.pop() + itpSolver.pop() + logger.write(Logger.Level.MAINSTEP, "Safety proven in IMC/BMC step\n") + return SafetyResult.safe(EmptyProof.getInstance(), BoundedStatistics(iteration)) + } + itpSolver.pop() + } - val status = itpSolver.check() + itpSolver.add(b, Not(unfoldedPropExpr(indices.last()))) - if (status.isSat) { - val trace = getTrace(itpSolver.model) - logger.write(Logger.Level.MAINSTEP, "CeX found in IMC/BMC step (length ${trace.length()})\n") - itpSolver.pop() - itpSolver.pop() - return SafetyResult.unsafe(trace, EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } + val status = itpSolver.check() - var img = unfoldedInitExpr - while (itpSolver.check().isUnsat) { - val interpolant = itpSolver.getInterpolant(pattern) - val itpFormula = PathUtils.unfold(PathUtils.foldin(interpolant.eval(a), indices[1]), indices[0]) - itpSolver.pop() - - itpSolver.push() - itpSolver.add(a, itpFormula) - itpSolver.add(a, Not(img)) - val itpStatus = itpSolver.check() - if (itpStatus.isUnsat) { - logger.write(Logger.Level.MAINSTEP, "Safety proven in IMC step\n") - itpSolver.pop() - itpSolver.pop() - return SafetyResult.safe(EmptyWitness.getInstance(), BoundedStatistics(iteration)) - } - itpSolver.pop() - img = Or(img, itpFormula) - - itpSolver.push() - itpSolver.add(a, itpFormula) - itpSolver.add(a, exprs[0]) - itpSolver.add(b, exprs.subList(1, exprs.size)) - itpSolver.add(b, Not(unfoldedPropExpr(indices.last()))) - } + if (status.isSat) { + val trace = getTrace(itpSolver.model) + logger.write(Logger.Level.MAINSTEP, "CeX found in IMC/BMC step (length ${trace.length()})\n") + itpSolver.pop() + itpSolver.pop() + return SafetyResult.unsafe(trace, EmptyProof.getInstance(), BoundedStatistics(iteration)) + } + var img = unfoldedInitExpr + while (itpSolver.check().isUnsat) { + val interpolant = itpSolver.getInterpolant(pattern) + val itpFormula = + PathUtils.unfold(PathUtils.foldin(interpolant.eval(a), indices[1]), indices[0]) + itpSolver.pop() + + itpSolver.push() + itpSolver.add(a, itpFormula) + itpSolver.add(a, Not(img)) + val itpStatus = itpSolver.check() + if (itpStatus.isUnsat) { + logger.write(Logger.Level.MAINSTEP, "Safety proven in IMC step\n") itpSolver.pop() itpSolver.pop() - return null + return SafetyResult.safe(EmptyProof.getInstance(), BoundedStatistics(iteration)) + } + itpSolver.pop() + img = Or(img, itpFormula) + + itpSolver.push() + itpSolver.add(a, itpFormula) + itpSolver.add(a, exprs[0]) + itpSolver.add(b, exprs.subList(1, exprs.size)) + itpSolver.add(b, Not(unfoldedPropExpr(indices.last()))) } - - private fun getTrace(model: Valuation): Trace { - val stateList = LinkedList() - val actionList = LinkedList() - var lastValuation: Valuation? = null - for (i in indices) { - val valuation = PathUtils.extractValuation(model, i, vars) - stateList.add(valToState(valuation)) - if (lastValuation != null) { - actionList.add(biValToAction(lastValuation, valuation)) - } - lastValuation = valuation - } - return Trace.of(stateList, actionList) + itpSolver.pop() + itpSolver.pop() + return null + } + + private fun getTrace(model: Valuation): Trace { + val stateList = LinkedList() + val actionList = LinkedList() + var lastValuation: Valuation? = null + for (i in indices) { + val valuation = PathUtils.extractValuation(model, i, vars) + stateList.add(valToState(valuation)) + if (lastValuation != null) { + actionList.add(biValToAction(lastValuation, valuation)) + } + lastValuation = valuation } - -} \ No newline at end of file + return Trace.of(stateList, actionList) + } +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java index a6cb49bb43..d4601d334e 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Abstractor.java @@ -16,22 +16,17 @@ package hu.bme.mit.theta.analysis.algorithm.cegar; import hu.bme.mit.theta.analysis.Prec; -import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.analysis.algorithm.Proof; /** - * Common interface for the abstractor component. It can create an initial witness and check a witness with - * a given precision. + * Common interface for the abstractor component. It can create an initial witness and check a + * witness with a given precision. */ -public interface Abstractor

{ +public interface Abstractor

{ - /** - * Create initial witness - */ - W createWitness(); - - /** - * Check witness with given precision - */ - AbstractorResult check(W witness, P prec); + /** Create initial witness */ + Pr createProof(); + /** Check witness with given precision */ + AbstractorResult check(Pr witness, P prec); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java index 050ae32ce3..a92dbedfc2 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/BasicArgAbstractor.java @@ -15,6 +15,9 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.Preconditions.checkState; + import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; @@ -30,18 +33,13 @@ import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.common.logging.NullLogger; - import java.util.Collection; import java.util.Collections; import java.util.function.Function; -import static com.google.common.base.Preconditions.checkNotNull; -import static com.google.common.base.Preconditions.checkState; - -/** - * Basic implementation for the abstractor, relying on an ArgBuilder. - */ -public class BasicArgAbstractor implements ArgAbstractor { +/** Basic implementation for the abstractor, relying on an ArgBuilder. */ +public class BasicArgAbstractor + implements ArgAbstractor { protected final ArgBuilder argBuilder; protected final Function projection; @@ -49,8 +47,12 @@ public class BasicArgAbstractor stopCriterion; protected final Logger logger; - protected BasicArgAbstractor(final ArgBuilder argBuilder, final Function projection, - final Waitlist> waitlist, final StopCriterion stopCriterion, final Logger logger) { + protected BasicArgAbstractor( + final ArgBuilder argBuilder, + final Function projection, + final Waitlist> waitlist, + final StopCriterion stopCriterion, + final Logger logger) { this.argBuilder = checkNotNull(argBuilder); this.projection = checkNotNull(projection); this.waitlist = checkNotNull(waitlist); @@ -64,7 +66,7 @@ public static Builder createWitness() { + public ARG createProof() { return argBuilder.createArg(); } @@ -82,11 +84,16 @@ public AbstractorResult check(final ARG arg, final P prec) { assert arg.isInitialized(); - logger.write(Level.INFO, "| | Starting ARG: %d nodes, %d incomplete, %d unsafe%n", arg.getNodes().count(), - arg.getIncompleteNodes().count(), arg.getUnsafeNodes().count()); + logger.write( + Level.INFO, + "| | Starting ARG: %d nodes, %d incomplete, %d unsafe%n", + arg.getNodes().count(), + arg.getIncompleteNodes().count(), + arg.getUnsafeNodes().count()); logger.write(Level.SUBSTEP, "| | Building ARG..."); - final Partition, ?> reachedSet = Partition.of(n -> projection.apply(n.getState())); + final Partition, ?> reachedSet = + Partition.of(n -> projection.apply(n.getState())); waitlist.clear(); reachedSet.addAll(arg.getNodes()); @@ -109,8 +116,12 @@ public AbstractorResult check(final ARG arg, final P prec) { } logger.write(Level.SUBSTEP, "done%n"); - logger.write(Level.INFO, "| | Finished ARG: %d nodes, %d incomplete, %d unsafe%n", arg.getNodes().count(), - arg.getIncompleteNodes().count(), arg.getUnsafeNodes().count()); + logger.write( + Level.INFO, + "| | Finished ARG: %d nodes, %d incomplete, %d unsafe%n", + arg.getNodes().count(), + arg.getIncompleteNodes().count(), + arg.getUnsafeNodes().count()); waitlist.clear(); // Optimization @@ -175,8 +186,8 @@ public Builder logger(final Logger logger) { } public BasicArgAbstractor build() { - return new BasicArgAbstractor<>(argBuilder, projection, waitlist, stopCriterion, logger); + return new BasicArgAbstractor<>( + argBuilder, projection, waitlist, stopCriterion, logger); } } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java index fa811afc42..30da9a28e5 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java @@ -20,11 +20,11 @@ import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; +import hu.bme.mit.theta.analysis.algorithm.Proof; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.SafetyResult; -import hu.bme.mit.theta.analysis.algorithm.Witness; import hu.bme.mit.theta.analysis.runtimemonitor.MonitorCheckpoint; -import hu.bme.mit.theta.analysis.utils.WitnessVisualizer; +import hu.bme.mit.theta.analysis.utils.ProofVisualizer; import hu.bme.mit.theta.common.Utils; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; @@ -42,38 +42,38 @@ * check counterexamples and refine them if needed. It also provides certain * statistics about its execution. */ -public final class CegarChecker implements SafetyChecker { +public final class CegarChecker implements SafetyChecker { - private final Abstractor abstractor; - private final Refiner refiner; + private final Abstractor abstractor; + private final Refiner refiner; private final Logger logger; - private final W witness; - private final WitnessVisualizer witnessVisualizer; + private final Pr proof; + private final ProofVisualizer proofVisualizer; - private CegarChecker(final Abstractor abstractor, final Refiner refiner, final Logger logger, final WitnessVisualizer witnessVisualizer) { + private CegarChecker(final Abstractor abstractor, final Refiner refiner, final Logger logger, final ProofVisualizer proofVisualizer) { this.abstractor = checkNotNull(abstractor); this.refiner = checkNotNull(refiner); this.logger = checkNotNull(logger); - witness = abstractor.createWitness(); - this.witnessVisualizer = checkNotNull(witnessVisualizer); + proof = abstractor.createProof(); + this.proofVisualizer = checkNotNull(proofVisualizer); } - public static CegarChecker create( - final Abstractor abstractor, final Refiner refiner, final WitnessVisualizer witnessVisualizer) { - return create(abstractor, refiner, NullLogger.getInstance(), witnessVisualizer); + public static CegarChecker create( + final Abstractor abstractor, final Refiner refiner, final ProofVisualizer proofVisualizer) { + return create(abstractor, refiner, NullLogger.getInstance(), proofVisualizer); } - public static CegarChecker create( - final Abstractor abstractor, final Refiner refiner, final Logger logger, final WitnessVisualizer witnessVisualizer) { - return new CegarChecker<>(abstractor, refiner, logger, witnessVisualizer); + public static CegarChecker create( + final Abstractor abstractor, final Refiner refiner, final Logger logger, final ProofVisualizer proofVisualizer) { + return new CegarChecker<>(abstractor, refiner, logger, proofVisualizer); } - public W getWitness() { - return witness; + public Pr getProof() { + return proof; } @Override - public SafetyResult check(final P initPrec) { + public SafetyResult check(final P initPrec) { logger.write(Level.INFO, "Configuration: %s%n", this); final Stopwatch stopwatch = Stopwatch.createStarted(); long abstractorTime = 0; @@ -89,12 +89,12 @@ public SafetyResult check(final P initPrec) { logger.write(Level.MAINSTEP, "Iteration %d%n", iteration); logger.write(Level.MAINSTEP, "| Checking abstraction...%n"); final long abstractorStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); - abstractorResult = abstractor.check(witness, prec); + abstractorResult = abstractor.check(proof, prec); abstractorTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - abstractorStartTime; logger.write(Level.MAINSTEP, "| Checking abstraction done, result: %s%n", abstractorResult); if (WebDebuggerLogger.enabled()) { - String argGraph = JSONWriter.getInstance().writeString(witnessVisualizer.visualize(witness)); + String argGraph = JSONWriter.getInstance().writeString(proofVisualizer.visualize(proof)); String precString = prec.toString(); wdl.addIteration(iteration, argGraph, precString); } @@ -105,7 +105,7 @@ public SafetyResult check(final P initPrec) { P lastPrec = prec; logger.write(Level.MAINSTEP, "| Refining abstraction...%n"); final long refinerStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); - refinerResult = refiner.refine(witness, prec); + refinerResult = refiner.refine(proof, prec); refinerTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - refinerStartTime; logger.write(Level.MAINSTEP, "Refining abstraction done, result: %s%n", refinerResult); @@ -124,16 +124,16 @@ public SafetyResult check(final P initPrec) { } while (!abstractorResult.isSafe() && !refinerResult.isUnsafe()); stopwatch.stop(); - SafetyResult cegarResult = null; + SafetyResult cegarResult = null; final CegarStatistics stats = new CegarStatistics(stopwatch.elapsed(TimeUnit.MILLISECONDS), abstractorTime, refinerTime, iteration); assert abstractorResult.isSafe() || refinerResult.isUnsafe(); if (abstractorResult.isSafe()) { - cegarResult = SafetyResult.safe(witness, stats); + cegarResult = SafetyResult.safe(proof, stats); } else if (refinerResult.isUnsafe()) { - cegarResult = SafetyResult.unsafe(refinerResult.asUnsafe().getCex(), witness, stats); + cegarResult = SafetyResult.unsafe(refinerResult.asUnsafe().getCex(), proof, stats); } assert cegarResult != null; diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java index 6eca5d7c21..abd645f3cf 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java @@ -19,16 +19,16 @@ import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.State; -import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.analysis.algorithm.Proof; /** * Common interface for refiners. It takes a witness and a precision, checks if the counterexample in * the witness is feasible and if not, it refines the precision */ -public interface Refiner { +public interface Refiner { /** * Checks if the counterexample in the witness is feasible. If not, refines the precision */ - RefinerResult refine(W witness, P prec); + RefinerResult refine(Pr witness, P prec); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt index 0c083b7cd0..a52da53d51 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/chc/HornChecker.kt @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.analysis.algorithm.chc import hu.bme.mit.theta.analysis.Cex +import hu.bme.mit.theta.analysis.algorithm.Proof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.algorithm.Witness import hu.bme.mit.theta.analysis.unit.UnitPrec import hu.bme.mit.theta.common.logging.Logger import hu.bme.mit.theta.core.Relation @@ -30,58 +29,62 @@ import hu.bme.mit.theta.solver.ProofNode import hu.bme.mit.theta.solver.SolverFactory import hu.bme.mit.theta.solver.SolverStatus -data class Invariant(val lookup: Map>) : Witness +data class Invariant(val lookup: Map>) : Proof data class CexTree(val proofNode: ProofNode) : Cex { - override fun length(): Int = proofNode.depth() + override fun length(): Int = proofNode.depth() } -/** - * A checker for CHC-based verification. - */ +/** A checker for CHC-based verification. */ class HornChecker( - private val relations: List, - private val hornSolverFactory: SolverFactory, - private val logger: Logger, + private val relations: List, + private val hornSolverFactory: SolverFactory, + private val logger: Logger, ) : SafetyChecker { - override fun check(prec: UnitPrec?): SafetyResult { - val solver = hornSolverFactory.createHornSolver() - logger.write(Logger.Level.MAINSTEP, "Starting encoding\n") - solver.add(relations) - logger.write(Logger.Level.DETAIL, "Relations:\n\t${ + override fun check(prec: UnitPrec?): SafetyResult { + val solver = hornSolverFactory.createHornSolver() + logger.write(Logger.Level.MAINSTEP, "Starting encoding\n") + solver.add(relations) + logger.write( + Logger.Level.DETAIL, + "Relations:\n\t${ relations.joinToString("\n\t") { it.constDecl.toString() } - }\n") - logger.write(Logger.Level.DETAIL, "Rules:\n\t${ + }\n", + ) + logger.write( + Logger.Level.DETAIL, + "Rules:\n\t${ solver.assertions.joinToString("\n\t") { it.toString().replace(Regex("[\r\n\t ]+"), " ") } - }\n") - logger.write(Logger.Level.MAINSTEP, "Added constraints to solver\n") - solver.check() - logger.write(Logger.Level.MAINSTEP, "Check() finished (result: ${solver.status})\n") - return when (solver.status) { - SolverStatus.SAT -> { - logger.write(Logger.Level.MAINSTEP, "Proof (model) found\n") - val model = solver.model.toMap() - SafetyResult.safe( - Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() })) - } + }\n", + ) + logger.write(Logger.Level.MAINSTEP, "Added constraints to solver\n") + solver.check() + logger.write(Logger.Level.MAINSTEP, "Check() finished (result: ${solver.status})\n") + return when (solver.status) { + SolverStatus.SAT -> { + logger.write(Logger.Level.MAINSTEP, "Proof (model) found\n") + val model = solver.model.toMap() + SafetyResult.safe( + Invariant(relations.associateWith { model[it.constDecl] as? Expr ?: True() }) + ) + } - SolverStatus.UNSAT -> { - logger.write(Logger.Level.MAINSTEP, "Counterexample found\n") - val proof = solver.proof - SafetyResult.unsafe(CexTree(proof), Invariant(emptyMap())) - } + SolverStatus.UNSAT -> { + logger.write(Logger.Level.MAINSTEP, "Counterexample found\n") + val proof = solver.proof + SafetyResult.unsafe(CexTree(proof), Invariant(emptyMap())) + } - else -> { - logger.write(Logger.Level.MAINSTEP, "No solution found.\n") - SafetyResult.unknown() - } - } + else -> { + logger.write(Logger.Level.MAINSTEP, "No solution found.\n") + SafetyResult.unknown() + } } - -} \ No newline at end of file + } +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/FiniteStateChecker.kt b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/FiniteStateChecker.kt index 05c02303c3..b316300d9c 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/FiniteStateChecker.kt +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mcm/analysis/FiniteStateChecker.kt @@ -13,14 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.analysis.algorithm.mcm.analysis import hu.bme.mit.theta.analysis.EmptyCex import hu.bme.mit.theta.analysis.InitFunc import hu.bme.mit.theta.analysis.LTS import hu.bme.mit.theta.analysis.TransFunc -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.mcm.interpreter.MemoryEventProvider @@ -35,52 +34,52 @@ import hu.bme.mit.theta.graphsolver.patterns.constraints.GraphConstraint import hu.bme.mit.theta.graphsolver.solvers.GraphSolver import java.util.* -/** - * WiP checker for finite-state systems - */ +/** WiP checker for finite-state systems */ class FiniteStateChecker( - private val mcm: Collection, - private val initFunc: InitFunc, - private val actionFunc: LTS, - private val transFunc: TransFunc, - private val memoryEventProvider: MemoryEventProvider, - private val graphPatternCompiler: GraphPatternCompiler, - private val graphPatternSolver: GraphSolver -) : SafetyChecker { + private val mcm: Collection, + private val initFunc: InitFunc, + private val actionFunc: LTS, + private val transFunc: TransFunc, + private val memoryEventProvider: MemoryEventProvider, + private val graphPatternCompiler: GraphPatternCompiler, + private val graphPatternSolver: GraphSolver, +) : SafetyChecker { - override fun check(prec: ExplPrec): SafetyResult { - val eventIds = LinkedList() - val rels = LinkedList>() - val lastIds = LinkedHashMap() - val initId = nextId(eventIds) - val initStates = LinkedList(initFunc.getInitStates(prec)) - initStates.forEach { lastIds[it] = initId } - while (initStates.isNotEmpty()) { - val state = initStates.pop() - val lastId = checkNotNull(lastIds[state]) - val actions = actionFunc.getEnabledActionsFor(state) - - val nextStates = actions.map { a -> - val memEvent = memoryEventProvider[a, prec] - transFunc.getSuccStates(state, a, prec).onEach { s -> - memEvent?.also { - val id = nextId(eventIds) - rels.add(Pair(memEvent.type().label, Tuple1.of(id))) - rels.add(Pair("po", Tuple2.of(lastId, id))) - lastIds[s] = id - } - } - }.flatten() - initStates.addAll(nextStates) - } -// PartialSolver(mcm, CandidateExecutionGraph(eventIds, rels)) - return SafetyResult.unsafe(EmptyCex.getInstance(), EmptyWitness.getInstance()) + override fun check(prec: ExplPrec): SafetyResult { + val eventIds = LinkedList() + val rels = LinkedList>() + val lastIds = LinkedHashMap() + val initId = nextId(eventIds) + val initStates = LinkedList(initFunc.getInitStates(prec)) + initStates.forEach { lastIds[it] = initId } + while (initStates.isNotEmpty()) { + val state = initStates.pop() + val lastId = checkNotNull(lastIds[state]) + val actions = actionFunc.getEnabledActionsFor(state) + val nextStates = + actions + .map { a -> + val memEvent = memoryEventProvider[a, prec] + transFunc.getSuccStates(state, a, prec).onEach { s -> + memEvent?.also { + val id = nextId(eventIds) + rels.add(Pair(memEvent.type().label, Tuple1.of(id))) + rels.add(Pair("po", Tuple2.of(lastId, id))) + lastIds[s] = id + } + } + } + .flatten() + initStates.addAll(nextStates) } + // PartialSolver(mcm, CandidateExecutionGraph(eventIds, rels)) + return SafetyResult.unsafe(EmptyCex.getInstance(), EmptyProof.getInstance()) + } - private fun nextId(list: MutableList): Int { - val ret = list.size - list.add(list.size) - return ret - } -} \ No newline at end of file + private fun nextId(list: MutableList): Int { + val ret = list.size + list.add(list.size) + return ret + } +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddChecker.java index df1feb4743..cd81d5a697 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddChecker.java @@ -15,28 +15,28 @@ */ package hu.bme.mit.theta.analysis.algorithm.mdd; -import hu.bme.mit.delta.collections.impl.RecursiveIntObjMapViews; -import hu.bme.mit.delta.java.mdd.*; +import static hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not; + +import hu.bme.mit.delta.java.mdd.JavaMddFactory; +import hu.bme.mit.delta.java.mdd.MddGraph; +import hu.bme.mit.delta.java.mdd.MddHandle; +import hu.bme.mit.delta.java.mdd.MddVariableOrder; import hu.bme.mit.delta.mdd.MddInterpreter; import hu.bme.mit.delta.mdd.MddVariableDescriptor; -import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; +import hu.bme.mit.theta.analysis.algorithm.SafetyResult; +import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.AbstractNextStateDescriptor; +import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeInitializer; +import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeNextStateDescriptor; +import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.ExprLatticeDefinition; +import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.MddExpressionTemplate; import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.BfsProvider; import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.GeneralizedSaturationProvider; -import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.AbstractNextStateDescriptor; import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.SimpleSaturationProvider; import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.StateSpaceEnumerationProvider; -import hu.bme.mit.theta.common.logging.Logger.Level; -import hu.bme.mit.theta.solver.SolverPool; -import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.ExprLatticeDefinition; -import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.MddExpressionTemplate; -import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeInitializer; -import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeNextStateDescriptor; import hu.bme.mit.theta.analysis.expr.ExprAction; -import hu.bme.mit.theta.analysis.utils.MddNodeVisualizer; import hu.bme.mit.theta.common.logging.Logger; -import hu.bme.mit.theta.common.visualization.Graph; -import hu.bme.mit.theta.common.visualization.writer.GraphvizWriter; +import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.core.decl.Decl; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.type.Expr; @@ -45,15 +45,11 @@ import hu.bme.mit.theta.core.utils.PathUtils; import hu.bme.mit.theta.core.utils.indexings.VarIndexing; import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory; -import hu.bme.mit.theta.solver.SolverFactory; - -import java.io.FileNotFoundException; +import hu.bme.mit.theta.solver.SolverPool; import java.util.List; import java.util.Set; -import static hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not; - -public class MddChecker implements SafetyChecker { +public class MddChecker implements SafetyChecker { private final Expr initRel; private final VarIndexing initIndexing; @@ -64,16 +60,19 @@ public class MddChecker implements SafetyChecker initRel, - VarIndexing initIndexing, - A transRel, - Expr safetyProperty, - SolverPool solverPool, - Logger logger, - IterationStrategy iterationStrategy) { + private MddChecker( + Expr initRel, + VarIndexing initIndexing, + A transRel, + Expr safetyProperty, + SolverPool solverPool, + Logger logger, + IterationStrategy iterationStrategy) { this.initRel = initRel; this.initIndexing = initIndexing; this.transRel = transRel; @@ -83,40 +82,63 @@ private MddChecker(Expr initRel, this.iterationStrategy = iterationStrategy; } - public static MddChecker create(Expr initRel, - VarIndexing initIndexing, - A transRel, - Expr safetyProperty, - SolverPool solverPool, - Logger logger) { - return new MddChecker(initRel, initIndexing, transRel, safetyProperty, solverPool, logger, IterationStrategy.GSAT); + public static MddChecker create( + Expr initRel, + VarIndexing initIndexing, + A transRel, + Expr safetyProperty, + SolverPool solverPool, + Logger logger) { + return new MddChecker( + initRel, + initIndexing, + transRel, + safetyProperty, + solverPool, + logger, + IterationStrategy.GSAT); } - public static MddChecker create(Expr initRel, - VarIndexing initIndexing, - A transRel, - Expr safetyProperty, - SolverPool solverPool, - Logger logger, - IterationStrategy iterationStrategy) { - return new MddChecker(initRel, initIndexing, transRel, safetyProperty, solverPool, logger, iterationStrategy); + public static MddChecker create( + Expr initRel, + VarIndexing initIndexing, + A transRel, + Expr safetyProperty, + SolverPool solverPool, + Logger logger, + IterationStrategy iterationStrategy) { + return new MddChecker( + initRel, + initIndexing, + transRel, + safetyProperty, + solverPool, + logger, + iterationStrategy); } @Override - public SafetyResult check(Void input) { + public SafetyResult check(Void input) { - final MddGraph mddGraph = JavaMddFactory.getDefault().createMddGraph(ExprLatticeDefinition.forExpr()); + final MddGraph mddGraph = + JavaMddFactory.getDefault().createMddGraph(ExprLatticeDefinition.forExpr()); - final MddVariableOrder stateOrder = JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); - final MddVariableOrder transOrder = JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); + final MddVariableOrder stateOrder = + JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); + final MddVariableOrder transOrder = + JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); - final Set> vars = ExprUtils.getVars(List.of(initRel, transRel.toExpr(), safetyProperty)); + final Set> vars = + ExprUtils.getVars(List.of(initRel, transRel.toExpr(), safetyProperty)); for (var v : vars) { final var domainSize = v.getType() instanceof BoolType ? 2 : 0; - stateOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(initIndexing.get(v)), domainSize)); + stateOrder.createOnTop( + MddVariableDescriptor.create(v.getConstDecl(initIndexing.get(v)), domainSize)); - transOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(transRel.nextIndexing().get(v)), domainSize)); + transOrder.createOnTop( + MddVariableDescriptor.create( + v.getConstDecl(transRel.nextIndexing().get(v)), domainSize)); transOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(0), domainSize)); } @@ -124,13 +146,20 @@ public SafetyResult check(Void input) { final var transSig = transOrder.getDefaultSetSignature(); final Expr initExpr = PathUtils.unfold(initRel, initIndexing); - final MddHandle initNode = stateSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(initExpr, o -> (Decl) o, solverPool)); + final MddHandle initNode = + stateSig.getTopVariableHandle() + .checkInNode(MddExpressionTemplate.of(initExpr, o -> (Decl) o, solverPool)); logger.write(Level.INFO, "Created initial node"); - final Expr transExpr = PathUtils.unfold(transRel.toExpr(), VarIndexingFactory.indexing(0)); - final MddHandle transitionNode = transSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(transExpr, o -> (Decl) o, solverPool)); - final AbstractNextStateDescriptor nextStates = MddNodeNextStateDescriptor.of(transitionNode); + final Expr transExpr = + PathUtils.unfold(transRel.toExpr(), VarIndexingFactory.indexing(0)); + final MddHandle transitionNode = + transSig.getTopVariableHandle() + .checkInNode( + MddExpressionTemplate.of(transExpr, o -> (Decl) o, solverPool)); + final AbstractNextStateDescriptor nextStates = + MddNodeNextStateDescriptor.of(transitionNode); logger.write(Level.INFO, "Created next-state node, starting fixed point calculation"); @@ -147,12 +176,20 @@ public SafetyResult check(Void input) { } default -> throw new IllegalStateException("Unexpected value: " + iterationStrategy); } - final MddHandle stateSpace = stateSpaceProvider.compute(MddNodeInitializer.of(initNode), nextStates, stateSig.getTopVariableHandle()); + final MddHandle stateSpace = + stateSpaceProvider.compute( + MddNodeInitializer.of(initNode), + nextStates, + stateSig.getTopVariableHandle()); logger.write(Level.INFO, "Enumerated state-space"); final Expr negatedPropExpr = PathUtils.unfold(Not(safetyProperty), initIndexing); - final MddHandle propNode = stateSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(negatedPropExpr, o -> (Decl) o, solverPool)); + final MddHandle propNode = + stateSig.getTopVariableHandle() + .checkInNode( + MddExpressionTemplate.of( + negatedPropExpr, o -> (Decl) o, solverPool)); final MddHandle propViolating = (MddHandle) stateSpace.intersection(propNode); @@ -164,13 +201,21 @@ public SafetyResult check(Void input) { final Long stateSpaceSize = MddInterpreter.calculateNonzeroCount(stateSpace); logger.write(Level.DETAIL, "State space size: " + stateSpaceSize); - final MddAnalysisStatistics statistics = new MddAnalysisStatistics(violatingSize, stateSpaceSize, stateSpaceProvider.getHitCount(), stateSpaceProvider.getQueryCount(), stateSpaceProvider.getCacheSize()); + final MddAnalysisStatistics statistics = + new MddAnalysisStatistics( + violatingSize, + stateSpaceSize, + stateSpaceProvider.getHitCount(), + stateSpaceProvider.getQueryCount(), + stateSpaceProvider.getCacheSize()); - final SafetyResult result; + final SafetyResult result; if (violatingSize != 0) { - result = SafetyResult.unsafe(MddCex.of(propViolating), MddWitness.of(stateSpace), statistics); + result = + SafetyResult.unsafe( + MddCex.of(propViolating), MddProof.of(stateSpace), statistics); } else { - result = SafetyResult.safe(MddWitness.of(stateSpace), statistics); + result = SafetyResult.safe(MddProof.of(stateSpace), statistics); } logger.write(Level.RESULT, "%s%n", result); return result; diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddWitness.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddProof.java similarity index 81% rename from subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddWitness.java rename to subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddProof.java index 300dc6579f..805a138399 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddWitness.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddProof.java @@ -17,18 +17,18 @@ import hu.bme.mit.delta.java.mdd.MddHandle; import hu.bme.mit.delta.mdd.MddInterpreter; -import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.analysis.algorithm.Proof; -public class MddWitness implements Witness { +public class MddProof implements Proof { private final MddHandle stateSpace; - private MddWitness(MddHandle stateSpace) { + private MddProof(MddHandle stateSpace) { this.stateSpace = stateSpace; } - public static MddWitness of(MddHandle stateSpace) { - return new MddWitness(stateSpace); + public static MddProof of(MddHandle stateSpace) { + return new MddProof(stateSpace); } public Long size() { diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java index c4c82eeb74..89efd988a5 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ArgVisualizer.java @@ -18,25 +18,23 @@ import static hu.bme.mit.theta.common.visualization.Alignment.LEFT; import static hu.bme.mit.theta.common.visualization.Shape.RECTANGLE; -import java.awt.Color; - -import hu.bme.mit.theta.common.container.Containers; - -import java.util.Set; -import java.util.function.Function; -import java.util.stream.Collectors; - import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgEdge; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode; +import hu.bme.mit.theta.common.container.Containers; import hu.bme.mit.theta.common.visualization.EdgeAttributes; import hu.bme.mit.theta.common.visualization.Graph; import hu.bme.mit.theta.common.visualization.LineStyle; import hu.bme.mit.theta.common.visualization.NodeAttributes; +import java.awt.*; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; -public final class ArgVisualizer implements WitnessVisualizer> { +public final class ArgVisualizer + implements ProofVisualizer> { private static final LineStyle COVER_EDGE_STYLE = LineStyle.DASHED; private static final LineStyle SUCC_EDGE_STYLE = LineStyle.NORMAL; @@ -53,8 +51,8 @@ public final class ArgVisualizer implements W private static class LazyHolderDefault { - static final ArgVisualizer INSTANCE = new ArgVisualizer<>(Object::toString, - Object::toString); + static final ArgVisualizer INSTANCE = + new ArgVisualizer<>(Object::toString, Object::toString); } private static class LazyHolderStructureOnly { @@ -62,8 +60,8 @@ private static class LazyHolderStructureOnly { static final ArgVisualizer INSTANCE = new ArgVisualizer<>(s -> "", a -> ""); } - public ArgVisualizer(final Function stateToString, - final Function actionToString) { + public ArgVisualizer( + final Function stateToString, final Function actionToString) { this.stateToString = stateToString; this.actionToString = actionToString; } @@ -87,24 +85,37 @@ public Graph visualize(final ARG arg) { final Set> traversed = Containers.createSet(); - for (final ArgNode initNode : arg.getInitNodes() - .collect(Collectors.toSet())) { + for (final ArgNode initNode : + arg.getInitNodes().collect(Collectors.toSet())) { traverse(graph, initNode, traversed); - final NodeAttributes nAttributes = NodeAttributes.builder().label("") - .fillColor(FILL_COLOR) - .lineColor(FILL_COLOR).lineStyle(SUCC_EDGE_STYLE).peripheries(1).build(); + final NodeAttributes nAttributes = + NodeAttributes.builder() + .label("") + .fillColor(FILL_COLOR) + .lineColor(FILL_COLOR) + .lineStyle(SUCC_EDGE_STYLE) + .peripheries(1) + .build(); graph.addNode(PHANTOM_INIT_ID + initNode.getId(), nAttributes); - final EdgeAttributes eAttributes = EdgeAttributes.builder().label("").color(LINE_COLOR) - .lineStyle(SUCC_EDGE_STYLE).build(); - graph.addEdge(PHANTOM_INIT_ID + initNode.getId(), NODE_ID_PREFIX + initNode.getId(), + final EdgeAttributes eAttributes = + EdgeAttributes.builder() + .label("") + .color(LINE_COLOR) + .lineStyle(SUCC_EDGE_STYLE) + .build(); + graph.addEdge( + PHANTOM_INIT_ID + initNode.getId(), + NODE_ID_PREFIX + initNode.getId(), eAttributes); } return graph; } - private void traverse(final Graph graph, final ArgNode node, - final Set> traversed) { + private void traverse( + final Graph graph, + final ArgNode node, + final Set> traversed) { if (traversed.contains(node)) { return; } else { @@ -114,21 +125,33 @@ private void traverse(final Graph graph, final ArgNode final LineStyle lineStyle = SUCC_EDGE_STYLE; final int peripheries = node.isTarget() ? 2 : 1; - final NodeAttributes nAttributes = NodeAttributes.builder() - .label(stateToString.apply(node.getState())) - .alignment(LEFT).shape(RECTANGLE).font(FONT).fillColor(FILL_COLOR).lineColor(LINE_COLOR) - .lineStyle(lineStyle).peripheries(peripheries).build(); + final NodeAttributes nAttributes = + NodeAttributes.builder() + .label(stateToString.apply(node.getState())) + .alignment(LEFT) + .shape(RECTANGLE) + .font(FONT) + .fillColor(FILL_COLOR) + .lineColor(LINE_COLOR) + .lineStyle(lineStyle) + .peripheries(peripheries) + .build(); graph.addNode(nodeId, nAttributes); - for (final ArgEdge edge : node.getOutEdges() - .collect(Collectors.toSet())) { + for (final ArgEdge edge : + node.getOutEdges().collect(Collectors.toSet())) { traverse(graph, edge.getTarget(), traversed); final String sourceId = NODE_ID_PREFIX + edge.getSource().getId(); final String targetId = NODE_ID_PREFIX + edge.getTarget().getId(); - final EdgeAttributes eAttributes = EdgeAttributes.builder() - .label(actionToString.apply(edge.getAction())) - .alignment(LEFT).font(FONT).color(LINE_COLOR).lineStyle(SUCC_EDGE_STYLE).build(); + final EdgeAttributes eAttributes = + EdgeAttributes.builder() + .label(actionToString.apply(edge.getAction())) + .alignment(LEFT) + .font(FONT) + .color(LINE_COLOR) + .lineStyle(SUCC_EDGE_STYLE) + .build(); graph.addEdge(sourceId, targetId, eAttributes); } @@ -136,10 +159,14 @@ private void traverse(final Graph graph, final ArgNode traverse(graph, node.getCoveringNode().get(), traversed); final String sourceId = NODE_ID_PREFIX + node.getId(); final String targetId = NODE_ID_PREFIX + node.getCoveringNode().get().getId(); - final EdgeAttributes eAttributes = EdgeAttributes.builder().label("").color(LINE_COLOR) - .lineStyle(COVER_EDGE_STYLE).weight(0).build(); + final EdgeAttributes eAttributes = + EdgeAttributes.builder() + .label("") + .color(LINE_COLOR) + .lineStyle(COVER_EDGE_STYLE) + .weight(0) + .build(); graph.addEdge(sourceId, targetId, eAttributes); } } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ProofVisualizer.java similarity index 83% rename from subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java rename to subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ProofVisualizer.java index bd1a9d8234..954604871d 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/WitnessVisualizer.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/utils/ProofVisualizer.java @@ -13,14 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.analysis.utils; -import hu.bme.mit.theta.analysis.algorithm.Witness; +import hu.bme.mit.theta.analysis.algorithm.Proof; import hu.bme.mit.theta.common.visualization.Graph; -public interface WitnessVisualizer { - - Graph visualize(W witness); +public interface ProofVisualizer { + Graph visualize(Pr proof); } diff --git a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddCheckerTest.java b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddCheckerTest.java index 070daeb91f..0f9f524354 100644 --- a/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddCheckerTest.java +++ b/subprojects/common/analysis/src/test/java/hu/bme/mit/theta/analysis/algorithm/mdd/MddCheckerTest.java @@ -15,6 +15,14 @@ */ package hu.bme.mit.theta.analysis.algorithm.mdd; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.*; +import static hu.bme.mit.theta.core.type.anytype.Exprs.Prime; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.common.logging.ConsoleLogger; @@ -29,31 +37,19 @@ import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory; import hu.bme.mit.theta.solver.SolverPool; import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; +import java.util.Arrays; +import java.util.Collection; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; - -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.*; -import static hu.bme.mit.theta.core.type.anytype.Exprs.Prime; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - @RunWith(value = Parameterized.class) - public class MddCheckerTest { private static final VarDecl X = Decls.Var("x", IntType.getInstance()); private static final VarDecl Y = Decls.Var("y", IntType.getInstance()); private static final VarDecl Z = Decls.Var("z", IntType.getInstance()); - @Parameterized.Parameter(value = 0) public Expr initExpr; @@ -71,57 +67,86 @@ public class MddCheckerTest { @Parameterized.Parameters(name = "{index}: {0}, {1}, {2}, {3}, {4}") public static Collection data() { - return Arrays.asList(new Object[][]{ - - {Eq(X.getRef(), Int(0)), // x = 0 + return Arrays.asList( + new Object[][] { + { + Eq(X.getRef(), Int(0)), // x = 0 Eq(Prime(X.getRef()), X.getRef()), // x'=x Not(Eq(X.getRef(), Int(5))), // not x = 5 true, - 1L}, - - {Eq(X.getRef(), Int(0)), + 1L + }, + { + Eq(X.getRef(), Int(0)), Eq(Prime(X.getRef()), X.getRef()), Not(Eq(X.getRef(), Int(0))), false, - 1L}, - - {Eq(X.getRef(), Int(0)), // x = 0 - And(Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), Leq(Prime(X.getRef()), Int(10))), // x' = x + 1 & x' <= 10 + 1L + }, + { + Eq(X.getRef(), Int(0)), // x = 0 + And( + Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), + Leq(Prime(X.getRef()), Int(10))), // x' = x + 1 & x' <= 10 Not(Eq(X.getRef(), Int(5))), false, - 11L}, - - {Eq(X.getRef(), Int(0)), - And(Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), Leq(Prime(X.getRef()), Int(5))), + 11L + }, + { + Eq(X.getRef(), Int(0)), + And( + Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), + Leq(Prime(X.getRef()), Int(5))), Not(Eq(X.getRef(), Int(5))), false, - 6L}, - - {Eq(X.getRef(), Int(0)), - And(Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), Leq(Prime(X.getRef()), Int(4))), + 6L + }, + { + Eq(X.getRef(), Int(0)), + And( + Eq(Prime(X.getRef()), Add(X.getRef(), Int(1))), + Leq(Prime(X.getRef()), Int(4))), Not(Eq(X.getRef(), Int(5))), true, - 5L}, - - {And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), - And(And(Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), IntExprs.Lt(Prime(Z.getRef()), Int(10))), + 5L + }, + { + And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), + And( + And( + Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), + Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), + Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), + IntExprs.Lt(Prime(Z.getRef()), Int(10))), Not(Eq(X.getRef(), Int(5))), false, - 10L}, - - {And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), - And(And(Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), IntExprs.Lt(Prime(Z.getRef()), Int(6))), + 10L + }, + { + And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), + And( + And( + Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), + Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), + Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), + IntExprs.Lt(Prime(Z.getRef()), Int(6))), Not(Eq(X.getRef(), Int(5))), false, - 6L}, - - {And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), - And(And(Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), IntExprs.Lt(Prime(Z.getRef()), Int(5))), + 6L + }, + { + And(Eq(X.getRef(), Int(0)), Eq(Y.getRef(), Int(0)), Eq(Z.getRef(), Int(0))), + And( + And( + Eq(Prime(X.getRef()), Add(Y.getRef(), Int(1))), + Eq(Prime(Y.getRef()), Add(Z.getRef(), Int(1))), + Eq(Prime(Z.getRef()), Add(Z.getRef(), Int(1)))), + IntExprs.Lt(Prime(Z.getRef()), Int(5))), Not(Eq(X.getRef(), Int(5))), true, - 5L}, - - }); + 5L + }, + }); } @Test @@ -139,23 +164,32 @@ public void testGsat() throws Exception { testWithIterationStrategy(MddChecker.IterationStrategy.GSAT); } - public void testWithIterationStrategy(MddChecker.IterationStrategy iterationStrategy) throws Exception { + public void testWithIterationStrategy(MddChecker.IterationStrategy iterationStrategy) + throws Exception { final Logger logger = new ConsoleLogger(Logger.Level.SUBSTEP); - final SafetyResult status; + final SafetyResult status; try (var solverPool = new SolverPool(Z3LegacySolverFactory.getInstance())) { - final MddChecker checker = MddChecker.create(initExpr, VarIndexingFactory.indexing(0), new ExprAction() { - @Override - public Expr toExpr() { - return tranExpr; - } - - @Override - public VarIndexing nextIndexing() { - return VarIndexingFactory.indexing(1); - } - }, propExpr, solverPool, logger, iterationStrategy); + final MddChecker checker = + MddChecker.create( + initExpr, + VarIndexingFactory.indexing(0), + new ExprAction() { + @Override + public Expr toExpr() { + return tranExpr; + } + + @Override + public VarIndexing nextIndexing() { + return VarIndexingFactory.indexing(1); + } + }, + propExpr, + solverPool, + logger, + iterationStrategy); status = checker.check(null); } @@ -164,9 +198,6 @@ public VarIndexing nextIndexing() { } else { assertTrue(status.isUnsafe()); } - assertEquals(stateSpaceSize, status.getWitness().size()); - - + assertEquals(stateSpaceSize, status.getProof().size()); } - } diff --git a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt index 6829d577c0..0cd6eb5b2f 100644 --- a/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt +++ b/subprojects/common/grammar/src/main/java/hu/bme/mit/theta/grammar/gson/SafetyResultAdapter.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.grammar.gson import com.google.gson.Gson @@ -24,72 +23,75 @@ import com.google.gson.stream.JsonWriter import hu.bme.mit.theta.analysis.Action import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.arg.ARG import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.Statistics +import hu.bme.mit.theta.analysis.algorithm.arg.ARG import java.lang.reflect.Type import java.util.* class SafetyResultAdapter( - val gsonSupplier: () -> Gson, - private val argTypeSupplier: () -> Type, - private val traceTypeSupplier: () -> Type, + val gsonSupplier: () -> Gson, + private val argTypeSupplier: () -> Type, + private val traceTypeSupplier: () -> Type, ) : TypeAdapter, Trace>>() { - private lateinit var gson: Gson - private lateinit var argType: Type - private lateinit var traceType: Type + private lateinit var gson: Gson + private lateinit var argType: Type + private lateinit var traceType: Type - override fun write(writer: JsonWriter, - value: SafetyResult, Trace>) { - initGson() - writer.beginObject() - writer.name("arg") - gson.toJson(gson.toJsonTree(value.witness), writer) - writer.name("stats") -// gson.toJson(gson.toJsonTree(value.stats), writer) - gson.toJson(gson.toJsonTree(Optional.empty()), writer) - if (value.isSafe) { - writer.name("safe").value(true) - } else { - val unsafe = value.asUnsafe() - writer.name("safe").value(false) - writer.name("trace") - gson.toJson(gson.toJsonTree(unsafe.cex), writer) - } - writer.endObject() + override fun write( + writer: JsonWriter, + value: SafetyResult, Trace>, + ) { + initGson() + writer.beginObject() + writer.name("arg") + gson.toJson(gson.toJsonTree(value.proof), writer) + writer.name("stats") + // gson.toJson(gson.toJsonTree(value.stats), writer) + gson.toJson(gson.toJsonTree(Optional.empty()), writer) + if (value.isSafe) { + writer.name("safe").value(true) + } else { + val unsafe = value.asUnsafe() + writer.name("safe").value(false) + writer.name("trace") + gson.toJson(gson.toJsonTree(unsafe.cex), writer) } + writer.endObject() + } - override fun read(reader: JsonReader): SafetyResult, Trace> { - initGson() - initTypes() - lateinit var arg: ARG - lateinit var stats: Optional - var safe: Boolean? = null - lateinit var trace: Trace - reader.beginObject() - while (reader.peek() != JsonToken.END_OBJECT) { - when (reader.nextName()) { - "arg" -> arg = gson.fromJson(reader, argType) - "stats" -> stats = gson.fromJson(reader, Optional::class.java) - "safe" -> safe = reader.nextBoolean() - "trace" -> trace = gson.fromJson(reader, traceType) - } - } - reader.endObject() - return if (stats.isEmpty) - if (safe == true) SafetyResult.safe(arg) else SafetyResult.unsafe(trace, arg) - else - if (safe == false) SafetyResult.safe(arg, stats.get()) else SafetyResult.unsafe(trace, - arg, stats.get()) + override fun read( + reader: JsonReader + ): SafetyResult, Trace> { + initGson() + initTypes() + lateinit var arg: ARG + lateinit var stats: Optional + var safe: Boolean? = null + lateinit var trace: Trace + reader.beginObject() + while (reader.peek() != JsonToken.END_OBJECT) { + when (reader.nextName()) { + "arg" -> arg = gson.fromJson(reader, argType) + "stats" -> stats = gson.fromJson(reader, Optional::class.java) + "safe" -> safe = reader.nextBoolean() + "trace" -> trace = gson.fromJson(reader, traceType) + } } + reader.endObject() + return if (stats.isEmpty) + if (safe == true) SafetyResult.safe(arg) else SafetyResult.unsafe(trace, arg) + else if (safe == false) SafetyResult.safe(arg, stats.get()) + else SafetyResult.unsafe(trace, arg, stats.get()) + } - private fun initGson() { - if (!this::gson.isInitialized) gson = gsonSupplier() - } + private fun initGson() { + if (!this::gson.isInitialized) gson = gsonSupplier() + } - private fun initTypes() { - if (!this::traceType.isInitialized) traceType = traceTypeSupplier() - if (!this::argType.isInitialized) argType = argTypeSupplier() - } -} \ No newline at end of file + private fun initTypes() { + if (!this::traceType.isInitialized) traceType = traceTypeSupplier() + if (!this::argType.isInitialized) argType = argTypeSupplier() + } +} diff --git a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java index 4f2f998af5..f6609fdc97 100644 --- a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java +++ b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsExplTest.java @@ -15,18 +15,25 @@ */ package hu.bme.mit.theta.sts.analysis; +import static hu.bme.mit.theta.analysis.algorithm.arg.ArgUtils.isWellLabeled; +import static hu.bme.mit.theta.core.decl.Decls.Var; +import static hu.bme.mit.theta.core.type.anytype.Exprs.Prime; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.*; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.*; +import static org.junit.Assert.assertTrue; + import hu.bme.mit.theta.analysis.Analysis; import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.analysis.Trace; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; import hu.bme.mit.theta.analysis.algorithm.arg.ArgNodeComparators; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.expl.ExplAnalysis; import hu.bme.mit.theta.analysis.expl.ExplPrec; import hu.bme.mit.theta.analysis.expl.ExplState; @@ -34,12 +41,7 @@ import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.analysis.expr.ExprStatePredicate; -import hu.bme.mit.theta.analysis.expr.refinement.ExprTraceChecker; -import hu.bme.mit.theta.analysis.expr.refinement.ExprTraceUnsatCoreChecker; -import hu.bme.mit.theta.analysis.expr.refinement.JoiningPrecRefiner; -import hu.bme.mit.theta.analysis.expr.refinement.PruneStrategy; -import hu.bme.mit.theta.analysis.expr.refinement.SingleExprTraceRefiner; -import hu.bme.mit.theta.analysis.expr.refinement.VarsRefutation; +import hu.bme.mit.theta.analysis.expr.refinement.*; import hu.bme.mit.theta.analysis.waitlist.PriorityWaitlist; import hu.bme.mit.theta.common.logging.ConsoleLogger; import hu.bme.mit.theta.common.logging.Logger; @@ -52,23 +54,9 @@ import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; import hu.bme.mit.theta.sts.STS; import hu.bme.mit.theta.sts.STS.Builder; -import org.junit.Test; - import java.util.Collections; import java.util.function.Predicate; - -import static hu.bme.mit.theta.analysis.algorithm.arg.ArgUtils.isWellLabeled; -import static hu.bme.mit.theta.core.decl.Decls.Var; -import static hu.bme.mit.theta.core.type.anytype.Exprs.Prime; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Imply; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Add; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Eq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Geq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Lt; -import static org.junit.Assert.assertTrue; +import org.junit.Test; public class StsExplTest { @@ -88,8 +76,10 @@ public void test() { builder.addInit(Eq(x, Int(0))); builder.addInit(Eq(y, Int(0))); - builder.addTrans(And(Imply(Lt(x, Int(mod)), Eq(Prime(x), Add(x, Int(1)))), - Imply(Geq(x, Int(mod)), Eq(Prime(x), Int(0))))); + builder.addTrans( + And( + Imply(Lt(x, Int(mod)), Eq(Prime(x), Add(x, Int(1)))), + Imply(Geq(x, Int(mod)), Eq(Prime(x), Int(0))))); builder.addTrans(Eq(Prime(y), Int(0))); builder.setProp(Not(Eq(x, Int(mod)))); @@ -98,40 +88,45 @@ public void test() { final Solver abstractionSolver = Z3LegacySolverFactory.getInstance().createSolver(); final UCSolver refinementSolver = Z3LegacySolverFactory.getInstance().createUCSolver(); - final Analysis analysis = ExplAnalysis.create( - abstractionSolver, sts.getInit()); - final Predicate target = new ExprStatePredicate(Not(sts.getProp()), - abstractionSolver); + final Analysis analysis = + ExplAnalysis.create(abstractionSolver, sts.getInit()); + final Predicate target = + new ExprStatePredicate(Not(sts.getProp()), abstractionSolver); final ExplPrec prec = ExplPrec.of(Collections.singleton(vy)); final LTS lts = StsLts.create(sts); - final ArgBuilder argBuilder = ArgBuilder.create(lts, - analysis, target); + final ArgBuilder argBuilder = + ArgBuilder.create(lts, analysis, target); - final ArgAbstractor abstractor = BasicArgAbstractor.builder( - argBuilder) - .waitlist(PriorityWaitlist.create(ArgNodeComparators.bfs())).logger(logger).build(); + final ArgAbstractor abstractor = + BasicArgAbstractor.builder(argBuilder) + .waitlist(PriorityWaitlist.create(ArgNodeComparators.bfs())) + .logger(logger) + .build(); - final ExprTraceChecker exprTraceChecker = ExprTraceUnsatCoreChecker.create( - sts.getInit(), - Not(sts.getProp()), refinementSolver); + final ExprTraceChecker exprTraceChecker = + ExprTraceUnsatCoreChecker.create( + sts.getInit(), Not(sts.getProp()), refinementSolver); - final SingleExprTraceRefiner refiner = SingleExprTraceRefiner - .create(exprTraceChecker, JoiningPrecRefiner.create(new VarsRefToExplPrec()), - PruneStrategy.LAZY, logger); + final SingleExprTraceRefiner refiner = + SingleExprTraceRefiner.create( + exprTraceChecker, + JoiningPrecRefiner.create(new VarsRefToExplPrec()), + PruneStrategy.LAZY, + logger); - final SafetyChecker, Trace, ExplPrec> checker = ArgCegarChecker.create( - abstractor, refiner, logger); + final SafetyChecker, Trace, ExplPrec> + checker = ArgCegarChecker.create(abstractor, refiner, logger); - final SafetyResult, Trace> safetyStatus = checker.check(prec); + final SafetyResult, Trace> safetyStatus = + checker.check(prec); - final ARG arg = safetyStatus.getWitness(); + final ARG arg = safetyStatus.getProof(); assertTrue(isWellLabeled(arg, abstractionSolver)); // System.out.println(new // GraphvizWriter().writeString(ArgVisualizer.visualize(arg))); } - } diff --git a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsMddCheckerTest.java b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsMddCheckerTest.java index e9f88faaad..929a01e400 100644 --- a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsMddCheckerTest.java +++ b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsMddCheckerTest.java @@ -15,11 +15,13 @@ */ package hu.bme.mit.theta.sts.analysis; +import static org.junit.Assert.assertTrue; + import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.mdd.MddCex; import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker; import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker.IterationStrategy; -import hu.bme.mit.theta.analysis.algorithm.mdd.MddWitness; +import hu.bme.mit.theta.analysis.algorithm.mdd.MddProof; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.common.Utils; import hu.bme.mit.theta.common.logging.ConsoleLogger; @@ -35,16 +37,12 @@ import hu.bme.mit.theta.sts.aiger.AigerToSts; import hu.bme.mit.theta.sts.dsl.StsDslManager; import hu.bme.mit.theta.sts.dsl.StsSpec; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - import java.io.FileInputStream; -import java.io.IOException; import java.util.Arrays; import java.util.Collection; - -import static org.junit.Assert.assertTrue; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; @RunWith(value = Parameterized.class) public class StsMddCheckerTest { @@ -56,35 +54,23 @@ public class StsMddCheckerTest { @Parameterized.Parameters(name = "{index}: {0}, {1}") public static Collection data() { - return Arrays.asList(new Object[][]{ - {"src/test/resources/hw1_false.aag", false}, - - {"src/test/resources/hw2_true.aag", true}, - - {"src/test/resources/boolean1.system", false}, - - {"src/test/resources/boolean2.system", false}, - - {"src/test/resources/counter.system", true}, - - {"src/test/resources/counter_bad.system", false}, - - {"src/test/resources/counter_parametric.system", true}, - - {"src/test/resources/loop.system", true}, - - {"src/test/resources/loop_bad.system", false}, - - {"src/test/resources/multipleinitial.system", false}, - - {"src/test/resources/readerswriters.system", true}, - - {"src/test/resources/simple1.system", false}, - - {"src/test/resources/simple2.system", true}, - - {"src/test/resources/simple3.system", false}, - }); + return Arrays.asList( + new Object[][] { + {"src/test/resources/hw1_false.aag", false}, + {"src/test/resources/hw2_true.aag", true}, + {"src/test/resources/boolean1.system", false}, + {"src/test/resources/boolean2.system", false}, + {"src/test/resources/counter.system", true}, + {"src/test/resources/counter_bad.system", false}, + {"src/test/resources/counter_parametric.system", true}, + {"src/test/resources/loop.system", true}, + {"src/test/resources/loop_bad.system", false}, + {"src/test/resources/multipleinitial.system", false}, + {"src/test/resources/readerswriters.system", true}, + {"src/test/resources/simple1.system", false}, + {"src/test/resources/simple2.system", true}, + {"src/test/resources/simple3.system", false}, + }); } @Test @@ -100,19 +86,27 @@ public void test() throws Exception { sts = Utils.singleElementOf(spec.getAllSts()); } - final SafetyResult status; + final SafetyResult status; try (var solverPool = new SolverPool(Z3LegacySolverFactory.getInstance())) { - final MddChecker checker = MddChecker.create(sts.getInit(), VarIndexingFactory.indexing(0), new ExprAction() { - @Override - public Expr toExpr() { - return sts.getTrans(); - } - - @Override - public VarIndexing nextIndexing() { - return VarIndexingFactory.indexing(1); - } - }, sts.getProp(), solverPool, logger, IterationStrategy.GSAT); + final MddChecker checker = + MddChecker.create( + sts.getInit(), + VarIndexingFactory.indexing(0), + new ExprAction() { + @Override + public Expr toExpr() { + return sts.getTrans(); + } + + @Override + public VarIndexing nextIndexing() { + return VarIndexingFactory.indexing(1); + } + }, + sts.getProp(), + solverPool, + logger, + IterationStrategy.GSAT); status = checker.check(null); } @@ -122,5 +116,4 @@ public VarIndexing nextIndexing() { assertTrue(status.isUnsafe()); } } - } diff --git a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java index bed9497f54..5022d36401 100644 --- a/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java +++ b/subprojects/sts/sts-analysis/src/test/java/hu/bme/mit/theta/sts/analysis/StsPredTest.java @@ -18,53 +18,40 @@ import static hu.bme.mit.theta.analysis.algorithm.arg.ArgUtils.isWellLabeled; import static hu.bme.mit.theta.core.decl.Decls.Var; import static hu.bme.mit.theta.core.type.anytype.Exprs.Prime; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Imply; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.Not; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Add; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Eq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Geq; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Int; -import static hu.bme.mit.theta.core.type.inttype.IntExprs.Lt; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.*; +import static hu.bme.mit.theta.core.type.inttype.IntExprs.*; import static org.junit.Assert.assertTrue; -import java.util.function.Predicate; - -import hu.bme.mit.theta.analysis.Trace; -import hu.bme.mit.theta.analysis.algorithm.SafetyResult; -import hu.bme.mit.theta.analysis.expr.refinement.*; -import hu.bme.mit.theta.solver.ItpSolver; -import hu.bme.mit.theta.solver.Solver; -import org.junit.Before; -import org.junit.Test; - import hu.bme.mit.theta.analysis.Analysis; import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.State; +import hu.bme.mit.theta.analysis.Trace; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; +import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgBuilder; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor; -import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker; +import hu.bme.mit.theta.analysis.algorithm.cegar.BasicArgAbstractor; import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.analysis.expr.ExprStatePredicate; -import hu.bme.mit.theta.analysis.pred.ExprSplitters; -import hu.bme.mit.theta.analysis.pred.ItpRefToPredPrec; -import hu.bme.mit.theta.analysis.pred.PredAbstractors; -import hu.bme.mit.theta.analysis.pred.PredAnalysis; -import hu.bme.mit.theta.analysis.pred.PredPrec; -import hu.bme.mit.theta.analysis.pred.PredState; +import hu.bme.mit.theta.analysis.expr.refinement.*; +import hu.bme.mit.theta.analysis.pred.*; import hu.bme.mit.theta.common.logging.ConsoleLogger; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.core.decl.VarDecl; import hu.bme.mit.theta.core.type.Expr; import hu.bme.mit.theta.core.type.inttype.IntType; +import hu.bme.mit.theta.solver.ItpSolver; +import hu.bme.mit.theta.solver.Solver; import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; import hu.bme.mit.theta.sts.STS; import hu.bme.mit.theta.sts.STS.Builder; +import java.util.function.Predicate; +import org.junit.Before; +import org.junit.Test; public class StsPredTest { @@ -81,8 +68,10 @@ public void setUp() { final Builder builder = STS.builder(); builder.addInit(Eq(x, Int(0))); - builder.addTrans(And(Imply(Lt(x, Int(mod)), Eq(Prime(x), Add(x, Int(1)))), - Imply(Geq(x, Int(mod)), Eq(Prime(x), Int(0))))); + builder.addTrans( + And( + Imply(Lt(x, Int(mod)), Eq(Prime(x), Add(x, Int(1)))), + Imply(Geq(x, Int(mod)), Eq(Prime(x), Int(0))))); builder.setProp(Not(Eq(x, Int(mod)))); sts = builder.build(); @@ -91,39 +80,43 @@ public void setUp() { @Test public void testPredPrec() { - final Analysis analysis = PredAnalysis.create( - abstractionSolver, - PredAbstractors.booleanSplitAbstractor(abstractionSolver), sts.getInit()); - final Predicate target = new ExprStatePredicate(Not(sts.getProp()), - abstractionSolver); + final Analysis analysis = + PredAnalysis.create( + abstractionSolver, + PredAbstractors.booleanSplitAbstractor(abstractionSolver), + sts.getInit()); + final Predicate target = + new ExprStatePredicate(Not(sts.getProp()), abstractionSolver); final PredPrec prec = PredPrec.of(); final LTS lts = StsLts.create(sts); - final ArgBuilder argBuilder = ArgBuilder.create(lts, - analysis, target); + final ArgBuilder argBuilder = + ArgBuilder.create(lts, analysis, target); - final ArgAbstractor abstractor = BasicArgAbstractor.builder( - argBuilder).logger(logger) - .build(); + final ArgAbstractor abstractor = + BasicArgAbstractor.builder(argBuilder).logger(logger).build(); - final ExprTraceChecker exprTraceChecker = ExprTraceFwBinItpChecker.create( - sts.getInit(), - Not(sts.getProp()), refinementSolver); + final ExprTraceChecker exprTraceChecker = + ExprTraceFwBinItpChecker.create( + sts.getInit(), Not(sts.getProp()), refinementSolver); - final SingleExprTraceRefiner refiner = SingleExprTraceRefiner - .create(exprTraceChecker, + final SingleExprTraceRefiner refiner = + SingleExprTraceRefiner.create( + exprTraceChecker, JoiningPrecRefiner.create(new ItpRefToPredPrec(ExprSplitters.atoms())), - PruneStrategy.LAZY, logger); + PruneStrategy.LAZY, + logger); - final SafetyChecker, Trace, PredPrec> checker = ArgCegarChecker.create( - abstractor, refiner, logger); + final SafetyChecker, Trace, PredPrec> + checker = ArgCegarChecker.create(abstractor, refiner, logger); - final SafetyResult, Trace> safetyStatus = checker.check(prec); + final SafetyResult, Trace> safetyStatus = + checker.check(prec); System.out.println(safetyStatus); - final ARG arg = safetyStatus.getWitness(); + final ARG arg = safetyStatus.getProof(); assertTrue(isWellLabeled(arg, abstractionSolver)); // System.out.println(new diff --git a/subprojects/sts/sts-cli/src/main/java/hu/bme/mit/theta/sts/cli/StsCli.java b/subprojects/sts/sts-cli/src/main/java/hu/bme/mit/theta/sts/cli/StsCli.java index ddb48470eb..884bfabdae 100644 --- a/subprojects/sts/sts-cli/src/main/java/hu/bme/mit/theta/sts/cli/StsCli.java +++ b/subprojects/sts/sts-cli/src/main/java/hu/bme/mit/theta/sts/cli/StsCli.java @@ -52,26 +52,14 @@ import hu.bme.mit.theta.sts.analysis.StsTraceConcretizer; import hu.bme.mit.theta.sts.analysis.config.StsConfig; import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder; -import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.Domain; -import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.InitPrec; -import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.PredSplit; -import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.Refinement; -import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.Search; +import hu.bme.mit.theta.sts.analysis.config.StsConfigBuilder.*; import hu.bme.mit.theta.sts.dsl.StsDslManager; import hu.bme.mit.theta.sts.dsl.StsSpec; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; +import java.io.*; import java.util.concurrent.TimeUnit; import java.util.stream.Stream; -/** - * A command line interface for running a CEGAR configuration on an STS. - */ +/** A command line interface for running a CEGAR configuration on an STS. */ public class StsCli { private static final String JAR_NAME = "theta-sts-cli.jar"; @@ -85,41 +73,64 @@ enum Algorithm { IMC } - @Parameter(names = {"--domain"}, description = "Abstract domain") + @Parameter( + names = {"--domain"}, + description = "Abstract domain") Domain domain = Domain.PRED_CART; - @Parameter(names = {"--algorithm"}, description = "Algorithm") + @Parameter( + names = {"--algorithm"}, + description = "Algorithm") Algorithm algorithm = Algorithm.CEGAR; - @Parameter(names = {"--refinement"}, description = "Refinement strategy") + @Parameter( + names = {"--refinement"}, + description = "Refinement strategy") Refinement refinement = Refinement.SEQ_ITP; - @Parameter(names = {"--search"}, description = "Search strategy") + @Parameter( + names = {"--search"}, + description = "Search strategy") Search search = Search.BFS; - @Parameter(names = {"--predsplit"}, description = "Predicate splitting") + @Parameter( + names = {"--predsplit"}, + description = "Predicate splitting") PredSplit predSplit = PredSplit.WHOLE; - @Parameter(names = {"--model"}, description = "Path of the input STS model", required = true) + @Parameter( + names = {"--model"}, + description = "Path of the input STS model", + required = true) String model; - @Parameter(names = {"--initprec"}, description = "Initial precision") + @Parameter( + names = {"--initprec"}, + description = "Initial precision") InitPrec initPrec = InitPrec.EMPTY; - @Parameter(names = "--prunestrategy", description = "Strategy for pruning the ARG after refinement") + @Parameter( + names = "--prunestrategy", + description = "Strategy for pruning the ARG after refinement") PruneStrategy pruneStrategy = PruneStrategy.LAZY; - @Parameter(names = {"--loglevel"}, description = "Detailedness of logging") + @Parameter( + names = {"--loglevel"}, + description = "Detailedness of logging") Logger.Level logLevel = Level.SUBSTEP; - @Parameter(names = {"--benchmark"}, description = "Benchmark mode (only print metrics)") + @Parameter( + names = {"--benchmark"}, + description = "Benchmark mode (only print metrics)") Boolean benchmarkMode = false; @Parameter(names = "--cex", description = "Write concrete counterexample to a file") String cexfile = null; - @Parameter(names = { - "--header"}, description = "Print only a header (for benchmarks)", help = true) + @Parameter( + names = {"--header"}, + description = "Print only a header (for benchmarks)", + help = true) boolean headerOnly = false; @Parameter(names = "--stacktrace", description = "Print full stack trace in case of exception") @@ -169,11 +180,15 @@ private void run() { if (algorithm.equals(Algorithm.CEGAR)) { final StsConfig configuration = buildConfiguration(sts); status = check(configuration); - } else if (algorithm == Algorithm.BMC || algorithm == Algorithm.KINDUCTION || algorithm == Algorithm.IMC) { - final BoundedChecker checker = buildBoundedChecker(sts, Z3LegacySolverFactory.getInstance()); + } else if (algorithm == Algorithm.BMC + || algorithm == Algorithm.KINDUCTION + || algorithm == Algorithm.IMC) { + final BoundedChecker checker = + buildBoundedChecker(sts, Z3LegacySolverFactory.getInstance()); status = checker.check(null); } else { - throw new UnsupportedOperationException("Algorithm " + algorithm + " not supported"); + throw new UnsupportedOperationException( + "Algorithm " + algorithm + " not supported"); } sw.stop(); printResult(status, sts, sw.elapsed(TimeUnit.MILLISECONDS)); @@ -186,20 +201,35 @@ private void run() { } } - private SafetyResult, ? extends Trace> check(StsConfig configuration) throws Exception { + private SafetyResult, ? extends Trace> check( + StsConfig configuration) throws Exception { try { return configuration.check(); } catch (final Exception ex) { String message = ex.getMessage() == null ? "(no message)" : ex.getMessage(); throw new Exception( - "Error while running algorithm: " + ex.getClass().getSimpleName() + " " + message, + "Error while running algorithm: " + + ex.getClass().getSimpleName() + + " " + + message, ex); } } private void printHeader() { - Stream.of("Result", "TimeMs", "AlgoTimeMs", "AbsTimeMs", "RefTimeMs", "Iterations", - "ArgSize", "ArgDepth", "ArgMeanBranchFactor", "CexLen", "Vars", "Size") + Stream.of( + "Result", + "TimeMs", + "AlgoTimeMs", + "AbsTimeMs", + "RefTimeMs", + "Iterations", + "ArgSize", + "ArgDepth", + "ArgMeanBranchFactor", + "CexLen", + "Vars", + "Size") .forEach(writer::cell); writer.newRow(); } @@ -228,49 +258,64 @@ private STS loadModel() throws Exception { private StsConfig buildConfiguration(final STS sts) throws Exception { try { return new StsConfigBuilder(domain, refinement, Z3LegacySolverFactory.getInstance()) - .initPrec(initPrec).search(search) - .predSplit(predSplit).pruneStrategy(pruneStrategy).logger(logger).build(sts); + .initPrec(initPrec) + .search(search) + .predSplit(predSplit) + .pruneStrategy(pruneStrategy) + .logger(logger) + .build(sts); } catch (final Exception ex) { throw new Exception("Could not create configuration: " + ex.getMessage(), ex); } } - private BoundedChecker buildBoundedChecker(final STS sts, final SolverFactory abstractionSolverFactory) { + private BoundedChecker buildBoundedChecker( + final STS sts, final SolverFactory abstractionSolverFactory) { final MonolithicExpr monolithicExpr = StsToMonolithicExprKt.toMonolithicExpr(sts); final BoundedChecker checker; switch (algorithm) { - case BMC -> checker = BoundedCheckerBuilderKt.buildBMC( - monolithicExpr, - abstractionSolverFactory.createSolver(), - val -> StsToMonolithicExprKt.valToState(sts, val), - (val1, val2) -> StsToMonolithicExprKt.valToAction(sts, val1, val2), - logger - ); - case KINDUCTION -> checker = BoundedCheckerBuilderKt.buildKIND( - monolithicExpr, - abstractionSolverFactory.createSolver(), - abstractionSolverFactory.createSolver(), - val -> StsToMonolithicExprKt.valToState(sts, val), - (val1, val2) -> StsToMonolithicExprKt.valToAction(sts, val1, val2), - logger - ); - case IMC -> checker = BoundedCheckerBuilderKt.buildIMC( - monolithicExpr, - abstractionSolverFactory.createSolver(), - abstractionSolverFactory.createItpSolver(), - val -> StsToMonolithicExprKt.valToState(sts, val), - (val1, val2) -> StsToMonolithicExprKt.valToAction(sts, val1, val2), - logger - ); + case BMC -> + checker = + BoundedCheckerBuilderKt.buildBMC( + monolithicExpr, + abstractionSolverFactory.createSolver(), + val -> StsToMonolithicExprKt.valToState(sts, val), + (val1, val2) -> + StsToMonolithicExprKt.valToAction(sts, val1, val2), + logger); + case KINDUCTION -> + checker = + BoundedCheckerBuilderKt.buildKIND( + monolithicExpr, + abstractionSolverFactory.createSolver(), + abstractionSolverFactory.createSolver(), + val -> StsToMonolithicExprKt.valToState(sts, val), + (val1, val2) -> + StsToMonolithicExprKt.valToAction(sts, val1, val2), + logger); + case IMC -> + checker = + BoundedCheckerBuilderKt.buildIMC( + monolithicExpr, + abstractionSolverFactory.createSolver(), + abstractionSolverFactory.createItpSolver(), + val -> StsToMonolithicExprKt.valToState(sts, val), + (val1, val2) -> + StsToMonolithicExprKt.valToAction(sts, val1, val2), + logger); default -> - throw new UnsupportedOperationException("Algorithm " + algorithm + " not supported"); + throw new UnsupportedOperationException( + "Algorithm " + algorithm + " not supported"); } return checker; } - private void printResult(final SafetyResult> status, final STS sts, - final long totalTimeMs) { - final CegarStatistics stats = (CegarStatistics) status.getStats().orElse(new CegarStatistics(0, 0, 0, 0)); + private void printResult( + final SafetyResult> status, + final STS sts, + final long totalTimeMs) { + final CegarStatistics stats = + (CegarStatistics) status.getStats().orElse(new CegarStatistics(0, 0, 0, 0)); if (benchmarkMode) { writer.cell(status.isSafe()); writer.cell(totalTimeMs); @@ -278,7 +323,7 @@ private void printResult(final SafetyResult> status, fi writer.cell(stats.getAbstractorTimeMs()); writer.cell(stats.getRefinerTimeMs()); writer.cell(stats.getIterations()); - if (status.getWitness() instanceof ARG arg) { + if (status.getProof() instanceof ARG arg) { writer.cell(arg.size()); writer.cell(arg.getDepth()); writer.cell(arg.getMeanBranchingFactor()); @@ -304,7 +349,10 @@ private void printError(final Throwable ex) { writer.cell("[EX] " + ex.getClass().getSimpleName() + ": " + message); writer.newRow(); } else { - logger.write(Level.RESULT, "%s occurred, message: %s%n", ex.getClass().getSimpleName(), + logger.write( + Level.RESULT, + "%s occurred, message: %s%n", + ex.getClass().getSimpleName(), message); if (stacktrace) { final StringWriter errors = new StringWriter(); @@ -318,9 +366,10 @@ private void printError(final Throwable ex) { private void writeCex(final STS sts, final SafetyResult.Unsafe> status) throws FileNotFoundException { - @SuppressWarnings("unchecked") final Trace trace = (Trace) status.getCex(); - final Trace concrTrace = StsTraceConcretizer.concretize(sts, trace, - Z3LegacySolverFactory.getInstance()); + @SuppressWarnings("unchecked") + final Trace trace = (Trace) status.getCex(); + final Trace concrTrace = + StsTraceConcretizer.concretize(sts, trace, Z3LegacySolverFactory.getInstance()); final File file = new File(cexfile); PrintWriter printWriter = null; try { diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt index 6ffa9bc1fb..72f7a2520e 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/oc/XcfaOcChecker.kt @@ -13,15 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.analysis.oc -import hu.bme.mit.theta.analysis.EmptyCex import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.algorithm.arg.ARG import hu.bme.mit.theta.analysis.algorithm.oc.EventType import hu.bme.mit.theta.analysis.algorithm.oc.OcChecker import hu.bme.mit.theta.analysis.algorithm.oc.Relation @@ -52,335 +49,363 @@ import hu.bme.mit.theta.xcfa.passes.AssumeFalseRemovalPass import hu.bme.mit.theta.xcfa.passes.AtomicReadsOneWritePass import hu.bme.mit.theta.xcfa.passes.MutexToVarPass -private val Expr<*>.vars get() = ExprUtils.getVars(this) +private val Expr<*>.vars + get() = ExprUtils.getVars(this) -class XcfaOcChecker(xcfa: XCFA, decisionProcedure: OcDecisionProcedureType, private val logger: Logger) : - SafetyChecker>, XcfaAction>, XcfaPrec> { +class XcfaOcChecker( + xcfa: XCFA, + decisionProcedure: OcDecisionProcedureType, + private val logger: Logger, +) : SafetyChecker>, XcfaAction>, XcfaPrec> { - private val ocChecker: OcChecker = decisionProcedure.checker() - private val solver = ocChecker.solver + private val ocChecker: OcChecker = decisionProcedure.checker() + private val solver = ocChecker.solver - private val xcfa: XCFA = xcfa.optimizeFurther( - listOf(AssumeFalseRemovalPass(), MutexToVarPass(), AtomicReadsOneWritePass()) + private val xcfa: XCFA = + xcfa.optimizeFurther( + listOf(AssumeFalseRemovalPass(), MutexToVarPass(), AtomicReadsOneWritePass()) ) - private var indexing = VarIndexingFactory.indexing(0) - private val localVars = mutableMapOf, MutableMap>>() - - private val threads = mutableSetOf() - private val events = mutableMapOf, MutableMap>>() - private val violations = mutableListOf() // OR! - private val branchingConditions = mutableListOf>() - private val pos = mutableListOf() - private val rfs = mutableMapOf, MutableSet>() - - override fun check( - prec: XcfaPrec?): SafetyResult>, XcfaAction>> = let { - if (xcfa.initProcedures.size > 1) error("Multiple entry points are not supported by OC checker.") + private var indexing = VarIndexingFactory.indexing(0) + private val localVars = mutableMapOf, MutableMap>>() + + private val threads = mutableSetOf() + private val events = mutableMapOf, MutableMap>>() + private val violations = mutableListOf() // OR! + private val branchingConditions = mutableListOf>() + private val pos = mutableListOf() + private val rfs = mutableMapOf, MutableSet>() + + override fun check( + prec: XcfaPrec? + ): SafetyResult>, XcfaAction>> = + let { + if (xcfa.initProcedures.size > 1) + error("Multiple entry points are not supported by OC checker.") logger.write(Logger.Level.MAINSTEP, "Adding constraints...\n") xcfa.initProcedures.forEach { processThread(Thread(it.first)) } addCrossThreadRelations() - if (!addToSolver()) return@let SafetyResult.safe>, XcfaAction>>( - EmptyWitness.getInstance()) // no violations in the model + if (!addToSolver()) + return@let SafetyResult.safe>, XcfaAction>>( + EmptyProof.getInstance() + ) // no violations in the model logger.write(Logger.Level.MAINSTEP, "Start checking...\n") val status = ocChecker.check(events, pos, rfs) when { - status?.isUnsat == true -> SafetyResult.safe(EmptyWitness.getInstance()) - status?.isSat == true -> SafetyResult.unsafe( - XcfaOcTraceExtractor(xcfa, ocChecker, threads, events, violations, pos).trace, - EmptyWitness.getInstance() + status?.isUnsat == true -> SafetyResult.safe(EmptyProof.getInstance()) + status?.isSat == true -> + SafetyResult.unsafe( + XcfaOcTraceExtractor(xcfa, ocChecker, threads, events, violations, pos).trace, + EmptyProof.getInstance(), ) - else -> SafetyResult.unknown() + else -> SafetyResult.unknown() } - }.also { logger.write(Logger.Level.MAINSTEP, "OC checker result: $it\n") } - - private fun processThread(thread: Thread): List { - threads.add(thread) - val pid = thread.pid - var last = listOf() - var guard = setOf>() - lateinit var lastWrites: MutableMap, Set> - lateinit var edge: XcfaEdge - var inEdge = false - var atomicEntered: Boolean? = null - - val newEvent: (VarDecl<*>, EventType) -> List = { d, type -> - check(!inEdge || last.size == 1) - val decl = d.threadVar(pid) - val useLastClk = inEdge || atomicEntered == true - val e = - if (useLastClk) E(decl.getNewIndexed(), type, guard, pid, edge, last.first().clkId) - else E(decl.getNewIndexed(), type, guard, pid, edge) - last.forEach { po(it, e) } - inEdge = true - if (atomicEntered == false) atomicEntered = true - when (type) { - EventType.READ -> lastWrites[decl]?.forEach { rfs.add(RelationType.RF, it, e) } - EventType.WRITE -> lastWrites[decl] = setOf(e) - } - events[decl] = (events[decl] ?: mutableMapOf()).apply { - this[pid] = (this[pid] ?: mutableListOf()).apply { add(e) } - } - listOf(e) + } + .also { logger.write(Logger.Level.MAINSTEP, "OC checker result: $it\n") } + + private fun processThread(thread: Thread): List { + threads.add(thread) + val pid = thread.pid + var last = listOf() + var guard = setOf>() + lateinit var lastWrites: MutableMap, Set> + lateinit var edge: XcfaEdge + var inEdge = false + var atomicEntered: Boolean? = null + + val newEvent: (VarDecl<*>, EventType) -> List = { d, type -> + check(!inEdge || last.size == 1) + val decl = d.threadVar(pid) + val useLastClk = inEdge || atomicEntered == true + val e = + if (useLastClk) E(decl.getNewIndexed(), type, guard, pid, edge, last.first().clkId) + else E(decl.getNewIndexed(), type, guard, pid, edge) + last.forEach { po(it, e) } + inEdge = true + if (atomicEntered == false) atomicEntered = true + when (type) { + EventType.READ -> lastWrites[decl]?.forEach { rfs.add(RelationType.RF, it, e) } + EventType.WRITE -> lastWrites[decl] = setOf(e) + } + events[decl] = + (events[decl] ?: mutableMapOf()).apply { + this[pid] = (this[pid] ?: mutableListOf()).apply { add(e) } } + listOf(e) + } - val waitList = mutableSetOf() - val toVisit = mutableSetOf(SearchItem(thread.procedure.initLoc).apply { - guards.add(thread.guard) - thread.startEvent?.let { lastEvents.add(it) } - this.lastWrites.add(thread.lastWrites) - }) - val threads = mutableListOf() - - while (toVisit.isNotEmpty()) { - val current = toVisit.first() - toVisit.remove(current) - check(current.incoming == current.loc.incomingEdges.size) - check(current.incoming == current.guards.size || current.loc.initial) - // lastEvents intentionally skipped - check(current.incoming == current.lastWrites.size || current.loc.initial) - check(current.incoming == current.threadLookups.size) - check(current.incoming == current.atomics.size) - check(current.atomics.all { it == current.atomics.first() }) // bad pattern otherwise - - if (current.loc.error) { - val errorGuard = Or(current.lastEvents.map { it.guard.toAnd() }) - violations.add(Violation(current.loc, pid, errorGuard, current.lastEvents)) - continue - } - - if (current.loc.final) { - thread.finalEvents.addAll(current.lastEvents) + val waitList = mutableSetOf() + val toVisit = + mutableSetOf( + SearchItem(thread.procedure.initLoc).apply { + guards.add(thread.guard) + thread.startEvent?.let { lastEvents.add(it) } + this.lastWrites.add(thread.lastWrites) + } + ) + val threads = mutableListOf() + + while (toVisit.isNotEmpty()) { + val current = toVisit.first() + toVisit.remove(current) + check(current.incoming == current.loc.incomingEdges.size) + check(current.incoming == current.guards.size || current.loc.initial) + // lastEvents intentionally skipped + check(current.incoming == current.lastWrites.size || current.loc.initial) + check(current.incoming == current.threadLookups.size) + check(current.incoming == current.atomics.size) + check(current.atomics.all { it == current.atomics.first() }) // bad pattern otherwise + + if (current.loc.error) { + val errorGuard = Or(current.lastEvents.map { it.guard.toAnd() }) + violations.add(Violation(current.loc, pid, errorGuard, current.lastEvents)) + continue + } + + if (current.loc.final) { + thread.finalEvents.addAll(current.lastEvents) + } + + val mergedGuard = current.guards.toOrInSet() + val assumeConsts = mutableMapOf, MutableList>>() + + for (e in current.loc.outgoingEdges) { + edge = e + inEdge = false + last = current.lastEvents + // intersection of guards of incoming edges: + guard = mergedGuard + lastWrites = current.lastWrites.merge().toMutableMap() + val threadLookup = + current.threadLookups + .merge { s1, s2 -> + s1 + s2.filter { (guard2, _) -> s1.none { (guard1, _) -> guard1 == guard2 } } } + .toMutableMap() + var firstLabel = true + atomicEntered = current.atomics.firstOrNull() + + edge.getFlatLabels().forEach { label -> + if (label.references.isNotEmpty() || label.dereferences.isNotEmpty()) { + error("References not supported by OC checker.") + } + when (label) { + is StmtLabel -> { + when (val stmt = label.stmt) { + is AssignStmt<*> -> { + val consts = mutableMapOf, ConstDecl<*>>() + stmt.expr.vars.forEach { + last = newEvent(it, EventType.READ) + consts[it] = last.first().const + } + last = newEvent(stmt.varDecl, EventType.WRITE) + last.first().assignment = Eq(last.first().const.ref, stmt.expr.withConsts(consts)) + } - val mergedGuard = current.guards.toOrInSet() - val assumeConsts = mutableMapOf, MutableList>>() - - for (e in current.loc.outgoingEdges) { - edge = e - inEdge = false - last = current.lastEvents - // intersection of guards of incoming edges: - guard = mergedGuard - lastWrites = current.lastWrites.merge().toMutableMap() - val threadLookup = current.threadLookups.merge { s1, s2 -> - s1 + s2.filter { (guard2, _) -> s1.none { (guard1, _) -> guard1 == guard2 } } - }.toMutableMap() - var firstLabel = true - atomicEntered = current.atomics.firstOrNull() - - edge.getFlatLabels().forEach { label -> - if (label.references.isNotEmpty() || label.dereferences.isNotEmpty()) { - error("References not supported by OC checker.") - } - when (label) { - is StmtLabel -> { - when (val stmt = label.stmt) { - is AssignStmt<*> -> { - val consts = mutableMapOf, ConstDecl<*>>() - stmt.expr.vars.forEach { - last = newEvent(it, EventType.READ) - consts[it] = last.first().const - } - last = newEvent(stmt.varDecl, EventType.WRITE) - last.first().assignment = Eq(last.first().const.ref, stmt.expr.withConsts(consts)) - } - - is AssumeStmt -> { - val consts = stmt.cond.vars.associateWith { it.threadVar(pid).getNewIndexed(false) } - val condWithConsts = stmt.cond.withConsts(consts) - val asAssign = consts.size == 1 && consts.keys.first().threadVar(pid) !in lastWrites - if (edge.source.outgoingEdges.size > 1 || !asAssign) { - guard = guard + condWithConsts - if (firstLabel) { - consts.forEach { (v, c) -> - assumeConsts.getOrPut(v) { mutableListOf() }.add(c) - } - } - } - stmt.cond.vars.forEach { - last = newEvent(it, EventType.READ) - } - if (edge.source.outgoingEdges.size == 1 && asAssign) { - last.first().assignment = condWithConsts - } - } - - is HavocStmt<*> -> { - last = newEvent(stmt.varDecl, EventType.WRITE) - } - - else -> error("Unsupported statement type: $stmt") - } - } - - is StartLabel -> { - // TODO StartLabel params - if (label.name in thread.startHistory) { - error("Recursive thread start not supported by OC checker.") - } - val procedure = xcfa.procedures.find { it.name == label.name } - ?: error("Procedure not found: ${label.name}") - last = newEvent(label.pidVar, EventType.WRITE) - val pidVar = label.pidVar.threadVar(pid) - if (this.threads.any { it.pidVar == pidVar }) { - error("Using a pthread_t variable in multiple threads is not supported by OC checker.") - } - val newHistory = thread.startHistory + thread.procedure.name - val newThread = Thread(procedure, guard, pidVar, last.first(), newHistory, lastWrites) - last.first().assignment = Eq(last.first().const.ref, Int(newThread.pid)) - threadLookup[pidVar] = setOf(Pair(guard, newThread)) - processThread(newThread) - } - - is JoinLabel -> { - val incomingGuard = guard - val lastEvents = mutableListOf() - val joinGuards = mutableListOf>>() - threadLookup[label.pidVar.threadVar(pid)]?.forEach { (g, thread) -> - guard = incomingGuard + g + thread.finalEvents.map { it.guard }.toOrInSet() - val joinEvent = newEvent(label.pidVar, EventType.READ).first() - thread.finalEvents.forEach { final -> po(final, joinEvent) } - lastEvents.add(joinEvent) - joinGuards.add(guard) - } ?: error("Thread started in a different thread: not supported by OC checker.") - guard = joinGuards.toOrInSet() - last = lastEvents - } - - is FenceLabel -> { - if (label.labels.size > 1 || label.labels.firstOrNull()?.contains("ATOMIC") != true) { - error("Untransformed fence label: $label") - } - if (label.isAtomicBegin) atomicEntered = false - if (label.isAtomicEnd) atomicEntered = null - } - - is NopLabel -> {} - else -> error("Unsupported label type by OC checker: $label") + is AssumeStmt -> { + val consts = + stmt.cond.vars.associateWith { it.threadVar(pid).getNewIndexed(false) } + val condWithConsts = stmt.cond.withConsts(consts) + val asAssign = + consts.size == 1 && consts.keys.first().threadVar(pid) !in lastWrites + if (edge.source.outgoingEdges.size > 1 || !asAssign) { + guard = guard + condWithConsts + if (firstLabel) { + consts.forEach { (v, c) -> + assumeConsts.getOrPut(v) { mutableListOf() }.add(c) + } } - firstLabel = false + } + stmt.cond.vars.forEach { last = newEvent(it, EventType.READ) } + if (edge.source.outgoingEdges.size == 1 && asAssign) { + last.first().assignment = condWithConsts + } } - val searchItem = waitList.find { it.loc == edge.target } - ?: SearchItem(edge.target).apply { waitList.add(this) } - searchItem.guards.add(guard) - searchItem.lastEvents.addAll(last) - searchItem.lastWrites.add(lastWrites) - searchItem.threadLookups.add(threadLookup) - searchItem.atomics.add(atomicEntered) - searchItem.incoming++ - if (searchItem.incoming == searchItem.loc.incomingEdges.size) { - waitList.remove(searchItem) - toVisit.add(searchItem) + is HavocStmt<*> -> { + last = newEvent(stmt.varDecl, EventType.WRITE) } - } - if (current.loc.outgoingEdges.size > 1) { - for (e in current.loc.outgoingEdges) { - val first = e.getFlatLabels().first() - if (first !is StmtLabel || first.stmt !is AssumeStmt) { - error("Branching with non-assume labels not supported by OC checker.") - } - } - assumeConsts.forEach { (_, set) -> - for ((i1, v1) in set.withIndex()) - for ((i2, v2) in set.withIndex()) { - if (i1 == i2) break - branchingConditions.add(Eq(v1.ref, v2.ref)) - } - } + else -> error("Unsupported statement type: $stmt") + } } - } - if (waitList.isNotEmpty()) error("Loops and dangling edges not supported by OC checker.") - return threads - } + is StartLabel -> { + // TODO StartLabel params + if (label.name in thread.startHistory) { + error("Recursive thread start not supported by OC checker.") + } + val procedure = + xcfa.procedures.find { it.name == label.name } + ?: error("Procedure not found: ${label.name}") + last = newEvent(label.pidVar, EventType.WRITE) + val pidVar = label.pidVar.threadVar(pid) + if (this.threads.any { it.pidVar == pidVar }) { + error( + "Using a pthread_t variable in multiple threads is not supported by OC checker." + ) + } + val newHistory = thread.startHistory + thread.procedure.name + val newThread = Thread(procedure, guard, pidVar, last.first(), newHistory, lastWrites) + last.first().assignment = Eq(last.first().const.ref, Int(newThread.pid)) + threadLookup[pidVar] = setOf(Pair(guard, newThread)) + processThread(newThread) + } - private fun addCrossThreadRelations() { - for ((_, map) in events) - for ((pid1, list1) in map) - for ((pid2, list2) in map) - if (pid1 != pid2) - for (e1 in list1.filter { it.type == EventType.WRITE }) - for (e2 in list2.filter { it.type == EventType.READ }) - rfs.add(RelationType.RF, e1, e2) - } + is JoinLabel -> { + val incomingGuard = guard + val lastEvents = mutableListOf() + val joinGuards = mutableListOf>>() + threadLookup[label.pidVar.threadVar(pid)]?.forEach { (g, thread) -> + guard = incomingGuard + g + thread.finalEvents.map { it.guard }.toOrInSet() + val joinEvent = newEvent(label.pidVar, EventType.READ).first() + thread.finalEvents.forEach { final -> po(final, joinEvent) } + lastEvents.add(joinEvent) + joinGuards.add(guard) + } ?: error("Thread started in a different thread: not supported by OC checker.") + guard = joinGuards.toOrInSet() + last = lastEvents + } - private fun addToSolver(): Boolean { - if (violations.isEmpty()) return false + is FenceLabel -> { + if (label.labels.size > 1 || label.labels.firstOrNull()?.contains("ATOMIC") != true) { + error("Untransformed fence label: $label") + } + if (label.isAtomicBegin) atomicEntered = false + if (label.isAtomicEnd) atomicEntered = null + } - // Value assignment - events.values.flatMap { it.values.flatten() }.filter { it.assignment != null }.forEach { event -> - if (event.guard.isEmpty()) solver.add(event.assignment) - else solver.add(Imply(event.guardExpr, event.assignment)) + is NopLabel -> {} + else -> error("Unsupported label type by OC checker: $label") + } + firstLabel = false } - // Branching conditions - branchingConditions.forEach { solver.add(it) } - - // Property violation - solver.add(Or(violations.map { it.guard })) - - // RF - rfs.forEach { (_, list) -> - list.groupBy { it.to }.forEach { (event, rels) -> - rels.forEach { rel -> - solver.add( - Imply( - rel.declRef, - And(rel.from.guardExpr, rel.to.guardExpr, Eq(rel.from.const.ref, rel.to.const.ref)) - ) - ) // RF-Val - } - solver.add(Imply(event.guardExpr, Or(rels.map { it.declRef }))) // RF-Some - } + val searchItem = + waitList.find { it.loc == edge.target } + ?: SearchItem(edge.target).apply { waitList.add(this) } + searchItem.guards.add(guard) + searchItem.lastEvents.addAll(last) + searchItem.lastWrites.add(lastWrites) + searchItem.threadLookups.add(threadLookup) + searchItem.atomics.add(atomicEntered) + searchItem.incoming++ + if (searchItem.incoming == searchItem.loc.incomingEdges.size) { + waitList.remove(searchItem) + toVisit.add(searchItem) } - - return true - } - - // Utility functions - - private fun po(from: E?, to: E) { - from ?: return - pos.add(Relation(RelationType.PO, from, to)) + } + + if (current.loc.outgoingEdges.size > 1) { + for (e in current.loc.outgoingEdges) { + val first = e.getFlatLabels().first() + if (first !is StmtLabel || first.stmt !is AssumeStmt) { + error("Branching with non-assume labels not supported by OC checker.") + } + } + assumeConsts.forEach { (_, set) -> + for ((i1, v1) in set.withIndex()) for ((i2, v2) in set.withIndex()) { + if (i1 == i2) break + branchingConditions.add(Eq(v1.ref, v2.ref)) + } + } + } } - private fun List>>.merge(merge: (Set, Set) -> Set = { a, b -> a + b }) = - reduce(mapOf()) { acc, map -> - (acc.keys + map.keys).associateWith { k -> - val set1 = acc[k] ?: setOf() - val set2 = map[k] ?: setOf() - merge(set1, set2) - } + if (waitList.isNotEmpty()) error("Loops and dangling edges not supported by OC checker.") + return threads + } + + private fun addCrossThreadRelations() { + for ((_, map) in events) for ((pid1, list1) in map) for ((pid2, list2) in map) if (pid1 != pid2) + for (e1 in list1.filter { it.type == EventType.WRITE }) for (e2 in + list2.filter { it.type == EventType.READ }) rfs.add(RelationType.RF, e1, e2) + } + + private fun addToSolver(): Boolean { + if (violations.isEmpty()) return false + + // Value assignment + events.values + .flatMap { it.values.flatten() } + .filter { it.assignment != null } + .forEach { event -> + if (event.guard.isEmpty()) solver.add(event.assignment) + else solver.add(Imply(event.guardExpr, event.assignment)) + } + + // Branching conditions + branchingConditions.forEach { solver.add(it) } + + // Property violation + solver.add(Or(violations.map { it.guard })) + + // RF + rfs.forEach { (_, list) -> + list + .groupBy { it.to } + .forEach { (event, rels) -> + rels.forEach { rel -> + solver.add( + Imply( + rel.declRef, + And(rel.from.guardExpr, rel.to.guardExpr, Eq(rel.from.const.ref, rel.to.const.ref)), + ) + ) // RF-Val + } + solver.add(Imply(event.guardExpr, Or(rels.map { it.declRef }))) // RF-Some } + } - private inline fun Collection.reduce(default: T, operation: (T, T) -> T): T = - if (isEmpty()) default else reduce(operation) + return true + } + + // Utility functions + + private fun po(from: E?, to: E) { + from ?: return + pos.add(Relation(RelationType.PO, from, to)) + } + + private fun List>>.merge( + merge: (Set, Set) -> Set = { a, b -> a + b } + ) = + reduce(mapOf()) { acc, map -> + (acc.keys + map.keys).associateWith { k -> + val set1 = acc[k] ?: setOf() + val set2 = map[k] ?: setOf() + merge(set1, set2) + } + } - private fun MutableMap, MutableSet>.add(type: RelationType, from: E, to: E) = - getOrPut(from.const.varDecl) { mutableSetOf() }.add(Relation(type, from, to)) + private inline fun Collection.reduce(default: T, operation: (T, T) -> T): T = + if (isEmpty()) default else reduce(operation) - private fun Expr.withConsts(varToConst: Map, ConstDecl<*>>): Expr { - if (this is RefExpr) { - return varToConst[decl]?.ref?.let { cast(it, type) } ?: this - } - return map { it.withConsts(varToConst) } - } + private fun MutableMap, MutableSet>.add(type: RelationType, from: E, to: E) = + getOrPut(from.const.varDecl) { mutableSetOf() }.add(Relation(type, from, to)) - private fun VarDecl.threadVar(pid: Int): VarDecl = - if (xcfa.vars.none { it.wrappedVar == this && !it.threadLocal }) { // if not global var - cast(localVars.getOrPut(this) { mutableMapOf() }.getOrPut(pid) { - Decls.Var("t$pid::$name", type) - }, type) - } else this - - private fun VarDecl.getNewIndexed(increment: Boolean = true): IndexedConstDecl { - val constDecl = getConstDecl(indexing.get(this)) - if (increment) indexing = indexing.inc(this) - return constDecl + private fun Expr.withConsts(varToConst: Map, ConstDecl<*>>): Expr { + if (this is RefExpr) { + return varToConst[decl]?.ref?.let { cast(it, type) } ?: this } + return map { it.withConsts(varToConst) } + } + + private fun VarDecl.threadVar(pid: Int): VarDecl = + if (xcfa.vars.none { it.wrappedVar == this && !it.threadLocal }) { // if not global var + cast( + localVars + .getOrPut(this) { mutableMapOf() } + .getOrPut(pid) { Decls.Var("t$pid::$name", type) }, + type, + ) + } else this + + private fun VarDecl.getNewIndexed(increment: Boolean = true): IndexedConstDecl { + val constDecl = getConstDecl(indexing.get(this)) + if (increment) indexing = indexing.inc(this) + return constDecl + } } diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt index 9469c2eca3..c7027914fc 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/ExecuteConfig.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli import com.google.common.base.Stopwatch @@ -23,7 +22,7 @@ import hu.bme.mit.theta.analysis.Action import hu.bme.mit.theta.analysis.EmptyCex import hu.bme.mit.theta.analysis.State import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.arg.ARG import hu.bme.mit.theta.analysis.algorithm.arg.debug.ARGWebDebugger @@ -68,318 +67,379 @@ import java.util.concurrent.TimeUnit import kotlin.random.Random fun runConfig( - config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger, - throwDontExit: Boolean + config: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger, + throwDontExit: Boolean, ): SafetyResult<*, *> { - propagateInputOptions(config, logger, uniqueLogger) + propagateInputOptions(config, logger, uniqueLogger) - registerAllSolverManagers(config.backendConfig.solverHome, logger) + registerAllSolverManagers(config.backendConfig.solverHome, logger) - validateInputOptions(config, logger, uniqueLogger) + validateInputOptions(config, logger, uniqueLogger) - val (xcfa, mcm, parseContext) = frontend(config, logger, uniqueLogger) + val (xcfa, mcm, parseContext) = frontend(config, logger, uniqueLogger) - preVerificationLogging(xcfa, mcm, parseContext, config, logger, uniqueLogger) + preVerificationLogging(xcfa, mcm, parseContext, config, logger, uniqueLogger) - val result = backend(xcfa, mcm, parseContext, config, logger, uniqueLogger, throwDontExit) + val result = backend(xcfa, mcm, parseContext, config, logger, uniqueLogger, throwDontExit) - postVerificationLogging(result, mcm, parseContext, config, logger, uniqueLogger) + postVerificationLogging(result, mcm, parseContext, config, logger, uniqueLogger) - return result + return result } - private fun propagateInputOptions(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger) { - config.inputConfig.property = determineProperty(config, logger) - LbePass.level = config.frontendConfig.lbeLevel - StaticCoiPass.enabled = config.frontendConfig.staticCoi - if (config.backendConfig.backend == Backend.CEGAR) { - val cegarConfig = config.backendConfig.specConfig - cegarConfig as CegarConfig - val random = Random(cegarConfig.porRandomSeed) - XcfaSporLts.random = random - XcfaDporLts.random = random - } - if (config.debugConfig.argToFile) { - WebDebuggerLogger.enableWebDebuggerLogger() - WebDebuggerLogger.getInstance().setTitle(config.inputConfig.input?.name) - } - - LoopUnrollPass.UNROLL_LIMIT = config.frontendConfig.loopUnroll - LoopUnrollPass.FORCE_UNROLL_LIMIT = config.frontendConfig.forceUnroll - FetchExecuteWriteback.enabled = config.frontendConfig.enableFew - ARGWebDebugger.on = config.debugConfig.argdebug + config.inputConfig.property = determineProperty(config, logger) + LbePass.level = config.frontendConfig.lbeLevel + StaticCoiPass.enabled = config.frontendConfig.staticCoi + if (config.backendConfig.backend == Backend.CEGAR) { + val cegarConfig = config.backendConfig.specConfig + cegarConfig as CegarConfig + val random = Random(cegarConfig.porRandomSeed) + XcfaSporLts.random = random + XcfaDporLts.random = random + } + if (config.debugConfig.argToFile) { + WebDebuggerLogger.enableWebDebuggerLogger() + WebDebuggerLogger.getInstance().setTitle(config.inputConfig.input?.name) + } + + LoopUnrollPass.UNROLL_LIMIT = config.frontendConfig.loopUnroll + LoopUnrollPass.FORCE_UNROLL_LIMIT = config.frontendConfig.forceUnroll + FetchExecuteWriteback.enabled = config.frontendConfig.enableFew + ARGWebDebugger.on = config.debugConfig.argdebug } private fun validateInputOptions(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger) { - rule("NoCoiWhenDataRace") { - config.backendConfig.backend == Backend.CEGAR && - (config.backendConfig.specConfig as? CegarConfig)?.coi != ConeOfInfluenceMode.NO_COI && - config.inputConfig.property == ErrorDetection.DATA_RACE - } - rule("NoAaporWhenDataRace") { - (config.backendConfig.specConfig as? CegarConfig)?.porLevel?.isAbstractionAware == true && - config.inputConfig.property == ErrorDetection.DATA_RACE - } - rule("DPORWithoutDFS") { - (config.backendConfig.specConfig as? CegarConfig)?.porLevel?.isDynamic == true && - (config.backendConfig.specConfig as? CegarConfig)?.abstractorConfig?.search != Search.DFS - } - rule("SensibleLoopUnrollLimits") { - config.frontendConfig.loopUnroll != -1 && config.frontendConfig.loopUnroll < config.frontendConfig.forceUnroll - } - rule("NoPredSplitUntilFixed(https://github.com/ftsrg/theta/issues/267)") { - (config.backendConfig.specConfig as? CegarConfig)?.abstractorConfig?.domain == Domain.PRED_SPLIT - } + rule("NoCoiWhenDataRace") { + config.backendConfig.backend == Backend.CEGAR && + (config.backendConfig.specConfig as? CegarConfig)?.coi != ConeOfInfluenceMode.NO_COI && + config.inputConfig.property == ErrorDetection.DATA_RACE + } + rule("NoAaporWhenDataRace") { + (config.backendConfig.specConfig as? CegarConfig)?.porLevel?.isAbstractionAware == true && + config.inputConfig.property == ErrorDetection.DATA_RACE + } + rule("DPORWithoutDFS") { + (config.backendConfig.specConfig as? CegarConfig)?.porLevel?.isDynamic == true && + (config.backendConfig.specConfig as? CegarConfig)?.abstractorConfig?.search != Search.DFS + } + rule("SensibleLoopUnrollLimits") { + config.frontendConfig.loopUnroll != -1 && + config.frontendConfig.loopUnroll < config.frontendConfig.forceUnroll + } + rule("NoPredSplitUntilFixed(https://github.com/ftsrg/theta/issues/267)") { + (config.backendConfig.specConfig as? CegarConfig)?.abstractorConfig?.domain == Domain.PRED_SPLIT + } } -fun frontend(config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger): Triple { - if (config.inputConfig.xcfaWCtx != null) { - val xcfa = config.inputConfig.xcfaWCtx!!.first - ConeOfInfluence = if (config.inputConfig.xcfaWCtx!!.third.multiThreading) { - XcfaCoiMultiThread(xcfa) - } else { - XcfaCoiSingleThread(xcfa) - } - return config.inputConfig.xcfaWCtx!! - } - - val stopwatch = Stopwatch.createStarted() - - val input = config.inputConfig.input!! - logger.write(Logger.Level.INFO, "Parsing the input $input as ${config.frontendConfig.inputType}\n") - - val parseContext = ParseContext() - - if (config.frontendConfig.inputType == InputType.C) { - val cConfig = config.frontendConfig.specConfig - cConfig as CFrontendConfig - parseContext.arithmetic = cConfig.arithmetic - parseContext.architecture = cConfig.architecture - } - - val xcfa = getXcfa(config, parseContext, logger, uniqueLogger) - - val mcm = if (config.inputConfig.catFile != null) { - CatDslManager.createMCM(config.inputConfig.catFile!!) +fun frontend( + config: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger, +): Triple { + if (config.inputConfig.xcfaWCtx != null) { + val xcfa = config.inputConfig.xcfaWCtx!!.first + ConeOfInfluence = + if (config.inputConfig.xcfaWCtx!!.third.multiThreading) { + XcfaCoiMultiThread(xcfa) + } else { + XcfaCoiSingleThread(xcfa) + } + return config.inputConfig.xcfaWCtx!! + } + + val stopwatch = Stopwatch.createStarted() + + val input = config.inputConfig.input!! + logger.write( + Logger.Level.INFO, + "Parsing the input $input as ${config.frontendConfig.inputType}\n", + ) + + val parseContext = ParseContext() + + if (config.frontendConfig.inputType == InputType.C) { + val cConfig = config.frontendConfig.specConfig + cConfig as CFrontendConfig + parseContext.arithmetic = cConfig.arithmetic + parseContext.architecture = cConfig.architecture + } + + val xcfa = getXcfa(config, parseContext, logger, uniqueLogger) + + val mcm = + if (config.inputConfig.catFile != null) { + CatDslManager.createMCM(config.inputConfig.catFile!!) } else { - emptySet() - } - - ConeOfInfluence = if (parseContext.multiThreading) XcfaCoiMultiThread(xcfa) else XcfaCoiSingleThread(xcfa) - - if (parseContext.multiThreading && (config.backendConfig.specConfig as? CegarConfig)?.let { it.abstractorConfig.search == Search.ERR } == true) { - val cConfig = config.backendConfig.specConfig as CegarConfig - cConfig.abstractorConfig.search = Search.DFS - uniqueLogger.write(INFO, "Multithreaded program found, using DFS instead of ERR.") + emptySet() } - logger.write( - Logger.Level.INFO, "Frontend finished: ${xcfa.name} (in ${ + ConeOfInfluence = + if (parseContext.multiThreading) XcfaCoiMultiThread(xcfa) else XcfaCoiSingleThread(xcfa) + + if ( + parseContext.multiThreading && + (config.backendConfig.specConfig as? CegarConfig)?.let { + it.abstractorConfig.search == Search.ERR + } == true + ) { + val cConfig = config.backendConfig.specConfig as CegarConfig + cConfig.abstractorConfig.search = Search.DFS + uniqueLogger.write(INFO, "Multithreaded program found, using DFS instead of ERR.") + } + + logger.write( + Logger.Level.INFO, + "Frontend finished: ${xcfa.name} (in ${ stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" - ) + } ms)\n", + ) - logger.write(RESULT, "ParsingResult Success\n") - logger.write(RESULT, - "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n") + logger.write(RESULT, "ParsingResult Success\n") + logger.write( + RESULT, + "Alias graph size: ${xcfa.pointsToGraph.size} -> ${xcfa.pointsToGraph.values.map { it.size }.toList()}\n", + ) - return Triple(xcfa, mcm, parseContext) + return Triple(xcfa, mcm, parseContext) } private fun backend( - xcfa: XCFA, mcm: MCM, parseContext: ParseContext, config: XcfaConfig<*, *>, - logger: Logger, - uniqueLogger: Logger, - throwDontExit: Boolean + xcfa: XCFA, + mcm: MCM, + parseContext: ParseContext, + config: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger, + throwDontExit: Boolean, ): SafetyResult<*, *> = - if (config.backendConfig.backend == Backend.NONE) { - SafetyResult.unknown() + if (config.backendConfig.backend == Backend.NONE) { + SafetyResult.unknown() + } else { + if ( + xcfa.procedures.all { + it.errorLoc.isEmpty && config.inputConfig.property == ErrorDetection.ERROR_LOCATION + } + ) { + val result = SafetyResult.safe(EmptyProof.getInstance()) + logger.write(Logger.Level.INFO, "Input is trivially safe\n") + + logger.write(RESULT, result.toString() + "\n") + result } else { - if (xcfa.procedures.all { it.errorLoc.isEmpty && config.inputConfig.property == ErrorDetection.ERROR_LOCATION }) { - val result = SafetyResult.safe(EmptyWitness.getInstance()) - logger.write(Logger.Level.INFO, "Input is trivially safe\n") - - logger.write(RESULT, result.toString() + "\n") - result - } else { - val stopwatch = Stopwatch.createStarted() - - logger.write( - Logger.Level.INFO, - "Starting verification of ${if (xcfa.name == "") "UnnamedXcfa" else xcfa.name} using ${config.backendConfig.backend}\n" - ) - - val checker = getChecker(xcfa, mcm, config, parseContext, logger, uniqueLogger) - val result = exitOnError(config.debugConfig.stacktrace, config.debugConfig.debug || throwDontExit) { - checker.check() - }.let { result -> - when { - result.isSafe && LoopUnrollPass.FORCE_UNROLL_USED -> { // cannot report safe if force unroll was used - logger.write(RESULT, "Incomplete loop unroll used: safe result is unreliable.\n") - SafetyResult.unknown() - } - - else -> result - } + val stopwatch = Stopwatch.createStarted() + + logger.write( + Logger.Level.INFO, + "Starting verification of ${if (xcfa.name == "") "UnnamedXcfa" else xcfa.name} using ${config.backendConfig.backend}\n", + ) + + val checker = getChecker(xcfa, mcm, config, parseContext, logger, uniqueLogger) + val result = + exitOnError(config.debugConfig.stacktrace, config.debugConfig.debug || throwDontExit) { + checker.check() + } + .let { result -> + when { + result.isSafe && + LoopUnrollPass.FORCE_UNROLL_USED -> { // cannot report safe if force unroll was used + logger.write(RESULT, "Incomplete loop unroll used: safe result is unreliable.\n") + SafetyResult.unknown() + } + + else -> result } + } - logger.write( - Logger.Level.INFO, "Backend finished (in ${ + logger.write( + Logger.Level.INFO, + "Backend finished (in ${ stopwatch.elapsed(TimeUnit.MILLISECONDS) - } ms)\n" - ) + } ms)\n", + ) - logger.write(RESULT, result.toString() + "\n") - result - } + logger.write(RESULT, result.toString() + "\n") + result } + } private fun preVerificationLogging( - xcfa: XCFA, mcm: MCM, parseContext: ParseContext, config: XcfaConfig<*, *>, - logger: Logger, uniqueLogger: Logger + xcfa: XCFA, + mcm: MCM, + parseContext: ParseContext, + config: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger, ) { - if (config.outputConfig.enableOutput) { - try { - val resultFolder = config.outputConfig.resultFolder - resultFolder.mkdirs() - - logger.write( - Logger.Level.INFO, - "Writing pre-verification artifacts to directory ${resultFolder.absolutePath}\n" - ) - - if (!config.outputConfig.chcOutputConfig.disable) { - xcfa.procedures.forEach { - try { - val chcFile = File(resultFolder, "xcfa-${it.name}.smt2") - chcFile.writeText(it.toSMT2CHC()) - } catch (e: Exception) { - logger.write(INFO, "Could not write CHC file: " + e.stackTraceToString()) - } - } - } + if (config.outputConfig.enableOutput) { + try { + val resultFolder = config.outputConfig.resultFolder + resultFolder.mkdirs() + + logger.write( + Logger.Level.INFO, + "Writing pre-verification artifacts to directory ${resultFolder.absolutePath}\n", + ) + + if (!config.outputConfig.chcOutputConfig.disable) { + xcfa.procedures.forEach { + try { + val chcFile = File(resultFolder, "xcfa-${it.name}.smt2") + chcFile.writeText(it.toSMT2CHC()) + } catch (e: Exception) { + logger.write(INFO, "Could not write CHC file: " + e.stackTraceToString()) + } + } + } - if (!config.outputConfig.xcfaOutputConfig.disable) { - val xcfaDotFile = File(resultFolder, "xcfa.dot") - xcfaDotFile.writeText(xcfa.toDot()) + if (!config.outputConfig.xcfaOutputConfig.disable) { + val xcfaDotFile = File(resultFolder, "xcfa.dot") + xcfaDotFile.writeText(xcfa.toDot()) - val xcfaJsonFile = File(resultFolder, "xcfa.json") - val uglyJson = getGson(xcfa).toJson(xcfa) - val create = GsonBuilder().setPrettyPrinting().create() - xcfaJsonFile.writeText(create.toJson(JsonParser.parseString(uglyJson))) - } + val xcfaJsonFile = File(resultFolder, "xcfa.json") + val uglyJson = getGson(xcfa).toJson(xcfa) + val create = GsonBuilder().setPrettyPrinting().create() + xcfaJsonFile.writeText(create.toJson(JsonParser.parseString(uglyJson))) + } - if (!config.outputConfig.cOutputConfig.disable) { - try { - val xcfaCFile = File(resultFolder, "xcfa.c") - xcfaCFile.writeText( - xcfa.toC( - parseContext, config.outputConfig.cOutputConfig.useArr, - config.outputConfig.cOutputConfig.useExArr, config.outputConfig.cOutputConfig.useRange - ) - ) - } catch (e: Throwable) { - logger.write(Logger.Level.VERBOSE, "Could not emit C file\n") - } - } + if (!config.outputConfig.cOutputConfig.disable) { + try { + val xcfaCFile = File(resultFolder, "xcfa.c") + xcfaCFile.writeText( + xcfa.toC( + parseContext, + config.outputConfig.cOutputConfig.useArr, + config.outputConfig.cOutputConfig.useExArr, + config.outputConfig.cOutputConfig.useRange, + ) + ) } catch (e: Throwable) { - logger.write(Logger.Level.INFO, "Could not output files: ${e.stackTraceToString()}\n") + logger.write(Logger.Level.VERBOSE, "Could not emit C file\n") } + } + } catch (e: Throwable) { + logger.write(Logger.Level.INFO, "Could not output files: ${e.stackTraceToString()}\n") } + } } private fun postVerificationLogging( - safetyResult: SafetyResult<*, *>, mcm: MCM, - parseContext: ParseContext, config: XcfaConfig<*, *>, logger: Logger, uniqueLogger: Logger + safetyResult: SafetyResult<*, *>, + mcm: MCM, + parseContext: ParseContext, + config: XcfaConfig<*, *>, + logger: Logger, + uniqueLogger: Logger, ) { - if (config.outputConfig.enableOutput) { - try { - // we only want to log the files if the current configuration is not --in-process or portfolio - if (config.backendConfig.inProcess || config.backendConfig.backend == Backend.PORTFOLIO) { - return - } - - val resultFolder = config.outputConfig.resultFolder - resultFolder.mkdirs() - - logger.write( - Logger.Level.INFO, - "Writing post-verification artifacts to directory ${resultFolder.absolutePath}\n" + if (config.outputConfig.enableOutput) { + try { + // we only want to log the files if the current configuration is not --in-process or portfolio + if (config.backendConfig.inProcess || config.backendConfig.backend == Backend.PORTFOLIO) { + return + } + + val resultFolder = config.outputConfig.resultFolder + resultFolder.mkdirs() + + logger.write( + Logger.Level.INFO, + "Writing post-verification artifacts to directory ${resultFolder.absolutePath}\n", + ) + + // TODO eliminate the need for the instanceof check + if ( + !config.outputConfig.argConfig.disable && safetyResult.proof is ARG? + ) { + val argFile = File(resultFolder, "arg-${safetyResult.isSafe}.dot") + val g: Graph = + ArgVisualizer.getDefault().visualize(safetyResult.proof as ARG?) + argFile.writeText(GraphvizWriter.getInstance().writeString(g)) + } + + if (!config.outputConfig.witnessConfig.disable) { + if ( + safetyResult.isUnsafe && + safetyResult.asUnsafe().cex != null && + !config.outputConfig.witnessConfig.svcomp + ) { + val concrTrace: Trace, XcfaAction> = + XcfaTraceConcretizer.concretize( + safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, + getSolver( + config.outputConfig.witnessConfig.concretizerSolver, + config.outputConfig.witnessConfig.validateConcretizerSolver, + ), + parseContext, ) - // TODO eliminate the need for the instanceof check - if (!config.outputConfig.argConfig.disable && safetyResult.witness is ARG?) { - val argFile = File(resultFolder, "arg-${safetyResult.isSafe}.dot") - val g: Graph = ArgVisualizer.getDefault().visualize(safetyResult.witness as ARG?) - argFile.writeText(GraphvizWriter.getInstance().writeString(g)) - } - - if (!config.outputConfig.witnessConfig.disable) { - if (safetyResult.isUnsafe && safetyResult.asUnsafe().cex != null && !config.outputConfig.witnessConfig.svcomp) { - val concrTrace: Trace, XcfaAction> = XcfaTraceConcretizer.concretize( - safetyResult.asUnsafe().cex as Trace>, XcfaAction>?, - getSolver( - config.outputConfig.witnessConfig.concretizerSolver, - config.outputConfig.witnessConfig.validateConcretizerSolver - ), - parseContext - ) - - val traceFile = File(resultFolder, "trace.dot") - val traceG: Graph = TraceVisualizer.getDefault().visualize(concrTrace) - traceFile.writeText(GraphvizWriter.getInstance().writeString(traceG)) - - val sequenceFile = File(resultFolder, "trace.plantuml") - writeSequenceTrace(sequenceFile, - safetyResult.asUnsafe().cex as Trace, XcfaAction>) { (_, act) -> - act.label.getFlatLabels().map(XcfaLabel::toString) - } - - val optSequenceFile = File(resultFolder, "trace-optimized.plantuml") - writeSequenceTrace(optSequenceFile, concrTrace) { (_, act) -> - act.label.getFlatLabels().map(XcfaLabel::toString) - } - - val cSequenceFile = File(resultFolder, "trace-c.plantuml") - writeSequenceTrace(cSequenceFile, concrTrace) { (state, act) -> - val proc = state.processes[act.pid] - val loc = proc?.locs?.peek() - (loc?.metadata as? CMetaData)?.sourceText?.split("\n") ?: listOf("") - } - } - val witnessFile = File(resultFolder, "witness.graphml") - XcfaWitnessWriter().writeWitness( - safetyResult, config.inputConfig.input!!, - getSolver( - config.outputConfig.witnessConfig.concretizerSolver, - config.outputConfig.witnessConfig.validateConcretizerSolver - ), parseContext, witnessFile - ) - } - } catch (e: Throwable) { - logger.write(Logger.Level.INFO, "Could not output files: ${e.stackTraceToString()}\n") + val traceFile = File(resultFolder, "trace.dot") + val traceG: Graph = TraceVisualizer.getDefault().visualize(concrTrace) + traceFile.writeText(GraphvizWriter.getInstance().writeString(traceG)) + + val sequenceFile = File(resultFolder, "trace.plantuml") + writeSequenceTrace( + sequenceFile, + safetyResult.asUnsafe().cex as Trace, XcfaAction>, + ) { (_, act) -> + act.label.getFlatLabels().map(XcfaLabel::toString) + } + + val optSequenceFile = File(resultFolder, "trace-optimized.plantuml") + writeSequenceTrace(optSequenceFile, concrTrace) { (_, act) -> + act.label.getFlatLabels().map(XcfaLabel::toString) + } + + val cSequenceFile = File(resultFolder, "trace-c.plantuml") + writeSequenceTrace(cSequenceFile, concrTrace) { (state, act) -> + val proc = state.processes[act.pid] + val loc = proc?.locs?.peek() + (loc?.metadata as? CMetaData)?.sourceText?.split("\n") ?: listOf("") + } } + val witnessFile = File(resultFolder, "witness.graphml") + XcfaWitnessWriter() + .writeWitness( + safetyResult, + config.inputConfig.input!!, + getSolver( + config.outputConfig.witnessConfig.concretizerSolver, + config.outputConfig.witnessConfig.validateConcretizerSolver, + ), + parseContext, + witnessFile, + ) + } + } catch (e: Throwable) { + logger.write(Logger.Level.INFO, "Could not output files: ${e.stackTraceToString()}\n") } + } } -private fun writeSequenceTrace(sequenceFile: File, trace: Trace, XcfaAction>, - printer: (Pair, XcfaAction>) -> List) { - sequenceFile.writeText("@startuml\n") - var maxWidth = 0 - trace.actions.forEachIndexed { i, it -> - val stateBefore = trace.states[i] - sequenceFile.appendText("hnote over ${it.pid}\n") - val labelStrings = printer(Pair(stateBefore, it)) - if (maxWidth < (labelStrings.maxOfOrNull { it.length } ?: 0)) { - maxWidth = labelStrings.maxOfOrNull { it.length } ?: 0 - } - sequenceFile.appendText("${labelStrings.joinToString("\n")}\n") - sequenceFile.appendText("endhnote\n") +private fun writeSequenceTrace( + sequenceFile: File, + trace: Trace, XcfaAction>, + printer: (Pair, XcfaAction>) -> List, +) { + sequenceFile.writeText("@startuml\n") + var maxWidth = 0 + trace.actions.forEachIndexed { i, it -> + val stateBefore = trace.states[i] + sequenceFile.appendText("hnote over ${it.pid}\n") + val labelStrings = printer(Pair(stateBefore, it)) + if (maxWidth < (labelStrings.maxOfOrNull { it.length } ?: 0)) { + maxWidth = labelStrings.maxOfOrNull { it.length } ?: 0 } - trace.actions.map { it.pid }.distinct().reduce { acc, current -> - sequenceFile.appendText("$acc --> $current: \"${" ".repeat(maxWidth)}\"\n") - current + sequenceFile.appendText("${labelStrings.joinToString("\n")}\n") + sequenceFile.appendText("endhnote\n") + } + trace.actions + .map { it.pid } + .distinct() + .reduce { acc, current -> + sequenceFile.appendText("$acc --> $current: \"${" ".repeat(maxWidth)}\"\n") + current } - sequenceFile.appendText("@enduml\n") -} \ No newline at end of file + sequenceFile.appendText("@enduml\n") +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt index 18e0bd82ca..5825b0d922 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToBoundedChecker.kt @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.checkers import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.bounded.BoundedChecker import hu.bme.mit.theta.analysis.ptr.PtrState @@ -30,35 +29,41 @@ import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA -fun getBoundedChecker(xcfa: XCFA, mcm: MCM, - config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - - val boundedConfig = config.backendConfig.specConfig as BoundedConfig +fun getBoundedChecker( + xcfa: XCFA, + mcm: MCM, + config: XcfaConfig<*, *>, + logger: Logger, +): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - return BoundedChecker( - monolithicExpr = xcfa.toMonolithicExpr(), - bmcSolver = tryGetSolver(boundedConfig.bmcConfig.bmcSolver, - boundedConfig.bmcConfig.validateBMCSolver)?.createSolver(), - bmcEnabled = { !boundedConfig.bmcConfig.disable }, - lfPathOnly = { !boundedConfig.bmcConfig.nonLfPath }, - itpSolver = tryGetSolver(boundedConfig.itpConfig.itpSolver, - boundedConfig.itpConfig.validateItpSolver)?.createItpSolver(), - imcEnabled = { !boundedConfig.itpConfig.disable }, - indSolver = tryGetSolver(boundedConfig.indConfig.indSolver, - boundedConfig.indConfig.validateIndSolver)?.createSolver(), - kindEnabled = { !boundedConfig.indConfig.disable }, - valToState = { xcfa.valToState(it) }, - biValToAction = { val1, val2 -> xcfa.valToAction(val1, val2) }, - logger = logger - ) as SafetyChecker>, XcfaAction>, XcfaPrec<*>> + val boundedConfig = config.backendConfig.specConfig as BoundedConfig + return BoundedChecker( + monolithicExpr = xcfa.toMonolithicExpr(), + bmcSolver = + tryGetSolver(boundedConfig.bmcConfig.bmcSolver, boundedConfig.bmcConfig.validateBMCSolver) + ?.createSolver(), + bmcEnabled = { !boundedConfig.bmcConfig.disable }, + lfPathOnly = { !boundedConfig.bmcConfig.nonLfPath }, + itpSolver = + tryGetSolver(boundedConfig.itpConfig.itpSolver, boundedConfig.itpConfig.validateItpSolver) + ?.createItpSolver(), + imcEnabled = { !boundedConfig.itpConfig.disable }, + indSolver = + tryGetSolver(boundedConfig.indConfig.indSolver, boundedConfig.indConfig.validateIndSolver) + ?.createSolver(), + kindEnabled = { !boundedConfig.indConfig.disable }, + valToState = { xcfa.valToState(it) }, + biValToAction = { val1, val2 -> xcfa.valToAction(val1, val2) }, + logger = logger, + ) + as SafetyChecker>, XcfaAction>, XcfaPrec<*>> } private fun tryGetSolver(name: String, validate: Boolean): SolverFactory? { - try { - return getSolver(name, validate) - } catch (e: Throwable) { - return null - } -} \ No newline at end of file + try { + return getSolver(name, validate) + } catch (e: Throwable) { + return null + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt index f8bf86f8d2..25a81fdb2e 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToCegarChecker.kt @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.checkers import hu.bme.mit.theta.analysis.PartialOrd import hu.bme.mit.theta.analysis.Prec import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.arg.ARG +import hu.bme.mit.theta.analysis.algorithm.arg.ArgNode import hu.bme.mit.theta.analysis.algorithm.cegar.ArgAbstractor import hu.bme.mit.theta.analysis.algorithm.cegar.ArgCegarChecker import hu.bme.mit.theta.analysis.algorithm.cegar.ArgRefiner @@ -44,109 +43,138 @@ import hu.bme.mit.theta.xcfa.cli.utils.getSolver import hu.bme.mit.theta.xcfa.model.XCFA fun getCegarChecker( - xcfa: XCFA, mcm: MCM, - config: XcfaConfig<*, *>, - logger: Logger -): SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { - val cegarConfig = config.backendConfig.specConfig as CegarConfig - val abstractionSolverFactory: SolverFactory = getSolver( - cegarConfig.abstractorConfig.abstractionSolver, - cegarConfig.abstractorConfig.validateAbstractionSolver + xcfa: XCFA, + mcm: MCM, + config: XcfaConfig<*, *>, + logger: Logger, +): SafetyChecker< + ARG, XcfaAction>, + Trace>, XcfaAction>, + XcfaPrec<*>, +> { + val cegarConfig = config.backendConfig.specConfig as CegarConfig + val abstractionSolverFactory: SolverFactory = + getSolver( + cegarConfig.abstractorConfig.abstractionSolver, + cegarConfig.abstractorConfig.validateAbstractionSolver, ) - val refinementSolverFactory: SolverFactory = getSolver( - cegarConfig.refinerConfig.refinementSolver, - cegarConfig.refinerConfig.validateRefinementSolver + val refinementSolverFactory: SolverFactory = + getSolver( + cegarConfig.refinerConfig.refinementSolver, + cegarConfig.refinerConfig.validateRefinementSolver, ) - val ignoredVarRegistry = mutableMapOf, MutableSet>() + val ignoredVarRegistry = mutableMapOf, MutableSet>() - val lts = cegarConfig.coi.getLts(xcfa, ignoredVarRegistry, cegarConfig.porLevel) - val waitlist = if (cegarConfig.porLevel.isDynamic) { - (cegarConfig.coi.porLts as XcfaDporLts).waitlist + val lts = cegarConfig.coi.getLts(xcfa, ignoredVarRegistry, cegarConfig.porLevel) + val waitlist = + if (cegarConfig.porLevel.isDynamic) { + (cegarConfig.coi.porLts as XcfaDporLts).waitlist } else { - PriorityWaitlist.create>, XcfaAction>>( - cegarConfig.abstractorConfig.search.getComp(xcfa) - ) + PriorityWaitlist.create>, XcfaAction>>( + cegarConfig.abstractorConfig.search.getComp(xcfa) + ) } - val abstractionSolverInstance = abstractionSolverFactory.createSolver() - val globalStatePartialOrd: PartialOrd> = cegarConfig.abstractorConfig.domain.partialOrd( - abstractionSolverInstance - ) as PartialOrd> - val corePartialOrd: PartialOrd>> = - if (xcfa.isInlined) getPartialOrder(globalStatePartialOrd) - else getStackPartialOrder(globalStatePartialOrd) - val abstractor: ArgAbstractor = cegarConfig.abstractorConfig.domain.abstractor( - xcfa, - abstractionSolverInstance, - cegarConfig.abstractorConfig.maxEnum, - waitlist, - cegarConfig.refinerConfig.refinement.stopCriterion, - logger, - lts, - config.inputConfig.property, - if (cegarConfig.porLevel.isDynamic) { - XcfaDporLts.getPartialOrder(corePartialOrd) - } else { - corePartialOrd - }, - cegarConfig.abstractorConfig.havocMemory + val abstractionSolverInstance = abstractionSolverFactory.createSolver() + val globalStatePartialOrd: PartialOrd> = + cegarConfig.abstractorConfig.domain.partialOrd(abstractionSolverInstance) + as PartialOrd> + val corePartialOrd: PartialOrd>> = + if (xcfa.isInlined) getPartialOrder(globalStatePartialOrd) + else getStackPartialOrder(globalStatePartialOrd) + val abstractor: ArgAbstractor = + cegarConfig.abstractorConfig.domain.abstractor( + xcfa, + abstractionSolverInstance, + cegarConfig.abstractorConfig.maxEnum, + waitlist, + cegarConfig.refinerConfig.refinement.stopCriterion, + logger, + lts, + config.inputConfig.property, + if (cegarConfig.porLevel.isDynamic) { + XcfaDporLts.getPartialOrder(corePartialOrd) + } else { + corePartialOrd + }, + cegarConfig.abstractorConfig.havocMemory, ) as ArgAbstractor - val ref: ExprTraceChecker = - cegarConfig.refinerConfig.refinement.refiner(refinementSolverFactory, cegarConfig.cexMonitor) - as ExprTraceChecker - val precRefiner: PrecRefiner = - cegarConfig.abstractorConfig.domain.itpPrecRefiner(cegarConfig.refinerConfig.exprSplitter.exprSplitter) - as PrecRefiner - val atomicNodePruner: NodePruner = - cegarConfig.abstractorConfig.domain.nodePruner as NodePruner - val refiner: ArgRefiner = - if (cegarConfig.refinerConfig.refinement == Refinement.MULTI_SEQ) - if (cegarConfig.porLevel == POR.AASPOR) - MultiExprTraceRefiner.create( - ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner - ) - else - MultiExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) - else - if (cegarConfig.porLevel == POR.AASPOR) - XcfaSingleExprTraceRefiner.create( - ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger, - atomicNodePruner - ) - else - XcfaSingleExprTraceRefiner.create(ref, precRefiner, cegarConfig.refinerConfig.pruneStrategy, logger) - - val cegarChecker = if (cegarConfig.porLevel == POR.AASPOR) - ArgCegarChecker.create( - abstractor, - AasporRefiner.create(refiner, cegarConfig.refinerConfig.pruneStrategy, ignoredVarRegistry), - logger + val ref: ExprTraceChecker = + cegarConfig.refinerConfig.refinement.refiner(refinementSolverFactory, cegarConfig.cexMonitor) + as ExprTraceChecker + val precRefiner: PrecRefiner = + cegarConfig.abstractorConfig.domain.itpPrecRefiner( + cegarConfig.refinerConfig.exprSplitter.exprSplitter + ) as PrecRefiner + val atomicNodePruner: NodePruner = + cegarConfig.abstractorConfig.domain.nodePruner as NodePruner + val refiner: ArgRefiner = + if (cegarConfig.refinerConfig.refinement == Refinement.MULTI_SEQ) + if (cegarConfig.porLevel == POR.AASPOR) + MultiExprTraceRefiner.create( + ref, + precRefiner, + cegarConfig.refinerConfig.pruneStrategy, + logger, + atomicNodePruner, + ) + else + MultiExprTraceRefiner.create( + ref, + precRefiner, + cegarConfig.refinerConfig.pruneStrategy, + logger, ) + else if (cegarConfig.porLevel == POR.AASPOR) + XcfaSingleExprTraceRefiner.create( + ref, + precRefiner, + cegarConfig.refinerConfig.pruneStrategy, + logger, + atomicNodePruner, + ) else - ArgCegarChecker.create(abstractor, refiner, logger) + XcfaSingleExprTraceRefiner.create( + ref, + precRefiner, + cegarConfig.refinerConfig.pruneStrategy, + logger, + ) - // initialize monitors - MonitorCheckpoint.reset() - if (cegarConfig.cexMonitor == CexMonitorOptions.CHECK) { - val cm = CexMonitor(logger, cegarChecker.witness) - MonitorCheckpoint.register(cm, "CegarChecker.unsafeARG") - } + val cegarChecker = + if (cegarConfig.porLevel == POR.AASPOR) + ArgCegarChecker.create( + abstractor, + AasporRefiner.create(refiner, cegarConfig.refinerConfig.pruneStrategy, ignoredVarRegistry), + logger, + ) + else ArgCegarChecker.create(abstractor, refiner, logger) + + // initialize monitors + MonitorCheckpoint.reset() + if (cegarConfig.cexMonitor == CexMonitorOptions.CHECK) { + val cm = CexMonitor(logger, cegarChecker.proof) + MonitorCheckpoint.register(cm, "CegarChecker.unsafeARG") + } - return object : - SafetyChecker, XcfaAction>, Trace>, XcfaAction>, XcfaPrec<*>> { - override fun check( - prec: XcfaPrec<*>? - ): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { - return cegarChecker.check( - prec - ) as SafetyResult, XcfaAction>, Trace>, XcfaAction>> - } + return object : + SafetyChecker< + ARG, XcfaAction>, + Trace>, XcfaAction>, + XcfaPrec<*>, + > { + override fun check( + prec: XcfaPrec<*>? + ): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { + return cegarChecker.check(prec) + as SafetyResult, XcfaAction>, Trace>, XcfaAction>> + } - override fun check(): SafetyResult, XcfaAction>, Trace>, XcfaAction>> { - return check(cegarConfig.abstractorConfig.domain.initPrec(xcfa, cegarConfig.initPrec)) - } + override fun check(): + SafetyResult, XcfaAction>, Trace>, XcfaAction>> { + return check(cegarConfig.abstractorConfig.domain.initPrec(xcfa, cegarConfig.initPrec)) } -} \ No newline at end of file + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToHornChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToHornChecker.kt index dd63b5eb48..a944126ace 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToHornChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToHornChecker.kt @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.checkers import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.chc.HornChecker @@ -36,32 +35,37 @@ import hu.bme.mit.theta.xcfa.model.XCFA import hu.bme.mit.theta.xcfa2chc.toCHC import org.abego.treelayout.internal.util.Contract.checkState -fun getHornChecker(xcfa: XCFA, mcm: MCM, config: XcfaConfig<*, *>, logger: Logger): - SafetyChecker>, XcfaAction>, XcfaPrec<*>> { +fun getHornChecker( + xcfa: XCFA, + mcm: MCM, + config: XcfaConfig<*, *>, + logger: Logger, +): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - checkState(xcfa.isInlined, "Only inlined XCFAs work right now") - checkState(xcfa.initProcedures.size == 1, "Only one-procedure XCFAs work right now") + checkState(xcfa.isInlined, "Only inlined XCFAs work right now") + checkState(xcfa.initProcedures.size == 1, "Only one-procedure XCFAs work right now") - val hornConfig = config.backendConfig.specConfig as HornConfig + val hornConfig = config.backendConfig.specConfig as HornConfig - val checker = HornChecker( - relations = xcfa.initProcedures[0].first.toCHC(), - hornSolverFactory = getSolver(hornConfig.solver, hornConfig.validateSolver), - logger = logger, + val checker = + HornChecker( + relations = xcfa.initProcedures[0].first.toCHC(), + hornSolverFactory = getSolver(hornConfig.solver, hornConfig.validateSolver), + logger = logger, ) - return SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - val result = checker.check(null) + return SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + val result = checker.check(null) - if (result.isSafe) { - SafetyResult.safe(EmptyWitness.getInstance()) - } else if (result.isUnsafe) { - val proof = result.asUnsafe().cex - val state = XcfaState>(xcfa, mapOf(), PtrState(PredState.of(proof.proofNode.expr))) - SafetyResult.unsafe(Trace.of(listOf(state), listOf()), EmptyWitness.getInstance()) - } else { - SafetyResult.unknown() - } + if (result.isSafe) { + SafetyResult.safe(EmptyProof.getInstance()) + } else if (result.isUnsafe) { + val proof = result.asUnsafe().cex + val state = + XcfaState>(xcfa, mapOf(), PtrState(PredState.of(proof.proofNode.expr))) + SafetyResult.unsafe(Trace.of(listOf(state), listOf()), EmptyProof.getInstance()) + } else { + SafetyResult.unknown() } - -} \ No newline at end of file + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt index df14f6ee8f..d8e3fc76ff 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/ConfigToOcChecker.kt @@ -13,11 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.checkers import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.ptr.PtrState @@ -31,14 +30,21 @@ import hu.bme.mit.theta.xcfa.cli.params.OcConfig import hu.bme.mit.theta.xcfa.cli.params.XcfaConfig import hu.bme.mit.theta.xcfa.model.XCFA -fun getOcChecker(xcfa: XCFA, mcm: MCM, - config: XcfaConfig<*, *>, - logger: Logger): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - val ocChecker = XcfaOcChecker(xcfa, (config.backendConfig.specConfig as OcConfig).decisionProcedure, logger) - return object : SafetyChecker>, XcfaAction>, XcfaPrec<*>> { - override fun check( - prec: XcfaPrec<*>?): SafetyResult>, XcfaAction>> = check() +fun getOcChecker( + xcfa: XCFA, + mcm: MCM, + config: XcfaConfig<*, *>, + logger: Logger, +): SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + val ocChecker = + XcfaOcChecker(xcfa, (config.backendConfig.specConfig as OcConfig).decisionProcedure, logger) + return object : + SafetyChecker>, XcfaAction>, XcfaPrec<*>> { + override fun check( + prec: XcfaPrec<*>? + ): SafetyResult>, XcfaAction>> = check() - override fun check(): SafetyResult>, XcfaAction>> = ocChecker.check() - } -} \ No newline at end of file + override fun check(): SafetyResult>, XcfaAction>> = + ocChecker.check() + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt index a20d9a5aaf..193a062499 100644 --- a/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt +++ b/subprojects/xcfa/xcfa-cli/src/main/java/hu/bme/mit/theta/xcfa/cli/checkers/InProcessChecker.kt @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xcfa.cli.checkers import com.zaxxer.nuprocess.NuAbstractProcessHandler import com.zaxxer.nuprocess.NuProcess import com.zaxxer.nuprocess.NuProcessBuilder import hu.bme.mit.theta.analysis.EmptyCex -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyChecker import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.ptr.PtrState import hu.bme.mit.theta.common.logging.Logger import hu.bme.mit.theta.frontend.ParseContext import hu.bme.mit.theta.xcfa.analysis.XcfaPrec @@ -40,47 +38,48 @@ import java.util.concurrent.TimeUnit import kotlin.io.path.createTempDirectory class InProcessChecker( - val xcfa: XCFA, - val config: XcfaConfig, - val parseContext: ParseContext, - val logger: Logger, -) : SafetyChecker> { - - override fun check( - prec: XcfaPrec<*>?): SafetyResult { - return check() - } - - override fun check(): SafetyResult { - val tempDir = createTempDirectory(config.outputConfig.resultFolder.toPath()) - - val xcfaJson = CachingFileSerializer.serialize("xcfa.json", xcfa) { getGson(xcfa).toJson(xcfa) } - val parseContextJson = CachingFileSerializer.serialize("parseContext.json", parseContext) { - getGson(xcfa).toJson(parseContext) - } - - val processConfig = config.copy( - inputConfig = config.inputConfig.copy( - input = xcfaJson, - parseCtx = parseContextJson, - ), - frontendConfig = config.frontendConfig.copy( - inputType = InputType.JSON - ), - backendConfig = config.backendConfig.copy(inProcess = false, timeoutMs = 0), - outputConfig = config.outputConfig.copy( - resultFolder = tempDir.toFile(), - cOutputConfig = COutputConfig(disable = true), - xcfaOutputConfig = XcfaOutputConfig(disable = true), - argConfig = config.outputConfig.argConfig.copy(disable = false), // we need the arg to be produced - ) - ) - - val configJson = CachingFileSerializer.serialize("config.json", processConfig) { - getGson(xcfa).toJson(processConfig) - } - - val pb = NuProcessBuilder(listOf( + val xcfa: XCFA, + val config: XcfaConfig, + val parseContext: ParseContext, + val logger: Logger, +) : SafetyChecker> { + + override fun check(prec: XcfaPrec<*>?): SafetyResult { + return check() + } + + override fun check(): SafetyResult { + val tempDir = createTempDirectory(config.outputConfig.resultFolder.toPath()) + + val xcfaJson = CachingFileSerializer.serialize("xcfa.json", xcfa) { getGson(xcfa).toJson(xcfa) } + val parseContextJson = + CachingFileSerializer.serialize("parseContext.json", parseContext) { + getGson(xcfa).toJson(parseContext) + } + + val processConfig = + config.copy( + inputConfig = config.inputConfig.copy(input = xcfaJson, parseCtx = parseContextJson), + frontendConfig = config.frontendConfig.copy(inputType = InputType.JSON), + backendConfig = config.backendConfig.copy(inProcess = false, timeoutMs = 0), + outputConfig = + config.outputConfig.copy( + resultFolder = tempDir.toFile(), + cOutputConfig = COutputConfig(disable = true), + xcfaOutputConfig = XcfaOutputConfig(disable = true), + argConfig = + config.outputConfig.argConfig.copy(disable = false), // we need the arg to be produced + ), + ) + + val configJson = + CachingFileSerializer.serialize("config.json", processConfig) { + getGson(xcfa).toJson(processConfig) + } + + val pb = + NuProcessBuilder( + listOf( ProcessHandle.current().info().command().orElse("java"), "-Xss120m", "-Xmx14210m", @@ -88,91 +87,94 @@ class InProcessChecker( File(XcfaCli::class.java.protectionDomain.codeSource.location.toURI()).absolutePath, XcfaCli::class.qualifiedName, "-c", - configJson.absolutePath - ).filterNotNull()) - val processHandler = ProcessHandler() - pb.setProcessListener(processHandler) - val process: NuProcess = pb.start() - pb.environment().putAll(System.getenv()) - - val retCode = process.waitFor(config.backendConfig.timeoutMs, TimeUnit.MILLISECONDS) - val booleanSafetyResult = - if (retCode == Int.MIN_VALUE) { - if (processHandler.safetyResult == null) { - process.destroy(true) - throw ErrorCodeException(ExitCodes.TIMEOUT.code) - } else { - logger.write(Logger.Level.RESULT, - "Config timed out but started writing result, trying to wait an additional 10%...") - val retCode = process.waitFor(config.backendConfig.timeoutMs / 10, TimeUnit.MILLISECONDS) - if (retCode != 0) { - throw ErrorCodeException(retCode) - } else { - processHandler.safetyResult - } - } - } else if (retCode != 0) { - throw ErrorCodeException(retCode) - } else { - processHandler.safetyResult - } - - tempDir.toFile().listFiles()?.forEach { - it.copyTo(config.outputConfig.resultFolder.resolve(it.name), overwrite = true) + configJson.absolutePath, + ) + .filterNotNull() + ) + val processHandler = ProcessHandler() + pb.setProcessListener(processHandler) + val process: NuProcess = pb.start() + pb.environment().putAll(System.getenv()) + + val retCode = process.waitFor(config.backendConfig.timeoutMs, TimeUnit.MILLISECONDS) + val booleanSafetyResult = + if (retCode == Int.MIN_VALUE) { + if (processHandler.safetyResult == null) { + process.destroy(true) + throw ErrorCodeException(ExitCodes.TIMEOUT.code) + } else { + logger.write( + Logger.Level.RESULT, + "Config timed out but started writing result, trying to wait an additional 10%...", + ) + val retCode = process.waitFor(config.backendConfig.timeoutMs / 10, TimeUnit.MILLISECONDS) + if (retCode != 0) { + throw ErrorCodeException(retCode) + } else { + processHandler.safetyResult + } } - tempDir.toFile().deleteRecursively() - - return booleanSafetyResult as SafetyResult + } else if (retCode != 0) { + throw ErrorCodeException(retCode) + } else { + processHandler.safetyResult + } + + tempDir.toFile().listFiles()?.forEach { + it.copyTo(config.outputConfig.resultFolder.resolve(it.name), overwrite = true) } + tempDir.toFile().deleteRecursively() - private class ProcessHandler : NuAbstractProcessHandler() { - - private val stdout = LinkedList() - private var stdoutRemainder = "" - private val stderr = LinkedList() - private var stderrRemainder = "" - var safetyResult: SafetyResult<*, *>? = null - private set - - override fun onStdout(buffer: ByteBuffer, closed: Boolean) { - if (!closed) { - val bytes = ByteArray(buffer.remaining()) - buffer[bytes] - val str = bytes.decodeToString() - - stdoutRemainder += str - if (stdoutRemainder.contains("SafetyResult Safe")) { - safetyResult = SafetyResult.safe(EmptyWitness.getInstance()) - } - if (stdoutRemainder.contains("SafetyResult Unsafe")) { - safetyResult = SafetyResult.unsafe(EmptyCex.getInstance(), EmptyWitness.getInstance()) - } - - val newLines = stdoutRemainder.split("\n") // if ends with \n, last element will be "" - newLines.subList(0, newLines.size - 1).forEach { - stdout.add(it) - println("server: $it") - } - stdoutRemainder = newLines[newLines.size - 1] - } + return booleanSafetyResult as SafetyResult + } + + private class ProcessHandler : NuAbstractProcessHandler() { + + private val stdout = LinkedList() + private var stdoutRemainder = "" + private val stderr = LinkedList() + private var stderrRemainder = "" + var safetyResult: SafetyResult<*, *>? = null + private set + + override fun onStdout(buffer: ByteBuffer, closed: Boolean) { + if (!closed) { + val bytes = ByteArray(buffer.remaining()) + buffer[bytes] + val str = bytes.decodeToString() + + stdoutRemainder += str + if (stdoutRemainder.contains("SafetyResult Safe")) { + safetyResult = SafetyResult.safe(EmptyProof.getInstance()) + } + if (stdoutRemainder.contains("SafetyResult Unsafe")) { + safetyResult = SafetyResult.unsafe(EmptyCex.getInstance(), EmptyProof.getInstance()) } - override fun onStderr(buffer: ByteBuffer, closed: Boolean) { - if (!closed) { - val bytes = ByteArray(buffer.remaining()) - buffer[bytes] - val str = bytes.decodeToString() - - stderrRemainder += str - - val newLines = stderrRemainder.split("\n") // if ends with \n, last element will be "" - newLines.subList(0, newLines.size - 1).forEach { - stderr.add(it) - err.println("server: $it") - } - stderrRemainder = newLines[newLines.size - 1] - } + val newLines = stdoutRemainder.split("\n") // if ends with \n, last element will be "" + newLines.subList(0, newLines.size - 1).forEach { + stdout.add(it) + println("server: $it") } + stdoutRemainder = newLines[newLines.size - 1] + } } -} \ No newline at end of file + override fun onStderr(buffer: ByteBuffer, closed: Boolean) { + if (!closed) { + val bytes = ByteArray(buffer.remaining()) + buffer[bytes] + val str = bytes.decodeToString() + + stderrRemainder += str + + val newLines = stderrRemainder.split("\n") // if ends with \n, last element will be "" + newLines.subList(0, newLines.size - 1).forEach { + stderr.add(it) + err.println("server: $it") + } + stderrRemainder = newLines[newLines.size - 1] + } + } + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt new file mode 100644 index 0000000000..3d29c73fb0 --- /dev/null +++ b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliProofTest.kt @@ -0,0 +1,136 @@ +/* + * Copyright 2024 Budapest University of Technology and Economics + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package hu.bme.mit.theta.xcfa.cli + +import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main +import java.util.stream.Stream +import kotlin.io.path.absolutePathString +import kotlin.io.path.createTempDirectory +import kotlin.io.path.exists +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.Arguments +import org.junit.jupiter.params.provider.MethodSource + +data class WitnessEdge( + val startlineRange: Pair?, + val endlineRange: Pair?, + val startoffsetRange: Pair?, + val endoffsetRange: Pair?, + val assumption: Regex?, +) + +class XcfaCliProofTest { + companion object { + + @JvmStatic + fun cFiles(): Stream { + return Stream.of( + Arguments.of( + "/c/litmustest/singlethread/witness_test.c", + null, + listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ) + ), + ), + Arguments.of( + "/c/litmustest/singlethread/witness_test.c", + "--backend BOUNDED", + listOf( + WitnessEdge( + startlineRange = Pair(5, 5), + endlineRange = Pair(5, 5), + startoffsetRange = Pair(100, 130), + endoffsetRange = Pair(100, 130), + assumption = Regex("i *== *-1"), + ) + ), + ), + ) + } + } + + @ParameterizedTest + @MethodSource("cFiles") + fun testCWitness(filePath: String, extraArgs: String?, expectedWitnessEdges: List) { + val temp = createTempDirectory() + val params = + arrayOf( + "--enable-output", + "--input-type", + "C", + "--input", + javaClass.getResource(filePath)!!.path, + *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), + "--stacktrace", + "--output-directory", + temp.absolutePathString(), + "--debug", + ) + main(params) + Assertions.assertTrue(temp.resolve("witness.graphml").exists()) + val witnessContents = temp.resolve("witness.graphml").toFile().readText() + val edges = mutableListOf>() + val edgeMatcher = Regex("(?s)(.*)") + val data = mutableMapOf() + for (dataMatch in dataMatcher.findAll(match.value)) { + val (key, value) = dataMatch.destructured + data.put(key, value) + } + edges.add(data) + println( + "Found edge containing data: ${data.entries.map { "${it.key}: ${it.value}" }.joinToString(", ")}" + ) + } + for (expectedWitnessEdge in expectedWitnessEdges) { + Assertions.assertFalse( + edges.none { edge -> + val startline = + expectedWitnessEdge.startlineRange + ?.let { edge["startline"]?.let { v -> Pair(it, Integer.parseInt(v)) } } + ?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false + val endline = + expectedWitnessEdge.endlineRange + ?.let { edge["endline"]?.let { v -> Pair(it, Integer.parseInt(v)) } } + ?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false + val startoffset = + expectedWitnessEdge.startoffsetRange + ?.let { edge["startoffset"]?.let { v -> Pair(it, Integer.parseInt(v)) } } + ?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false + val endoffset = + expectedWitnessEdge.endoffsetRange + ?.let { edge["endoffset"]?.let { v -> Pair(it, Integer.parseInt(v)) } } + ?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false + val assumption = + expectedWitnessEdge.assumption + ?.let { edge["assumption"]?.let { v -> Pair(it, v) } } + ?.let { it.first.matches(it.second) } ?: false + startline && endline && startoffset && endoffset && assumption + }, + "Expected witness edge not found: $expectedWitnessEdge", + ) + } + temp.toFile().deleteRecursively() + } +} diff --git a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt b/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt deleted file mode 100644 index bc5657f5ba..0000000000 --- a/subprojects/xcfa/xcfa-cli/src/test/java/hu/bme/mit/theta/xcfa/cli/XcfaCliWitnessTest.kt +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2024 Budapest University of Technology and Economics - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package hu.bme.mit.theta.xcfa.cli - -import hu.bme.mit.theta.xcfa.cli.XcfaCli.Companion.main -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.params.ParameterizedTest -import org.junit.jupiter.params.provider.Arguments -import org.junit.jupiter.params.provider.MethodSource -import java.util.stream.Stream -import kotlin.io.path.absolutePathString -import kotlin.io.path.createTempDirectory -import kotlin.io.path.exists - -data class WitnessEdge( - val startlineRange: Pair?, - val endlineRange: Pair?, - val startoffsetRange: Pair?, - val endoffsetRange: Pair?, - val assumption: Regex?, -) - -class XcfaCliWitnessTest { - companion object { - - @JvmStatic - fun cFiles(): Stream { - return Stream.of( - Arguments.of("/c/litmustest/singlethread/witness_test.c", null, listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - )), - Arguments.of("/c/litmustest/singlethread/witness_test.c", "--backend BOUNDED", listOf( - WitnessEdge( - startlineRange = Pair(5, 5), - endlineRange = Pair(5, 5), - startoffsetRange = Pair(100, 130), - endoffsetRange = Pair(100, 130), - assumption = Regex("i *== *-1"), - ), - )), - ) - } - - } - - @ParameterizedTest - @MethodSource("cFiles") - fun testCWitness(filePath: String, extraArgs: String?, expectedWitnessEdges: List) { - val temp = createTempDirectory() - val params = arrayOf( - "--enable-output", - "--input-type", "C", - "--input", javaClass.getResource(filePath)!!.path, - *(extraArgs?.split(" ")?.toTypedArray() ?: emptyArray()), - "--stacktrace", - "--output-directory", temp.absolutePathString(), - "--debug", - ) - main(params) - Assertions.assertTrue(temp.resolve("witness.graphml").exists()) - val witnessContents = temp.resolve("witness.graphml").toFile().readText() - val edges = mutableListOf>() - val edgeMatcher = Regex("(?s)(.*)") - val data = mutableMapOf() - for (dataMatch in dataMatcher.findAll(match.value)) { - val (key, value) = dataMatch.destructured - data.put(key, value) - } - edges.add(data) - println("Found edge containing data: ${data.entries.map { "${it.key}: ${it.value}" }.joinToString(", ")}") - } - for (expectedWitnessEdge in expectedWitnessEdges) { - Assertions.assertFalse( - edges.none { edge -> - val startline = expectedWitnessEdge.startlineRange?.let { - edge["startline"]?.let { v -> - Pair(it, Integer.parseInt(v)) - } - }?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false - val endline = expectedWitnessEdge.endlineRange?.let { - edge["endline"]?.let { v -> - Pair(it, Integer.parseInt(v)) - } - }?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false - val startoffset = expectedWitnessEdge.startoffsetRange?.let { - edge["startoffset"]?.let { v -> - Pair(it, Integer.parseInt(v)) - } - }?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false - val endoffset = expectedWitnessEdge.endoffsetRange?.let { - edge["endoffset"]?.let { v -> - Pair(it, Integer.parseInt(v)) - } - }?.let { it.first.first <= it.second && it.second <= it.first.second } ?: false - val assumption = expectedWitnessEdge.assumption?.let { - edge["assumption"]?.let { v -> - Pair(it, v) - } - }?.let { it.first.matches(it.second) } ?: false - startline && endline && startoffset && endoffset && assumption - }, - "Expected witness edge not found: $expectedWitnessEdge" - ) - } - temp.toFile().deleteRecursively() - } - - -} diff --git a/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/mdd/XstsMddChecker.java b/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/mdd/XstsMddChecker.java index ae9262e03f..b8ae5f098e 100644 --- a/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/mdd/XstsMddChecker.java +++ b/subprojects/xsts/xsts-analysis/src/main/java/hu/bme/mit/theta/xsts/analysis/mdd/XstsMddChecker.java @@ -15,30 +15,32 @@ */ package hu.bme.mit.theta.xsts.analysis.mdd; +import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Eq; +import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; +import static hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not; + import com.google.common.base.Preconditions; -import hu.bme.mit.delta.collections.impl.RecursiveIntObjMapViews; -import hu.bme.mit.delta.java.mdd.*; +import hu.bme.mit.delta.java.mdd.JavaMddFactory; +import hu.bme.mit.delta.java.mdd.MddGraph; +import hu.bme.mit.delta.java.mdd.MddHandle; +import hu.bme.mit.delta.java.mdd.MddVariableOrder; import hu.bme.mit.delta.mdd.MddInterpreter; import hu.bme.mit.delta.mdd.MddVariableDescriptor; -import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; +import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.mdd.MddAnalysisStatistics; import hu.bme.mit.theta.analysis.algorithm.mdd.MddCex; import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker.IterationStrategy; -import hu.bme.mit.theta.analysis.algorithm.mdd.MddWitness; -import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.*; +import hu.bme.mit.theta.analysis.algorithm.mdd.MddProof; import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.AbstractNextStateDescriptor; +import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeInitializer; +import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeNextStateDescriptor; import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.OrNextStateDescriptor; -import hu.bme.mit.theta.common.logging.Logger; -import hu.bme.mit.theta.common.logging.Logger.Level; -import hu.bme.mit.theta.solver.SolverPool; import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.ExprLatticeDefinition; import hu.bme.mit.theta.analysis.algorithm.mdd.expressionnode.MddExpressionTemplate; -import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeInitializer; -import hu.bme.mit.theta.analysis.algorithm.mdd.ansd.impl.MddNodeNextStateDescriptor; -import hu.bme.mit.theta.analysis.utils.MddNodeVisualizer; -import hu.bme.mit.theta.common.visualization.Graph; -import hu.bme.mit.theta.common.visualization.writer.GraphvizWriter; +import hu.bme.mit.theta.analysis.algorithm.mdd.fixedpoint.*; +import hu.bme.mit.theta.common.logging.Logger; +import hu.bme.mit.theta.common.logging.Logger.Level; import hu.bme.mit.theta.core.decl.Decl; import hu.bme.mit.theta.core.stmt.NonDetStmt; import hu.bme.mit.theta.core.stmt.SequenceStmt; @@ -48,17 +50,12 @@ import hu.bme.mit.theta.core.utils.PathUtils; import hu.bme.mit.theta.core.utils.StmtUtils; import hu.bme.mit.theta.core.utils.indexings.VarIndexingFactory; +import hu.bme.mit.theta.solver.SolverPool; import hu.bme.mit.theta.xsts.XSTS; - -import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.List; -import static hu.bme.mit.theta.core.type.abstracttype.AbstractExprs.Eq; -import static hu.bme.mit.theta.core.type.booltype.BoolExprs.And; -import static hu.bme.mit.theta.core.type.booltype.SmartBoolExprs.Not; - -public class XstsMddChecker implements SafetyChecker { +public class XstsMddChecker implements SafetyChecker { private final SolverPool solverPool; private final XSTS xsts; @@ -66,7 +63,8 @@ public class XstsMddChecker implements SafetyChecker { private final Logger logger; private IterationStrategy iterationStrategy; - private XstsMddChecker(XSTS xsts, SolverPool solverPool, Logger logger, IterationStrategy iterationStrategy) { + private XstsMddChecker( + XSTS xsts, SolverPool solverPool, Logger logger, IterationStrategy iterationStrategy) { this.xsts = xsts; this.solverPool = solverPool; this.logger = logger; @@ -77,33 +75,64 @@ public static XstsMddChecker create(XSTS xsts, SolverPool solverPool, Logger log return new XstsMddChecker(xsts, solverPool, logger, IterationStrategy.GSAT); } - public static XstsMddChecker create(XSTS xsts, SolverPool solverPool, Logger logger, IterationStrategy iterationStrategy) { + public static XstsMddChecker create( + XSTS xsts, SolverPool solverPool, Logger logger, IterationStrategy iterationStrategy) { return new XstsMddChecker(xsts, solverPool, logger, iterationStrategy); } @Override - public SafetyResult check(Void input) { - - final MddGraph mddGraph = JavaMddFactory.getDefault().createMddGraph(ExprLatticeDefinition.forExpr()); - - final MddVariableOrder stateOrder = JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); - final MddVariableOrder transOrder = JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); - final MddVariableOrder initOrder = JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); - - final NonDetStmt envTran = NonDetStmt.of(xsts.getEnv().getStmts().stream().flatMap(e -> xsts.getTran().getStmts().stream().map(t -> (Stmt) SequenceStmt.of(List.of(e, t)))).toList()); + public SafetyResult check(Void input) { + + final MddGraph mddGraph = + JavaMddFactory.getDefault().createMddGraph(ExprLatticeDefinition.forExpr()); + + final MddVariableOrder stateOrder = + JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); + final MddVariableOrder transOrder = + JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); + final MddVariableOrder initOrder = + JavaMddFactory.getDefault().createMddVariableOrder(mddGraph); + + final NonDetStmt envTran = + NonDetStmt.of( + xsts.getEnv().getStmts().stream() + .flatMap( + e -> + xsts.getTran().getStmts().stream() + .map( + t -> + (Stmt) + SequenceStmt.of( + List.of( + e, + t)))) + .toList()); final var envTranToExprResult = StmtUtils.toExpr(envTran, VarIndexingFactory.indexing(0)); - final var initToExprResult = StmtUtils.toExpr(xsts.getInit(), VarIndexingFactory.indexing(0)); + final var initToExprResult = + StmtUtils.toExpr(xsts.getInit(), VarIndexingFactory.indexing(0)); for (var v : xsts.getVars()) { final var domainSize = /*v.getType() instanceof BoolType ? 2 :*/ 0; stateOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(0), domainSize)); - transOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(envTranToExprResult.getIndexing().get(v) == 0 ? 1 : envTranToExprResult.getIndexing().get(v)), domainSize)); + transOrder.createOnTop( + MddVariableDescriptor.create( + v.getConstDecl( + envTranToExprResult.getIndexing().get(v) == 0 + ? 1 + : envTranToExprResult.getIndexing().get(v)), + domainSize)); transOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(0), domainSize)); // TODO if indexes are identical, inject v'=v - initOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(initToExprResult.getIndexing().get(v) == 0 ? 1 : initToExprResult.getIndexing().get(v)), domainSize)); + initOrder.createOnTop( + MddVariableDescriptor.create( + v.getConstDecl( + initToExprResult.getIndexing().get(v) == 0 + ? 1 + : initToExprResult.getIndexing().get(v)), + domainSize)); initOrder.createOnTop(MddVariableDescriptor.create(v.getConstDecl(0), domainSize)); } @@ -112,21 +141,30 @@ public SafetyResult check(Void input) { final var initSig = initOrder.getDefaultSetSignature(); final Expr initExpr = PathUtils.unfold(xsts.getInitFormula(), 0); - final MddHandle initNode = stateSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(initExpr, o -> (Decl) o, solverPool)); + final MddHandle initNode = + stateSig.getTopVariableHandle() + .checkInNode(MddExpressionTemplate.of(initExpr, o -> (Decl) o, solverPool)); Preconditions.checkState(initToExprResult.getExprs().size() == 1); - final var initUnfold = PathUtils.unfold(initToExprResult.getExprs().stream().findFirst().get(), 0); + final var initUnfold = + PathUtils.unfold(initToExprResult.getExprs().stream().findFirst().get(), 0); final var initIdentityExprs = new ArrayList>(); for (var v : xsts.getVars()) { if (initToExprResult.getIndexing().get(v) == 0) initIdentityExprs.add(Eq(v.getConstDecl(0).getRef(), v.getConstDecl(1).getRef())); } final var initExprWithIdentity = And(initUnfold, And(initIdentityExprs)); - final MddHandle initTranNode = initSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(initExprWithIdentity, o -> (Decl) o, solverPool)); - final AbstractNextStateDescriptor initNextState = MddNodeNextStateDescriptor.of(initTranNode); + final MddHandle initTranNode = + initSig.getTopVariableHandle() + .checkInNode( + MddExpressionTemplate.of( + initExprWithIdentity, o -> (Decl) o, solverPool)); + final AbstractNextStateDescriptor initNextState = + MddNodeNextStateDescriptor.of(initTranNode); final var rel = new LegacyRelationalProductProvider(stateSig.getVariableOrder()); - final var initResult = rel.compute(initNode, initNextState, stateSig.getTopVariableHandle()); + final var initResult = + rel.compute(initNode, initNextState, stateSig.getTopVariableHandle()); logger.write(Level.INFO, "Created initial node"); @@ -138,13 +176,21 @@ public SafetyResult check(Void input) { final var identityExprs = new ArrayList>(); for (var v : xsts.getVars()) { if (stmtToExpr.getIndexing().get(v) < envTranToExprResult.getIndexing().get(v)) - identityExprs.add(Eq(v.getConstDecl(stmtToExpr.getIndexing().get(v)).getRef(), v.getConstDecl(envTranToExprResult.getIndexing().get(v)).getRef())); + identityExprs.add( + Eq( + v.getConstDecl(stmtToExpr.getIndexing().get(v)).getRef(), + v.getConstDecl(envTranToExprResult.getIndexing().get(v)) + .getRef())); if (envTranToExprResult.getIndexing().get(v) == 0) identityExprs.add(Eq(v.getConstDecl(0).getRef(), v.getConstDecl(1).getRef())); } if (!identityExprs.isEmpty()) stmtUnfold = And(stmtUnfold, And(identityExprs)); - MddHandle transitionNode = transSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(stmtUnfold, o -> (Decl) o, solverPool)); + MddHandle transitionNode = + transSig.getTopVariableHandle() + .checkInNode( + MddExpressionTemplate.of( + stmtUnfold, o -> (Decl) o, solverPool)); descriptors.add(MddNodeNextStateDescriptor.of(transitionNode)); } final AbstractNextStateDescriptor nextStates = OrNextStateDescriptor.create(descriptors); @@ -164,12 +210,20 @@ public SafetyResult check(Void input) { } default -> throw new IllegalStateException("Unexpected value: " + iterationStrategy); } - final MddHandle stateSpace = stateSpaceProvider.compute(MddNodeInitializer.of(initResult), nextStates, stateSig.getTopVariableHandle()); + final MddHandle stateSpace = + stateSpaceProvider.compute( + MddNodeInitializer.of(initResult), + nextStates, + stateSig.getTopVariableHandle()); logger.write(Level.INFO, "Enumerated state-space"); final Expr negatedPropExpr = PathUtils.unfold(Not(xsts.getProp()), 0); - final MddHandle propNode = stateSig.getTopVariableHandle().checkInNode(MddExpressionTemplate.of(negatedPropExpr, o -> (Decl) o, solverPool)); + final MddHandle propNode = + stateSig.getTopVariableHandle() + .checkInNode( + MddExpressionTemplate.of( + negatedPropExpr, o -> (Decl) o, solverPool)); final MddHandle propViolating = (MddHandle) stateSpace.intersection(propNode); @@ -181,16 +235,23 @@ public SafetyResult check(Void input) { final Long stateSpaceSize = MddInterpreter.calculateNonzeroCount(stateSpace); logger.write(Level.DETAIL, "State space size: " + stateSpaceSize); - final MddAnalysisStatistics statistics = new MddAnalysisStatistics(violatingSize, stateSpaceSize, stateSpaceProvider.getHitCount(), stateSpaceProvider.getQueryCount(), stateSpaceProvider.getCacheSize()); + final MddAnalysisStatistics statistics = + new MddAnalysisStatistics( + violatingSize, + stateSpaceSize, + stateSpaceProvider.getHitCount(), + stateSpaceProvider.getQueryCount(), + stateSpaceProvider.getCacheSize()); - final SafetyResult result; + final SafetyResult result; if (violatingSize != 0) { - result = SafetyResult.unsafe(MddCex.of(propViolating), MddWitness.of(stateSpace), statistics); + result = + SafetyResult.unsafe( + MddCex.of(propViolating), MddProof.of(stateSpace), statistics); } else { - result = SafetyResult.safe(MddWitness.of(stateSpace), statistics); + result = SafetyResult.safe(MddProof.of(stateSpace), statistics); } logger.write(Level.RESULT, "%s%n", result); return result; - } } diff --git a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsMddCheckerTest.java b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsMddCheckerTest.java index bda3053ed6..4208cdfd6a 100644 --- a/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsMddCheckerTest.java +++ b/subprojects/xsts/xsts-analysis/src/test/java/hu/bme/mit/theta/xsts/analysis/XstsMddCheckerTest.java @@ -15,10 +15,12 @@ */ package hu.bme.mit.theta.xsts.analysis; +import static org.junit.Assert.assertTrue; + import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.mdd.MddCex; import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker.IterationStrategy; -import hu.bme.mit.theta.analysis.algorithm.mdd.MddWitness; +import hu.bme.mit.theta.analysis.algorithm.mdd.MddProof; import hu.bme.mit.theta.common.logging.ConsoleLogger; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.solver.SolverPool; @@ -26,99 +28,159 @@ import hu.bme.mit.theta.xsts.XSTS; import hu.bme.mit.theta.xsts.analysis.mdd.XstsMddChecker; import hu.bme.mit.theta.xsts.dsl.XstsDslManager; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - import java.io.FileInputStream; -import java.io.IOException; import java.io.InputStream; import java.io.SequenceInputStream; import java.util.Arrays; import java.util.Collection; -import static org.junit.Assert.assertTrue; - public class XstsMddCheckerTest { public static Collection data() { - return Arrays.asList(new Object[][]{ - -// { "src/test/resources/model/trafficlight.xsts", "src/test/resources/property/green_and_red.prop", true}, - - {"src/test/resources/model/trafficlight_v2.xsts", "src/test/resources/property/green_and_red.prop", true}, - - {"src/test/resources/model/counter5.xsts", "src/test/resources/property/x_between_0_and_5.prop", true}, - - {"src/test/resources/model/counter5.xsts", "src/test/resources/property/x_eq_5.prop", false}, - - {"src/test/resources/model/x_and_y.xsts", "src/test/resources/property/x_geq_y.prop", true}, - - {"src/test/resources/model/x_powers.xsts", "src/test/resources/property/x_even.prop", true}, - -// { "src/test/resources/model/cross_with.xsts", "src/test/resources/property/cross.prop", false}, - -// { "src/test/resources/model/cross_without.xsts", "src/test/resources/property/cross.prop", false}, - - {"src/test/resources/model/choices.xsts", "src/test/resources/property/choices.prop", false}, - -// { "src/test/resources/model/literals.xsts", "src/test/resources/property/literals.prop", true}, - -// { "src/test/resources/model/cross3.xsts", "src/test/resources/property/cross.prop", false}, - - {"src/test/resources/model/sequential.xsts", "src/test/resources/property/sequential.prop", true}, - - {"src/test/resources/model/sequential.xsts", "src/test/resources/property/sequential2.prop", false}, - - {"src/test/resources/model/on_off_statemachine.xsts", "src/test/resources/property/on_off_statemachine.prop", false}, - - {"src/test/resources/model/on_off_statemachine.xsts", "src/test/resources/property/on_off_statemachine2.prop", true}, - - {"src/test/resources/model/on_off_statemachine.xsts", "src/test/resources/property/on_off_statemachine3.prop", false}, - -// {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_5.prop", false}, -// -// {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_50.prop", false}, -// -// {"src/test/resources/model/counter50.xsts", "src/test/resources/property/x_eq_51.prop", true}, - - {"src/test/resources/model/count_up_down.xsts", "src/test/resources/property/count_up_down.prop", false}, - - {"src/test/resources/model/count_up_down.xsts", "src/test/resources/property/count_up_down2.prop", true}, - -// {"src/test/resources/model/bhmr2007.xsts", "src/test/resources/property/bhmr2007.prop", true}, -// -// {"src/test/resources/model/css2003.xsts", "src/test/resources/property/css2003.prop", true}, -// -// { "src/test/resources/model/array_counter.xsts", "src/test/resources/property/array_10.prop", false}, -// -// { "src/test/resources/model/array_constant.xsts", "src/test/resources/property/array_constant.prop", true}, -// -// { "src/test/resources/model/localvars.xsts", "src/test/resources/property/localvars.prop", true}, -// -// { "src/test/resources/model/localvars2.xsts", "src/test/resources/property/localvars2.prop", true}, -// -// { "src/test/resources/model/loopxy.xsts", "src/test/resources/property/loopxy.prop", true}, -// -// { "src/test/resources/model/arraywrite_sugar.xsts", "src/test/resources/property/arraywrite_sugar.prop", false}, -// -// { "src/test/resources/model/if1.xsts", "src/test/resources/property/if1.prop", true}, -// -// { "src/test/resources/model/if2.xsts", "src/test/resources/property/if2.prop", false} - }); + return Arrays.asList( + new Object[][] { + + // { "src/test/resources/model/trafficlight.xsts", + // "src/test/resources/property/green_and_red.prop", true}, + + { + "src/test/resources/model/trafficlight_v2.xsts", + "src/test/resources/property/green_and_red.prop", + true + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_between_0_and_5.prop", + true + }, + { + "src/test/resources/model/counter5.xsts", + "src/test/resources/property/x_eq_5.prop", + false + }, + { + "src/test/resources/model/x_and_y.xsts", + "src/test/resources/property/x_geq_y.prop", + true + }, + { + "src/test/resources/model/x_powers.xsts", + "src/test/resources/property/x_even.prop", + true + }, + + // { "src/test/resources/model/cross_with.xsts", + // "src/test/resources/property/cross.prop", false}, + + // { "src/test/resources/model/cross_without.xsts", + // "src/test/resources/property/cross.prop", false}, + + { + "src/test/resources/model/choices.xsts", + "src/test/resources/property/choices.prop", + false + }, + + // { "src/test/resources/model/literals.xsts", + // "src/test/resources/property/literals.prop", true}, + + // { "src/test/resources/model/cross3.xsts", + // "src/test/resources/property/cross.prop", false}, + + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential.prop", + true + }, + { + "src/test/resources/model/sequential.xsts", + "src/test/resources/property/sequential2.prop", + false + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine.prop", + false + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine2.prop", + true + }, + { + "src/test/resources/model/on_off_statemachine.xsts", + "src/test/resources/property/on_off_statemachine3.prop", + false + }, + + // {"src/test/resources/model/counter50.xsts", + // "src/test/resources/property/x_eq_5.prop", false}, + // + // {"src/test/resources/model/counter50.xsts", + // "src/test/resources/property/x_eq_50.prop", false}, + // + // {"src/test/resources/model/counter50.xsts", + // "src/test/resources/property/x_eq_51.prop", true}, + + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down.prop", + false + }, + { + "src/test/resources/model/count_up_down.xsts", + "src/test/resources/property/count_up_down2.prop", + true + }, + + // {"src/test/resources/model/bhmr2007.xsts", + // "src/test/resources/property/bhmr2007.prop", true}, + // + // {"src/test/resources/model/css2003.xsts", + // "src/test/resources/property/css2003.prop", true}, + // + // { "src/test/resources/model/array_counter.xsts", + // "src/test/resources/property/array_10.prop", false}, + // + // { "src/test/resources/model/array_constant.xsts", + // "src/test/resources/property/array_constant.prop", true}, + // + // { "src/test/resources/model/localvars.xsts", + // "src/test/resources/property/localvars.prop", true}, + // + // { "src/test/resources/model/localvars2.xsts", + // "src/test/resources/property/localvars2.prop", true}, + // + // { "src/test/resources/model/loopxy.xsts", + // "src/test/resources/property/loopxy.prop", true}, + // + // { "src/test/resources/model/arraywrite_sugar.xsts", + // "src/test/resources/property/arraywrite_sugar.prop", false}, + // + // { "src/test/resources/model/if1.xsts", + // "src/test/resources/property/if1.prop", true}, + // + // { "src/test/resources/model/if2.xsts", + // "src/test/resources/property/if2.prop", false} + }); } - public static void runTestWithIterationStrategy(String filePath, String propPath, boolean safe, IterationStrategy iterationStrategy) throws Exception { + public static void runTestWithIterationStrategy( + String filePath, String propPath, boolean safe, IterationStrategy iterationStrategy) + throws Exception { final Logger logger = new ConsoleLogger(Logger.Level.SUBSTEP); XSTS xsts; - try (InputStream inputStream = new SequenceInputStream(new FileInputStream(filePath), new FileInputStream(propPath))) { + try (InputStream inputStream = + new SequenceInputStream( + new FileInputStream(filePath), new FileInputStream(propPath))) { xsts = XstsDslManager.createXsts(inputStream); } - final SafetyResult status; + final SafetyResult status; try (var solverPool = new SolverPool(Z3LegacySolverFactory.getInstance())) { - final XstsMddChecker checker = XstsMddChecker.create(xsts, solverPool, logger, iterationStrategy); + final XstsMddChecker checker = + XstsMddChecker.create(xsts, solverPool, logger, iterationStrategy); status = checker.check(null); } @@ -128,5 +190,4 @@ public static void runTestWithIterationStrategy(String filePath, String propPath assertTrue(status.isUnsafe()); } } - } diff --git a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliBounded.kt b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliBounded.kt index b0582bf87f..7df23a5d53 100644 --- a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliBounded.kt +++ b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliBounded.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.cli import com.github.ajalt.clikt.parameters.options.default @@ -21,7 +20,7 @@ import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.types.enum import com.google.common.base.Stopwatch import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness +import hu.bme.mit.theta.analysis.algorithm.EmptyProof import hu.bme.mit.theta.analysis.algorithm.SafetyResult import hu.bme.mit.theta.analysis.algorithm.bounded.* import hu.bme.mit.theta.analysis.expl.ExplState @@ -40,84 +39,109 @@ import kotlin.system.exitProcess typealias S = XstsState -class XstsCliBounded : XstsCliBaseCommand( +class XstsCliBounded : + XstsCliBaseCommand( name = "BOUNDED", - help = "Bounded model checking algorithms (BMC, IMC, KINDUCTION). Use --variant to select the algorithm (by default BMC is selected)." -) { - - enum class Variant { - BMC { + help = + "Bounded model checking algorithms (BMC, IMC, KINDUCTION). Use --variant to select the algorithm (by default BMC is selected).", + ) { - override fun buildChecker( - monolithicExpr: MonolithicExpr, solverFactory: SolverFactory, - valToState: (Valuation) -> S, biValToAction: (Valuation, Valuation) -> XstsAction, - logger: Logger - ) = buildBMC(monolithicExpr, solverFactory.createSolver(), valToState, biValToAction, logger) - }, - KINDUCTION { + enum class Variant { + BMC { - override fun buildChecker( - monolithicExpr: MonolithicExpr, solverFactory: SolverFactory, - valToState: (Valuation) -> S, biValToAction: (Valuation, Valuation) -> XstsAction, - logger: Logger - ) = buildKIND( - monolithicExpr, solverFactory.createSolver(), solverFactory.createSolver(), valToState, biValToAction, - logger - ) - }, - IMC { + override fun buildChecker( + monolithicExpr: MonolithicExpr, + solverFactory: SolverFactory, + valToState: (Valuation) -> S, + biValToAction: (Valuation, Valuation) -> XstsAction, + logger: Logger, + ) = buildBMC(monolithicExpr, solverFactory.createSolver(), valToState, biValToAction, logger) + }, + KINDUCTION { - override fun buildChecker( - monolithicExpr: MonolithicExpr, solverFactory: SolverFactory, - valToState: (Valuation) -> S, biValToAction: (Valuation, Valuation) -> XstsAction, - logger: Logger - ) = buildIMC( - monolithicExpr, solverFactory.createSolver(), solverFactory.createItpSolver(), valToState, - biValToAction, logger - ) - }; + override fun buildChecker( + monolithicExpr: MonolithicExpr, + solverFactory: SolverFactory, + valToState: (Valuation) -> S, + biValToAction: (Valuation, Valuation) -> XstsAction, + logger: Logger, + ) = + buildKIND( + monolithicExpr, + solverFactory.createSolver(), + solverFactory.createSolver(), + valToState, + biValToAction, + logger, + ) + }, + IMC { - abstract fun buildChecker( - monolithicExpr: MonolithicExpr, solverFactory: SolverFactory, valToState: (Valuation) -> S, - biValToAction: (Valuation, Valuation) -> XstsAction, logger: Logger - ): BoundedChecker - } + override fun buildChecker( + monolithicExpr: MonolithicExpr, + solverFactory: SolverFactory, + valToState: (Valuation) -> S, + biValToAction: (Valuation, Valuation) -> XstsAction, + logger: Logger, + ) = + buildIMC( + monolithicExpr, + solverFactory.createSolver(), + solverFactory.createItpSolver(), + valToState, + biValToAction, + logger, + ) + }; - private val variant by option().enum().default(Variant.BMC) + abstract fun buildChecker( + monolithicExpr: MonolithicExpr, + solverFactory: SolverFactory, + valToState: (Valuation) -> S, + biValToAction: (Valuation, Valuation) -> XstsAction, + logger: Logger, + ): BoundedChecker + } - private fun printResult(status: SafetyResult>, xsts: XSTS, totalTimeMs: Long) { - if (!outputOptions.benchmarkMode) return - printCommonResult(status, xsts, totalTimeMs) - val stats = status.stats.orElse(BoundedStatistics(0)) as BoundedStatistics - listOf( - stats.iterations, - ).forEach(writer::cell) - writer.newRow() - } + private val variant by option().enum().default(Variant.BMC) - override fun run() { - try { - doRun() - } catch (e: Exception) { - printError(e) - exitProcess(1) - } - } + private fun printResult( + status: SafetyResult>, + xsts: XSTS, + totalTimeMs: Long, + ) { + if (!outputOptions.benchmarkMode) return + printCommonResult(status, xsts, totalTimeMs) + val stats = status.stats.orElse(BoundedStatistics(0)) as BoundedStatistics + listOf(stats.iterations).forEach(writer::cell) + writer.newRow() + } - private fun doRun() { - registerSolverManagers() - val solverFactory = SolverManager.resolveSolverFactory(solver) - val xsts = inputOptions.loadXsts() - val sw = Stopwatch.createStarted() - val checker = variant.buildChecker( - xsts.toMonolithicExpr(), solverFactory, xsts::valToState, - xsts::valToAction, - logger - ) - val result = checker.check() - sw.stop() - printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) - writeCex(result, xsts) + override fun run() { + try { + doRun() + } catch (e: Exception) { + printError(e) + exitProcess(1) } + } -} \ No newline at end of file + private fun doRun() { + registerSolverManagers() + val solverFactory = SolverManager.resolveSolverFactory(solver) + val xsts = inputOptions.loadXsts() + val sw = Stopwatch.createStarted() + val checker = + variant.buildChecker( + xsts.toMonolithicExpr(), + solverFactory, + xsts::valToState, + xsts::valToAction, + logger, + ) + val result = checker.check() + sw.stop() + printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + writeCex(result, xsts) + } +} diff --git a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliCegar.kt b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliCegar.kt index ee455f86dc..ade34d7127 100644 --- a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliCegar.kt +++ b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliCegar.kt @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.cli import com.github.ajalt.clikt.parameters.options.default @@ -38,73 +37,90 @@ import hu.bme.mit.theta.xsts.analysis.config.XstsConfigBuilder.* import java.util.concurrent.TimeUnit import kotlin.system.exitProcess -class XstsCliCegar : XstsCliBaseCommand( +class XstsCliCegar : + XstsCliBaseCommand( name = "CEGAR", - help = "Model checking using the CEGAR (CounterExample Guided Abstraction Refinement) algorithm" -) { + help = "Model checking using the CEGAR (CounterExample Guided Abstraction Refinement) algorithm", + ) { - private val domain: Domain by option(help = "Abstraction domain to use").enum().default(Domain.PRED_CART) - private val refinement: Refinement by option(help = "Refinement strategy to use").enum() - .default(Refinement.SEQ_ITP) - private val search: Search by option(help = "Search strategy to use").enum().default(Search.BFS) - private val refinementSolver: String? by option(help = "Use a different solver for abstraction") - private val abstractionSolver: String? by option(help = "Use a different solver for refinement") - private val predsplit: PredSplit by option().enum().default(PredSplit.WHOLE) - private val maxenum: Int by option().int().default(0) - private val autoexpl: AutoExpl by option().enum().default(AutoExpl.NEWOPERANDS) - private val initprec: InitPrec by option().enum().default(InitPrec.EMPTY) - private val prunestrategy: PruneStrategy by option().enum().default(PruneStrategy.LAZY) - private val optimizestmts: OptimizeStmts by option().enum().default(OptimizeStmts.ON) + private val domain: Domain by + option(help = "Abstraction domain to use").enum().default(Domain.PRED_CART) + private val refinement: Refinement by + option(help = "Refinement strategy to use").enum().default(Refinement.SEQ_ITP) + private val search: Search by + option(help = "Search strategy to use").enum().default(Search.BFS) + private val refinementSolver: String? by option(help = "Use a different solver for abstraction") + private val abstractionSolver: String? by option(help = "Use a different solver for refinement") + private val predsplit: PredSplit by option().enum().default(PredSplit.WHOLE) + private val maxenum: Int by option().int().default(0) + private val autoexpl: AutoExpl by option().enum().default(AutoExpl.NEWOPERANDS) + private val initprec: InitPrec by option().enum().default(InitPrec.EMPTY) + private val prunestrategy: PruneStrategy by + option().enum().default(PruneStrategy.LAZY) + private val optimizestmts: OptimizeStmts by + option().enum().default(OptimizeStmts.ON) - private fun printResult(status: SafetyResult?, out Trace<*, *>?>, xsts: XSTS, totalTimeMs: Long) { - if (!outputOptions.benchmarkMode) return - printCommonResult(status, xsts, totalTimeMs) - val stats = status.stats.orElse(CegarStatistics(0, 0, 0, 0)) as CegarStatistics - listOf( - stats.algorithmTimeMs, - stats.abstractorTimeMs, - stats.refinerTimeMs, - stats.iterations, - status.witness!!.size(), - status.witness!!.depth, - status.witness!!.meanBranchingFactor, - ).forEach(writer::cell) - writer.newRow() - } + private fun printResult( + status: SafetyResult?, out Trace<*, *>?>, + xsts: XSTS, + totalTimeMs: Long, + ) { + if (!outputOptions.benchmarkMode) return + printCommonResult(status, xsts, totalTimeMs) + val stats = status.stats.orElse(CegarStatistics(0, 0, 0, 0)) as CegarStatistics + listOf( + stats.algorithmTimeMs, + stats.abstractorTimeMs, + stats.refinerTimeMs, + stats.iterations, + status.proof!!.size(), + status.proof!!.depth, + status.proof!!.meanBranchingFactor, + ) + .forEach(writer::cell) + writer.newRow() + } - private fun writeVisualStatus( - status: SafetyResult?, out Trace?> - ) { - if (outputOptions.visualize == null) return - val graph = if (status.isSafe) ArgVisualizer.getDefault().visualize(status.asSafe().witness) - else TraceVisualizer.getDefault().visualize(status.asUnsafe().cex) - GraphvizWriter.getInstance().writeFile(graph, outputOptions.visualize!!) - } - - override fun run() { - try { - doRun() - } catch (e: Exception) { - printError(e) - exitProcess(1) - } - } + private fun writeVisualStatus( + status: SafetyResult?, out Trace?> + ) { + if (outputOptions.visualize == null) return + val graph = + if (status.isSafe) ArgVisualizer.getDefault().visualize(status.asSafe().proof) + else TraceVisualizer.getDefault().visualize(status.asUnsafe().cex) + GraphvizWriter.getInstance().writeFile(graph, outputOptions.visualize!!) + } - private fun doRun() { - registerSolverManagers() - val abstractionSolverFactory = SolverManager.resolveSolverFactory(abstractionSolver ?: solver) - val refinementSolverFactory = SolverManager.resolveSolverFactory(refinementSolver ?: solver) - val xsts = inputOptions.loadXsts() - val config = - XstsConfigBuilder(domain, refinement, abstractionSolverFactory, refinementSolverFactory).maxEnum(maxenum) - .autoExpl(autoexpl).initPrec(initprec).pruneStrategy(prunestrategy).search(search).predSplit(predsplit) - .optimizeStmts(optimizestmts).logger(logger).build(xsts) - val sw = Stopwatch.createStarted() - val result = config.check() - sw.stop() - printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) - writeCex(result, xsts) - writeVisualStatus(result) + override fun run() { + try { + doRun() + } catch (e: Exception) { + printError(e) + exitProcess(1) } + } -} \ No newline at end of file + private fun doRun() { + registerSolverManagers() + val abstractionSolverFactory = SolverManager.resolveSolverFactory(abstractionSolver ?: solver) + val refinementSolverFactory = SolverManager.resolveSolverFactory(refinementSolver ?: solver) + val xsts = inputOptions.loadXsts() + val config = + XstsConfigBuilder(domain, refinement, abstractionSolverFactory, refinementSolverFactory) + .maxEnum(maxenum) + .autoExpl(autoexpl) + .initPrec(initprec) + .pruneStrategy(prunestrategy) + .search(search) + .predSplit(predsplit) + .optimizeStmts(optimizestmts) + .logger(logger) + .build(xsts) + val sw = Stopwatch.createStarted() + val result = config.check() + sw.stop() + printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + writeCex(result, xsts) + writeVisualStatus(result) + } +} diff --git a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMdd.kt b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMdd.kt index cc74818770..f64094d0a8 100644 --- a/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMdd.kt +++ b/subprojects/xsts/xsts-cli/src/main/kotlin/hu/bme/mit/theta/xsts/cli/XstsCliMdd.kt @@ -13,80 +13,70 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package hu.bme.mit.theta.xsts.cli import com.github.ajalt.clikt.parameters.options.default import com.github.ajalt.clikt.parameters.options.option -import com.github.ajalt.clikt.parameters.options.required import com.github.ajalt.clikt.parameters.types.enum import com.google.common.base.Stopwatch -import hu.bme.mit.theta.analysis.Trace -import hu.bme.mit.theta.analysis.algorithm.EmptyWitness import hu.bme.mit.theta.analysis.algorithm.SafetyResult -import hu.bme.mit.theta.analysis.algorithm.bounded.* -import hu.bme.mit.theta.analysis.algorithm.cegar.CegarStatistics import hu.bme.mit.theta.analysis.algorithm.mdd.MddAnalysisStatistics import hu.bme.mit.theta.analysis.algorithm.mdd.MddCex import hu.bme.mit.theta.analysis.algorithm.mdd.MddChecker -import hu.bme.mit.theta.analysis.algorithm.mdd.MddWitness -import hu.bme.mit.theta.common.logging.Logger -import hu.bme.mit.theta.core.model.Valuation -import hu.bme.mit.theta.solver.SolverFactory +import hu.bme.mit.theta.analysis.algorithm.mdd.MddProof import hu.bme.mit.theta.solver.SolverManager import hu.bme.mit.theta.solver.SolverPool import hu.bme.mit.theta.xsts.XSTS -import hu.bme.mit.theta.xsts.analysis.XstsAction -import hu.bme.mit.theta.xsts.analysis.hu.bme.mit.theta.xsts.analysis.toMonolithicExpr -import hu.bme.mit.theta.xsts.analysis.hu.bme.mit.theta.xsts.analysis.valToAction -import hu.bme.mit.theta.xsts.analysis.hu.bme.mit.theta.xsts.analysis.valToState import hu.bme.mit.theta.xsts.analysis.mdd.XstsMddChecker import java.util.concurrent.TimeUnit import kotlin.system.exitProcess -class XstsCliMdd : XstsCliBaseCommand( +class XstsCliMdd : + XstsCliBaseCommand( name = "MDD", - help = "Model checking of XSTS using MDDs (Multi-value Decision Diagrams)" -) { - - private val iterationStrategy: MddChecker.IterationStrategy by option( - help = "The state space enumeration algorithm to use" - ).enum().default(MddChecker.IterationStrategy.GSAT) + help = "Model checking of XSTS using MDDs (Multi-value Decision Diagrams)", + ) { - private fun printResult(status: SafetyResult, xsts: XSTS, totalTimeMs: Long) { - if (!outputOptions.benchmarkMode) return - printCommonResult(status, xsts, totalTimeMs) - val stats = status.stats.orElse(MddAnalysisStatistics(0, 0, 0, 0, 0)) as MddAnalysisStatistics - listOf( - stats.violatingSize, - stats.stateSpaceSize, - stats.hitCount, - stats.queryCount, - stats.cacheSize, - ).forEach(writer::cell) - writer.newRow() - } + private val iterationStrategy: MddChecker.IterationStrategy by + option(help = "The state space enumeration algorithm to use") + .enum() + .default(MddChecker.IterationStrategy.GSAT) - override fun run() { - try { - doRun() - } catch (e: Exception) { - printError(e) - exitProcess(1) - } - } + private fun printResult(status: SafetyResult, xsts: XSTS, totalTimeMs: Long) { + if (!outputOptions.benchmarkMode) return + printCommonResult(status, xsts, totalTimeMs) + val stats = status.stats.orElse(MddAnalysisStatistics(0, 0, 0, 0, 0)) as MddAnalysisStatistics + listOf( + stats.violatingSize, + stats.stateSpaceSize, + stats.hitCount, + stats.queryCount, + stats.cacheSize, + ) + .forEach(writer::cell) + writer.newRow() + } - private fun doRun() { - registerSolverManagers() - val solverFactory = SolverManager.resolveSolverFactory(solver) - val xsts = inputOptions.loadXsts() - val sw = Stopwatch.createStarted() - val result = SolverPool(solverFactory).use { - val checker = XstsMddChecker.create(xsts, it, logger, iterationStrategy) - checker.check(null) - } - sw.stop() - printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + override fun run() { + try { + doRun() + } catch (e: Exception) { + printError(e) + exitProcess(1) } + } -} \ No newline at end of file + private fun doRun() { + registerSolverManagers() + val solverFactory = SolverManager.resolveSolverFactory(solver) + val xsts = inputOptions.loadXsts() + val sw = Stopwatch.createStarted() + val result = + SolverPool(solverFactory).use { + val checker = XstsMddChecker.create(xsts, it, logger, iterationStrategy) + checker.check(null) + } + sw.stop() + printResult(result, xsts, sw.elapsed(TimeUnit.MILLISECONDS)) + } +} diff --git a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/LazyXtaCheckerTest.java b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/LazyXtaCheckerTest.java index be1fc4afe0..eefc740ce6 100644 --- a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/LazyXtaCheckerTest.java +++ b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/LazyXtaCheckerTest.java @@ -15,13 +15,17 @@ */ package hu.bme.mit.theta.xta.analysis; +import static hu.bme.mit.theta.analysis.algorithm.arg.SearchStrategy.BFS; +import static hu.bme.mit.theta.xta.analysis.lazy.ClockStrategy.LU; +import static org.junit.Assert.assertTrue; + import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import hu.bme.mit.theta.analysis.Trace; +import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.SafetyResult; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; import hu.bme.mit.theta.analysis.algorithm.arg.ArgChecker; -import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.unit.UnitPrec; import hu.bme.mit.theta.solver.z3legacy.Z3LegacySolverFactory; import hu.bme.mit.theta.xta.XtaSystem; @@ -29,6 +33,10 @@ import hu.bme.mit.theta.xta.analysis.lazy.DataStrategy; import hu.bme.mit.theta.xta.analysis.lazy.LazyXtaCheckerFactory; import hu.bme.mit.theta.xta.dsl.XtaDslManager; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -36,15 +44,6 @@ import org.junit.runners.Parameterized.Parameter; import org.junit.runners.Parameterized.Parameters; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.Collection; - -import static hu.bme.mit.theta.analysis.algorithm.arg.SearchStrategy.BFS; -import static hu.bme.mit.theta.xta.analysis.lazy.ClockStrategy.LU; -import static org.junit.Assert.assertTrue; - @RunWith(Parameterized.class) public final class LazyXtaCheckerTest { @@ -55,13 +54,17 @@ public final class LazyXtaCheckerTest { private static final String MODEL_ENGINE = "/engine-classic.xta"; private static final String MODEL_BROADCAST = "/broadcast.xta"; - private static final Collection MODELS = ImmutableList.of(MODEL_CSMA, MODEL_FDDI, - MODEL_FISCHER, - MODEL_LYNCH, MODEL_ENGINE, MODEL_BROADCAST); + private static final Collection MODELS = + ImmutableList.of( + MODEL_CSMA, + MODEL_FDDI, + MODEL_FISCHER, + MODEL_LYNCH, + MODEL_ENGINE, + MODEL_BROADCAST); - private static final Collection MODELS_WITH_UNKNOWN_SOLVER_STATUS = ImmutableSet.of( - MODEL_FDDI, - MODEL_ENGINE, MODEL_BROADCAST); + private static final Collection MODELS_WITH_UNKNOWN_SOLVER_STATUS = + ImmutableSet.of(MODEL_FDDI, MODEL_ENGINE, MODEL_BROADCAST); @Parameter(0) public String filepath; @@ -72,7 +75,11 @@ public final class LazyXtaCheckerTest { @Parameter(2) public ClockStrategy clockStrategy; - private SafetyChecker, XtaAction>, ? extends Trace, XtaAction>, UnitPrec> checker; + private SafetyChecker< + ? extends ARG, XtaAction>, + ? extends Trace, XtaAction>, + UnitPrec> + checker; @Parameters(name = "model: {0}, discrete: {1}, clock: {2}") public static Collection data() { @@ -80,9 +87,9 @@ public static Collection data() { for (final String model : MODELS) { for (final DataStrategy dataStrategy : DataStrategy.values()) { for (final ClockStrategy clockStrategy : ClockStrategy.values()) { - if (!MODELS_WITH_UNKNOWN_SOLVER_STATUS.contains(model) || (clockStrategy - != LU)) { - result.add(new Object[]{model, dataStrategy, clockStrategy}); + if (!MODELS_WITH_UNKNOWN_SOLVER_STATUS.contains(model) + || (clockStrategy != LU)) { + result.add(new Object[] {model, dataStrategy, clockStrategy}); } } } @@ -100,14 +107,15 @@ public void initialize() throws IOException { @Test public void test() { // Act - final SafetyResult, XtaAction>, ? extends Trace, XtaAction>> status = checker.check( - UnitPrec.getInstance()); + final SafetyResult< + ? extends ARG, XtaAction>, + ? extends Trace, XtaAction>> + status = checker.check(UnitPrec.getInstance()); // Assert - final ArgChecker argChecker = ArgChecker.create( - Z3LegacySolverFactory.getInstance().createSolver()); - final boolean argCheckResult = argChecker.isWellLabeled(status.getWitness()); + final ArgChecker argChecker = + ArgChecker.create(Z3LegacySolverFactory.getInstance().createSolver()); + final boolean argCheckResult = argChecker.isWellLabeled(status.getProof()); assertTrue(argCheckResult); } - } diff --git a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java index 6bbc845a97..aabfaa25e3 100644 --- a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java +++ b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaAnalysisTest.java @@ -15,18 +15,6 @@ */ package hu.bme.mit.theta.xta.analysis; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collection; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - import hu.bme.mit.theta.analysis.Analysis; import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; @@ -40,27 +28,31 @@ import hu.bme.mit.theta.common.visualization.writer.GraphvizWriter; import hu.bme.mit.theta.xta.XtaSystem; import hu.bme.mit.theta.xta.dsl.XtaDslManager; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collection; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public final class XtaAnalysisTest { @Parameters(name = "{0}") public static Collection data() { - return Arrays.asList(new Object[][]{ - - {"/critical-2-25-50.xta"}, - - {"/csma-2.xta"}, - - {"/fddi-2.xta"}, - - {"/fischer-2-32-64.xta"}, - - {"/lynch-2-16.xta"}, - - {"/broadcast.xta"}, - - }); + return Arrays.asList( + new Object[][] { + {"/critical-2-25-50.xta"}, + {"/csma-2.xta"}, + {"/fddi-2.xta"}, + {"/fischer-2-32-64.xta"}, + {"/lynch-2-16.xta"}, + {"/broadcast.xta"}, + }); } @Parameter(0) @@ -72,22 +64,19 @@ public void test() throws FileNotFoundException, IOException { final XtaSystem system = XtaDslManager.createSystem(inputStream); final LTS, XtaAction> lts = XtaLts.create(system); - final Analysis, XtaAction, UnitPrec> analysis = XtaAnalysis.create( - system, - UnitAnalysis.getInstance()); - final ArgBuilder, XtaAction, UnitPrec> argBuilder = ArgBuilder.create( - lts, analysis, - s -> false); + final Analysis, XtaAction, UnitPrec> analysis = + XtaAnalysis.create(system, UnitAnalysis.getInstance()); + final ArgBuilder, XtaAction, UnitPrec> argBuilder = + ArgBuilder.create(lts, analysis, s -> false); - final ArgAbstractor, XtaAction, UnitPrec> abstractor = BasicArgAbstractor.builder( - argBuilder) - .projection(s -> s.getLocs()).build(); + final ArgAbstractor, XtaAction, UnitPrec> abstractor = + BasicArgAbstractor.builder(argBuilder).projection(s -> s.getLocs()).build(); - final ARG, XtaAction> arg = abstractor.createWitness(); + final ARG, XtaAction> arg = abstractor.createProof(); abstractor.check(arg, UnitPrec.getInstance()); System.out.println( - GraphvizWriter.getInstance().writeString(ArgVisualizer.getDefault().visualize(arg))); + GraphvizWriter.getInstance() + .writeString(ArgVisualizer.getDefault().visualize(arg))); } - } diff --git a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java index 111e451934..1c1e6fa56e 100644 --- a/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java +++ b/subprojects/xta/xta-analysis/src/test/java/hu/bme/mit/theta/xta/analysis/XtaZoneAnalysisTest.java @@ -15,19 +15,6 @@ */ package hu.bme.mit.theta.xta.analysis; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Arrays; -import java.util.Collection; -import java.util.stream.Collectors; - -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameter; -import org.junit.runners.Parameterized.Parameters; - import hu.bme.mit.theta.analysis.Analysis; import hu.bme.mit.theta.analysis.LTS; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; @@ -46,25 +33,31 @@ import hu.bme.mit.theta.xta.analysis.expl.XtaExplAnalysis; import hu.bme.mit.theta.xta.analysis.zone.XtaZoneAnalysis; import hu.bme.mit.theta.xta.dsl.XtaDslManager; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.stream.Collectors; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameter; +import org.junit.runners.Parameterized.Parameters; @RunWith(Parameterized.class) public final class XtaZoneAnalysisTest { @Parameters(name = "{0}") public static Collection data() { - return Arrays.asList(new Object[][]{ - - {"/csma-2.xta"}, - - {"/fddi-2.xta"}, - - {"/fischer-2-32-64.xta"}, - - {"/lynch-2-16.xta"}, - - {"/broadcast.xta"}, - - }); + return Arrays.asList( + new Object[][] { + {"/csma-2.xta"}, + {"/fddi-2.xta"}, + {"/fischer-2-32-64.xta"}, + {"/lynch-2-16.xta"}, + {"/broadcast.xta"}, + }); } @Parameter(0) @@ -76,30 +69,32 @@ public void test() throws FileNotFoundException, IOException { final XtaSystem system = XtaDslManager.createSystem(inputStream); final LTS, XtaAction> lts = XtaLts.create(system); - final Analysis explAnalysis = XtaExplAnalysis.create( - system); + final Analysis explAnalysis = + XtaExplAnalysis.create(system); final Analysis zoneAnalysis = XtaZoneAnalysis.getInstance(); - final Analysis, XtaAction, Prod2Prec> prodAnalysis = Prod2Analysis - .create(explAnalysis, zoneAnalysis); - final Analysis, XtaAction, ZonePrec> mappedAnalysis = PrecMappingAnalysis - .create(prodAnalysis, z -> Prod2Prec.of(UnitPrec.getInstance(), z)); - final Analysis>, XtaAction, ZonePrec> analysis = XtaAnalysis - .create(system, mappedAnalysis); + final Analysis, XtaAction, Prod2Prec> + prodAnalysis = Prod2Analysis.create(explAnalysis, zoneAnalysis); + final Analysis, XtaAction, ZonePrec> mappedAnalysis = + PrecMappingAnalysis.create( + prodAnalysis, z -> Prod2Prec.of(UnitPrec.getInstance(), z)); + final Analysis>, XtaAction, ZonePrec> analysis = + XtaAnalysis.create(system, mappedAnalysis); final ZonePrec prec = ZonePrec.of(system.getClockVars()); - final ArgBuilder>, XtaAction, ZonePrec> argBuilder = ArgBuilder - .create(lts, analysis, s -> false); + final ArgBuilder>, XtaAction, ZonePrec> + argBuilder = ArgBuilder.create(lts, analysis, s -> false); - final ArgAbstractor>, XtaAction, ZonePrec> abstractor = BasicArgAbstractor - .builder(argBuilder).projection(s -> s.getLocs()).build(); + final ArgAbstractor>, XtaAction, ZonePrec> + abstractor = + BasicArgAbstractor.builder(argBuilder).projection(s -> s.getLocs()).build(); - final ARG>, XtaAction> arg = abstractor.createWitness(); + final ARG>, XtaAction> arg = + abstractor.createProof(); abstractor.check(arg, prec); System.out.println(arg.getNodes().collect(Collectors.toSet())); System.out.println(arg.getNodes().count()); } - } diff --git a/subprojects/xta/xta-cli/src/main/java/hu/bme/mit/theta/xta/cli/XtaCli.java b/subprojects/xta/xta-cli/src/main/java/hu/bme/mit/theta/xta/cli/XtaCli.java index 4bf1694ff4..7f5185f6fb 100644 --- a/subprojects/xta/xta-cli/src/main/java/hu/bme/mit/theta/xta/cli/XtaCli.java +++ b/subprojects/xta/xta-cli/src/main/java/hu/bme/mit/theta/xta/cli/XtaCli.java @@ -15,12 +15,9 @@ */ package hu.bme.mit.theta.xta.cli; -import java.io.*; - import com.beust.jcommander.JCommander; import com.beust.jcommander.Parameter; import com.beust.jcommander.ParameterException; - import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.analysis.Trace; @@ -42,6 +39,7 @@ import hu.bme.mit.theta.xta.analysis.lazy.LazyXtaCheckerFactory; import hu.bme.mit.theta.xta.analysis.lazy.LazyXtaStatistics; import hu.bme.mit.theta.xta.dsl.XtaDslManager; +import java.io.*; public final class XtaCli { @@ -49,29 +47,44 @@ public final class XtaCli { private final String[] args; private final TableWriter writer; - @Parameter(names = {"--model", "-m"}, description = "Path of the input model", required = true) + @Parameter( + names = {"--model", "-m"}, + description = "Path of the input model", + required = true) String model; - @Parameter(names = {"--discrete", - "-d"}, description = "Refinement strategy for discrete variables", required = false) + @Parameter( + names = {"--discrete", "-d"}, + description = "Refinement strategy for discrete variables", + required = false) DataStrategy dataStrategy = DataStrategy.NONE; - @Parameter(names = {"--clock", - "-c"}, description = "Refinement strategy for clock variables", required = true) + @Parameter( + names = {"--clock", "-c"}, + description = "Refinement strategy for clock variables", + required = true) ClockStrategy clockStrategy; - @Parameter(names = {"--search", "-s"}, description = "Search strategy", required = true) + @Parameter( + names = {"--search", "-s"}, + description = "Search strategy", + required = true) SearchStrategy searchStrategy; - @Parameter(names = {"--benchmark", "-b"}, description = "Benchmark mode (only print metrics)") + @Parameter( + names = {"--benchmark", "-b"}, + description = "Benchmark mode (only print metrics)") Boolean benchmarkMode = false; - @Parameter(names = {"--visualize", - "-v"}, description = "Write proof or counterexample to file in dot format") + @Parameter( + names = {"--visualize", "-v"}, + description = "Write proof or counterexample to file in dot format") String dotfile = null; - @Parameter(names = {"--header", - "-h"}, description = "Print only a header (for benchmarks)", help = true) + @Parameter( + names = {"--header", "-h"}, + description = "Print only a header (for benchmarks)", + help = true) boolean headerOnly = false; @Parameter(names = "--stacktrace", description = "Print full stack trace in case of exception") @@ -112,10 +125,12 @@ private void run() { try { final XtaSystem system = loadModel(); - final SafetyChecker checker = LazyXtaCheckerFactory.create(system, - dataStrategy, - clockStrategy, searchStrategy); - final SafetyResult, ? extends Trace> result = check(checker); + final SafetyChecker checker = + LazyXtaCheckerFactory.create( + system, dataStrategy, clockStrategy, searchStrategy); + final SafetyResult< + ? extends ARG, ? extends Trace> + result = check(checker); printResult(result); if (dotfile != null) { writeVisualStatus(result, dotfile); @@ -126,13 +141,20 @@ private void run() { } } - private SafetyResult, ? extends Trace> check(SafetyChecker checker) throws Exception { + private SafetyResult, ? extends Trace> + check(SafetyChecker checker) throws Exception { try { - return (SafetyResult, ? extends Trace>) checker.check(UnitPrec.getInstance()); + return (SafetyResult< + ? extends ARG, + ? extends Trace>) + checker.check(UnitPrec.getInstance()); } catch (final Exception ex) { String message = ex.getMessage() == null ? "(no message)" : ex.getMessage(); throw new Exception( - "Error while running algorithm: " + ex.getClass().getSimpleName() + " " + message, + "Error while running algorithm: " + + ex.getClass().getSimpleName() + + " " + + message, ex); } } @@ -147,7 +169,8 @@ private XtaSystem loadModel() throws Exception { } } - private void printResult(final SafetyResult, ? extends Trace> result) { + private void printResult( + final SafetyResult, ? extends Trace> result) { final LazyXtaStatistics stats = (LazyXtaStatistics) result.getStats().get(); if (benchmarkMode) { stats.writeData(writer); @@ -173,12 +196,16 @@ private void printError(final Throwable ex) { } } - private void writeVisualStatus(final SafetyResult, ? extends Trace> status, final String filename) + private void writeVisualStatus( + final SafetyResult< + ? extends ARG, ? extends Trace> + status, + final String filename) throws FileNotFoundException { final Graph graph = - status.isSafe() ? ArgVisualizer.getDefault().visualize(status.asSafe().getWitness()) + status.isSafe() + ? ArgVisualizer.getDefault().visualize(status.asSafe().getProof()) : TraceVisualizer.getDefault().visualize(status.asUnsafe().getCex()); GraphvizWriter.getInstance().writeFile(graph, filename); } - } From 35dee48f3e9b7cbf2734609b10a30a6641541ea0 Mon Sep 17 00:00:00 2001 From: RipplB Date: Wed, 16 Oct 2024 22:31:29 +0200 Subject: [PATCH 40/40] Further generalize refiners Refiners and all their links don't need state and action generics specified anymore --- .../algorithm/cegar/ArgCegarChecker.java | 23 +- .../analysis/algorithm/cegar/ArgRefiner.java | 4 +- .../algorithm/cegar/CegarChecker.java | 72 +++-- .../analysis/algorithm/cegar/Refiner.java | 14 +- .../algorithm/cegar/RefinerResult.java | 51 ++-- .../expr/refinement/AasporRefiner.java | 51 ++-- .../refinement/MultiExprTraceRefiner.java | 71 +++-- .../refinement/SingleExprTraceRefiner.java | 60 ++-- .../analysis/XcfaSingeExprTraceRefiner.kt | 283 ++++++++++-------- 9 files changed, 353 insertions(+), 276 deletions(-) diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java index 06260c732c..8ac9d3a5a7 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgCegarChecker.java @@ -25,24 +25,25 @@ import hu.bme.mit.theta.common.logging.NullLogger; /** - * Counterexample-Guided Abstraction Refinement (CEGAR) loop implementation, - * that uses an Abstractor to explore the abstract state space and a Refiner to - * check counterexamples and refine them if needed. It also provides certain - * statistics about its execution. + * Counterexample-Guided Abstraction Refinement (CEGAR) loop implementation, that uses an Abstractor + * to explore the abstract state space and a Refiner to check counterexamples and refine them if + * needed. It also provides certain statistics about its execution. */ public final class ArgCegarChecker { - private ArgCegarChecker() { - } + private ArgCegarChecker() {} - public static CegarChecker, Trace> create( - final ArgAbstractor abstractor, final ArgRefiner refiner) { + public static + CegarChecker, Trace> create( + final ArgAbstractor abstractor, final ArgRefiner refiner) { return create(abstractor, refiner, NullLogger.getInstance()); } - public static CegarChecker, Trace> create( - final ArgAbstractor abstractor, final ArgRefiner refiner, final Logger logger) { + public static + CegarChecker, Trace> create( + final ArgAbstractor abstractor, + final ArgRefiner refiner, + final Logger logger) { return CegarChecker.create(abstractor, refiner, logger, ArgVisualizer.getDefault()); } - } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java index 2683a2fd0f..afb07b11c7 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/ArgRefiner.java @@ -25,5 +25,5 @@ * Common interface for refiners. It takes an ARG and a precision, checks if the counterexample in * the ARG is feasible and if not, it refines the precision and may also prune the ARG. */ -public interface ArgRefiner extends Refiner, Trace> { -} +public interface ArgRefiner + extends Refiner, Trace> {} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java index 30da9a28e5..dac497e043 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/CegarChecker.java @@ -15,11 +15,11 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; +import static com.google.common.base.Preconditions.checkNotNull; + import com.google.common.base.Stopwatch; -import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; -import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.analysis.algorithm.Proof; import hu.bme.mit.theta.analysis.algorithm.SafetyChecker; import hu.bme.mit.theta.analysis.algorithm.SafetyResult; @@ -31,26 +31,27 @@ import hu.bme.mit.theta.common.logging.NullLogger; import hu.bme.mit.theta.common.visualization.writer.JSONWriter; import hu.bme.mit.theta.common.visualization.writer.WebDebuggerLogger; - import java.util.concurrent.TimeUnit; -import static com.google.common.base.Preconditions.checkNotNull; - /** - * Counterexample-Guided Abstraction Refinement (CEGAR) loop implementation, - * that uses an Abstractor to explore the abstract state space and a Refiner to - * check counterexamples and refine them if needed. It also provides certain - * statistics about its execution. + * Counterexample-Guided Abstraction Refinement (CEGAR) loop implementation, that uses an Abstractor + * to explore the abstract state space and a Refiner to check counterexamples and refine them if + * needed. It also provides certain statistics about its execution. */ -public final class CegarChecker implements SafetyChecker { +public final class CegarChecker

+ implements SafetyChecker { private final Abstractor abstractor; - private final Refiner refiner; + private final Refiner refiner; private final Logger logger; private final Pr proof; private final ProofVisualizer proofVisualizer; - private CegarChecker(final Abstractor abstractor, final Refiner refiner, final Logger logger, final ProofVisualizer proofVisualizer) { + private CegarChecker( + final Abstractor abstractor, + final Refiner refiner, + final Logger logger, + final ProofVisualizer proofVisualizer) { this.abstractor = checkNotNull(abstractor); this.refiner = checkNotNull(refiner); this.logger = checkNotNull(logger); @@ -58,13 +59,18 @@ private CegarChecker(final Abstractor abstractor, final Refiner CegarChecker create( - final Abstractor abstractor, final Refiner refiner, final ProofVisualizer proofVisualizer) { + public static

CegarChecker create( + final Abstractor abstractor, + final Refiner refiner, + final ProofVisualizer proofVisualizer) { return create(abstractor, refiner, NullLogger.getInstance(), proofVisualizer); } - public static CegarChecker create( - final Abstractor abstractor, final Refiner refiner, final Logger logger, final ProofVisualizer proofVisualizer) { + public static

CegarChecker create( + final Abstractor abstractor, + final Refiner refiner, + final Logger logger, + final ProofVisualizer proofVisualizer) { return new CegarChecker<>(abstractor, refiner, logger, proofVisualizer); } @@ -78,7 +84,7 @@ public SafetyResult check(final P initPrec) { final Stopwatch stopwatch = Stopwatch.createStarted(); long abstractorTime = 0; long refinerTime = 0; - RefinerResult refinerResult = null; + RefinerResult refinerResult = null; AbstractorResult abstractorResult; P prec = initPrec; int iteration = 0; @@ -91,10 +97,12 @@ public SafetyResult check(final P initPrec) { final long abstractorStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); abstractorResult = abstractor.check(proof, prec); abstractorTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - abstractorStartTime; - logger.write(Level.MAINSTEP, "| Checking abstraction done, result: %s%n", abstractorResult); + logger.write( + Level.MAINSTEP, "| Checking abstraction done, result: %s%n", abstractorResult); if (WebDebuggerLogger.enabled()) { - String argGraph = JSONWriter.getInstance().writeString(proofVisualizer.visualize(proof)); + String argGraph = + JSONWriter.getInstance().writeString(proofVisualizer.visualize(proof)); String precString = prec.toString(); wdl.addIteration(iteration, argGraph, precString); } @@ -107,26 +115,35 @@ public SafetyResult check(final P initPrec) { final long refinerStartTime = stopwatch.elapsed(TimeUnit.MILLISECONDS); refinerResult = refiner.refine(proof, prec); refinerTime += stopwatch.elapsed(TimeUnit.MILLISECONDS) - refinerStartTime; - logger.write(Level.MAINSTEP, "Refining abstraction done, result: %s%n", refinerResult); + logger.write( + Level.MAINSTEP, "Refining abstraction done, result: %s%n", refinerResult); if (refinerResult.isSpurious()) { prec = refinerResult.asSpurious().getRefinedPrec(); } if (lastPrec.equals(prec)) { - logger.write(Level.MAINSTEP, "! Precision did NOT change in this iteration" + System.lineSeparator()); + logger.write( + Level.MAINSTEP, + "! Precision did NOT change in this iteration" + + System.lineSeparator()); } else { - logger.write(Level.MAINSTEP, "! Precision DID change in this iteration" + System.lineSeparator()); + logger.write( + Level.MAINSTEP, + "! Precision DID change in this iteration" + System.lineSeparator()); } - } } while (!abstractorResult.isSafe() && !refinerResult.isUnsafe()); stopwatch.stop(); SafetyResult cegarResult = null; - final CegarStatistics stats = new CegarStatistics(stopwatch.elapsed(TimeUnit.MILLISECONDS), abstractorTime, - refinerTime, iteration); + final CegarStatistics stats = + new CegarStatistics( + stopwatch.elapsed(TimeUnit.MILLISECONDS), + abstractorTime, + refinerTime, + iteration); assert abstractorResult.isSafe() || refinerResult.isUnsafe(); @@ -144,6 +161,9 @@ public SafetyResult check(final P initPrec) { @Override public String toString() { - return Utils.lispStringBuilder(getClass().getSimpleName()).add(abstractor).add(refiner).toString(); + return Utils.lispStringBuilder(getClass().getSimpleName()) + .add(abstractor) + .add(refiner) + .toString(); } } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java index abd645f3cf..819bd3c403 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/Refiner.java @@ -15,20 +15,16 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; -import hu.bme.mit.theta.analysis.Action; import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; -import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.analysis.algorithm.Proof; /** - * Common interface for refiners. It takes a witness and a precision, checks if the counterexample in - * the witness is feasible and if not, it refines the precision + * Common interface for refiners. It takes a witness and a precision, checks if the counterexample + * in the witness is feasible and if not, it refines the precision */ -public interface Refiner { +public interface Refiner

{ - /** - * Checks if the counterexample in the witness is feasible. If not, refines the precision - */ - RefinerResult refine(Pr witness, P prec); + /** Checks if the counterexample in the witness is feasible. If not, refines the precision */ + RefinerResult refine(Pr witness, P prec); } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java index a4be30781e..63011b7d08 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/algorithm/cegar/RefinerResult.java @@ -15,30 +15,26 @@ */ package hu.bme.mit.theta.analysis.algorithm.cegar; -import hu.bme.mit.theta.analysis.Action; +import static com.google.common.base.Preconditions.checkNotNull; + import hu.bme.mit.theta.analysis.Cex; import hu.bme.mit.theta.analysis.Prec; -import hu.bme.mit.theta.analysis.State; import hu.bme.mit.theta.common.Utils; -import static com.google.common.base.Preconditions.checkNotNull; - /** * Represents the result of the Refiner class that can be either spurious or unsafe. In the former * case it also contains the refined precision and in the latter case the feasible counterexample. */ -public abstract class RefinerResult { +public abstract class RefinerResult

{ - protected RefinerResult() { - } + protected RefinerResult() {} /** * Create a new spurious result. * * @param refinedPrec Refined precision */ - public static Spurious spurious( - final P refinedPrec) { + public static

Spurious spurious(final P refinedPrec) { return new Spurious<>(refinedPrec); } @@ -47,8 +43,7 @@ public static * * @param cex Feasible counterexample */ - public static Unsafe unsafe( - final C cex) { + public static

Unsafe unsafe(final C cex) { return new Unsafe<>(cex); } @@ -56,15 +51,12 @@ public static public abstract boolean isUnsafe(); - public abstract Spurious asSpurious(); + public abstract Spurious asSpurious(); - public abstract Unsafe asUnsafe(); + public abstract Unsafe asUnsafe(); - /** - * Represents the spurious result with a refined precision. - */ - public static final class Spurious - extends RefinerResult { + /** Represents the spurious result with a refined precision. */ + public static final class Spurious

extends RefinerResult { private final P refinedPrec; @@ -87,14 +79,16 @@ public boolean isUnsafe() { } @Override - public Spurious asSpurious() { + public Spurious asSpurious() { return this; } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { throw new ClassCastException( - "Cannot cast " + Spurious.class.getSimpleName() + " to " + "Cannot cast " + + Spurious.class.getSimpleName() + + " to " + Unsafe.class.getSimpleName()); } @@ -106,11 +100,8 @@ public String toString() { } } - /** - * Represents the unsafe result with a feasible counterexample. - */ - public static final class Unsafe extends - RefinerResult { + /** Represents the unsafe result with a feasible counterexample. */ + public static final class Unsafe

extends RefinerResult { private final C cex; @@ -133,14 +124,16 @@ public boolean isUnsafe() { } @Override - public Spurious asSpurious() { + public Spurious asSpurious() { throw new ClassCastException( - "Cannot cast " + Unsafe.class.getSimpleName() + " to " + "Cannot cast " + + Unsafe.class.getSimpleName() + + " to " + Spurious.class.getSimpleName()); } @Override - public Unsafe asUnsafe() { + public Unsafe asUnsafe() { return this; } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java index f1f7430241..69b184e8b6 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/AasporRefiner.java @@ -24,13 +24,13 @@ import hu.bme.mit.theta.analysis.expr.ExprAction; import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.core.decl.VarDecl; - import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -public final class AasporRefiner implements ArgRefiner { +public final class AasporRefiner + implements ArgRefiner { private final ArgRefiner refiner; @@ -38,38 +38,51 @@ public final class AasporRefiner, Set> ignoredVarRegistry; - private AasporRefiner(final ArgRefiner refiner, - final PruneStrategy pruneStrategy, - final Map, Set> ignoredVarRegistry) { + private AasporRefiner( + final ArgRefiner refiner, + final PruneStrategy pruneStrategy, + final Map, Set> ignoredVarRegistry) { this.refiner = refiner; this.pruneStrategy = pruneStrategy; this.ignoredVarRegistry = ignoredVarRegistry; } - public static AasporRefiner create( - final ArgRefiner refiner, final PruneStrategy pruneStrategy, - final Map, Set> ignoredVarRegistry) { + public static + AasporRefiner create( + final ArgRefiner refiner, + final PruneStrategy pruneStrategy, + final Map, Set> ignoredVarRegistry) { return new AasporRefiner<>(refiner, pruneStrategy, ignoredVarRegistry); } @Override - public RefinerResult> refine(final ARG arg, final P prec) { - final RefinerResult> result = refiner.refine(arg, prec); + public RefinerResult> refine(final ARG arg, final P prec) { + final RefinerResult> result = refiner.refine(arg, prec); if (result.isUnsafe() || pruneStrategy != PruneStrategy.LAZY) return result; final P newPrec = result.asSpurious().getRefinedPrec(); final Set> newlyAddedVars = new HashSet<>(newPrec.getUsedVars()); newlyAddedVars.removeAll(prec.getUsedVars()); - newlyAddedVars.forEach(newVar -> { - if (ignoredVarRegistry.containsKey(newVar)) { - Set> nodesToReExpand = ignoredVarRegistry.get(newVar).stream().flatMap(stateToPrune -> - arg.getNodes().filter(node -> node.getState().equals(stateToPrune)) // TODO one state can be in one ARG node? - ).collect(Collectors.toSet()); - nodesToReExpand.forEach(arg::markForReExpansion); - ignoredVarRegistry.remove(newVar); - } - }); + newlyAddedVars.forEach( + newVar -> { + if (ignoredVarRegistry.containsKey(newVar)) { + Set> nodesToReExpand = + ignoredVarRegistry.get(newVar).stream() + .flatMap( + stateToPrune -> + arg.getNodes() + .filter( + node -> + node.getState() + .equals( + stateToPrune)) // TODO one state can be in one ARG node? + ) + .collect(Collectors.toSet()); + nodesToReExpand.forEach(arg::markForReExpansion); + ignoredVarRegistry.remove(newVar); + } + }); return result; } diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java index b2cee796d0..71b8799468 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/MultiExprTraceRefiner.java @@ -15,6 +15,8 @@ */ package hu.bme.mit.theta.analysis.expr.refinement; +import static com.google.common.base.Preconditions.checkNotNull; + import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; @@ -26,14 +28,11 @@ import hu.bme.mit.theta.analysis.expr.ExprState; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; - import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; -import static com.google.common.base.Preconditions.checkNotNull; - -public final class MultiExprTraceRefiner +public final class MultiExprTraceRefiner< + S extends ExprState, A extends ExprAction, P extends Prec, R extends Refutation> implements ArgRefiner { private final ExprTraceChecker exprTraceChecker; @@ -42,9 +41,11 @@ public final class MultiExprTraceRefiner nodePruner; private final Logger logger; - private MultiExprTraceRefiner(final ExprTraceChecker exprTraceChecker, - final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger) { + private MultiExprTraceRefiner( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger) { this.exprTraceChecker = checkNotNull(exprTraceChecker); this.precRefiner = checkNotNull(precRefiner); this.pruneStrategy = checkNotNull(pruneStrategy); @@ -52,10 +53,12 @@ private MultiExprTraceRefiner(final ExprTraceChecker exprTraceChecker, this.logger = checkNotNull(logger); } - private MultiExprTraceRefiner(final ExprTraceChecker exprTraceChecker, - final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger, - final NodePruner nodePruner) { + private MultiExprTraceRefiner( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger, + final NodePruner nodePruner) { this.exprTraceChecker = checkNotNull(exprTraceChecker); this.precRefiner = checkNotNull(precRefiner); this.pruneStrategy = checkNotNull(pruneStrategy); @@ -63,20 +66,28 @@ private MultiExprTraceRefiner(final ExprTraceChecker exprTraceChecker, this.logger = checkNotNull(logger); } - public static MultiExprTraceRefiner create( - final ExprTraceChecker exprTraceChecker, final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger) { + public static + MultiExprTraceRefiner create( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger) { return new MultiExprTraceRefiner<>(exprTraceChecker, precRefiner, pruneStrategy, logger); } - public static MultiExprTraceRefiner create( - final ExprTraceChecker exprTraceChecker, final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger, final NodePruner nodePruner) { - return new MultiExprTraceRefiner<>(exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner); + public static + MultiExprTraceRefiner create( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger, + final NodePruner nodePruner) { + return new MultiExprTraceRefiner<>( + exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner); } @Override - public RefinerResult> refine(final ARG arg, final P prec) { + public RefinerResult> refine(final ARG arg, final P prec) { checkNotNull(arg); checkNotNull(prec); assert !arg.isSafe() : "ARG must be unsafe"; @@ -100,13 +111,18 @@ public RefinerResult> refine(final ARG arg, final P p if (cexStatuses.stream().anyMatch(ExprTraceStatus::isFeasible)) { logger.write(Level.SUBSTEP, "done, result: found feasible%n"); - return RefinerResult.unsafe(traces.get( - cexStatuses.indexOf(cexStatuses.stream().filter(ExprTraceStatus::isFeasible).findFirst().get()))); + return RefinerResult.unsafe( + traces.get( + cexStatuses.indexOf( + cexStatuses.stream() + .filter(ExprTraceStatus::isFeasible) + .findFirst() + .get()))); } else { assert cexStatuses.size() == cexs.size(); logger.write(Level.SUBSTEP, "done, result: all infeasible%n"); - final List refutations = cexStatuses.stream().map(s -> s.asInfeasible().getRefutation()) - .toList(); + final List refutations = + cexStatuses.stream().map(s -> s.asInfeasible().getRefutation()).toList(); assert refutations.size() == cexs.size(); final List> nodesToPrune = new ArrayList<>(traces.size()); @@ -130,7 +146,8 @@ public RefinerResult> refine(final ARG arg, final P p P refinedPrec = prec; for (int i = 0; i < refutations.size(); ++i) { if (!skip.get(i)) { - refinedPrec = precRefiner.refine(refinedPrec, traces.get(i), refutations.get(i)); + refinedPrec = + precRefiner.refine(refinedPrec, traces.get(i), refutations.get(i)); } } @@ -153,7 +170,5 @@ public RefinerResult> refine(final ARG arg, final P p logger.write(Level.SUBSTEP, "done%n"); return RefinerResult.spurious(refinedPrec); } - } - -} \ No newline at end of file +} diff --git a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java index 126f4212f4..04befdbfcb 100644 --- a/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java +++ b/subprojects/common/analysis/src/main/java/hu/bme/mit/theta/analysis/expr/refinement/SingleExprTraceRefiner.java @@ -15,6 +15,8 @@ */ package hu.bme.mit.theta.analysis.expr.refinement; +import static com.google.common.base.Preconditions.checkNotNull; + import hu.bme.mit.theta.analysis.Prec; import hu.bme.mit.theta.analysis.Trace; import hu.bme.mit.theta.analysis.algorithm.arg.ARG; @@ -27,16 +29,14 @@ import hu.bme.mit.theta.common.Utils; import hu.bme.mit.theta.common.logging.Logger; import hu.bme.mit.theta.common.logging.Logger.Level; - import java.util.Optional; -import static com.google.common.base.Preconditions.checkNotNull; - /** - * A Refiner implementation that can refine a single trace (of ExprStates and - * ExprActions) using an ExprTraceChecker and a PrecRefiner. + * A Refiner implementation that can refine a single trace (of ExprStates and ExprActions) using an + * ExprTraceChecker and a PrecRefiner. */ -public class SingleExprTraceRefiner +public class SingleExprTraceRefiner< + S extends ExprState, A extends ExprAction, P extends Prec, R extends Refutation> implements ArgRefiner { protected final ExprTraceChecker exprTraceChecker; protected final PrecRefiner precRefiner; @@ -44,9 +44,11 @@ public class SingleExprTraceRefiner nodePruner; protected final Logger logger; - protected SingleExprTraceRefiner(final ExprTraceChecker exprTraceChecker, - final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger) { + protected SingleExprTraceRefiner( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger) { this.exprTraceChecker = checkNotNull(exprTraceChecker); this.precRefiner = checkNotNull(precRefiner); this.pruneStrategy = checkNotNull(pruneStrategy); @@ -54,10 +56,12 @@ protected SingleExprTraceRefiner(final ExprTraceChecker exprTraceChecker, this.logger = checkNotNull(logger); } - protected SingleExprTraceRefiner(final ExprTraceChecker exprTraceChecker, - final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger, - final NodePruner nodePruner) { + protected SingleExprTraceRefiner( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger, + final NodePruner nodePruner) { this.exprTraceChecker = checkNotNull(exprTraceChecker); this.precRefiner = checkNotNull(precRefiner); this.pruneStrategy = checkNotNull(pruneStrategy); @@ -65,20 +69,28 @@ protected SingleExprTraceRefiner(final ExprTraceChecker exprTraceChecker, this.logger = checkNotNull(logger); } - public static SingleExprTraceRefiner create( - final ExprTraceChecker exprTraceChecker, final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger) { + public static + SingleExprTraceRefiner create( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger) { return new SingleExprTraceRefiner<>(exprTraceChecker, precRefiner, pruneStrategy, logger); } - public static SingleExprTraceRefiner create( - final ExprTraceChecker exprTraceChecker, final PrecRefiner precRefiner, - final PruneStrategy pruneStrategy, final Logger logger, final NodePruner nodePruner) { - return new SingleExprTraceRefiner<>(exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner); + public static + SingleExprTraceRefiner create( + final ExprTraceChecker exprTraceChecker, + final PrecRefiner precRefiner, + final PruneStrategy pruneStrategy, + final Logger logger, + final NodePruner nodePruner) { + return new SingleExprTraceRefiner<>( + exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner); } @Override - public RefinerResult> refine(final ARG arg, final P prec) { + public RefinerResult> refine(final ARG arg, final P prec) { checkNotNull(arg); checkNotNull(prec); assert !arg.isSafe() : "ARG must be unsafe"; @@ -127,7 +139,9 @@ public RefinerResult> refine(final ARG arg, final P p @Override public String toString() { - return Utils.lispStringBuilder(getClass().getSimpleName()).add(exprTraceChecker).add(precRefiner).toString(); + return Utils.lispStringBuilder(getClass().getSimpleName()) + .add(exprTraceChecker) + .add(precRefiner) + .toString(); } - } diff --git a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt index 93410e0641..4ca545dd9b 100644 --- a/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt +++ b/subprojects/xcfa/xcfa-analysis/src/main/java/hu/bme/mit/theta/xcfa/analysis/XcfaSingeExprTraceRefiner.kt @@ -29,143 +29,168 @@ import hu.bme.mit.theta.analysis.ptr.patch import hu.bme.mit.theta.common.logging.Logger import java.util.* - class XcfaSingleExprTraceRefiner : - SingleExprTraceRefiner { - - private constructor( - exprTraceChecker: ExprTraceChecker, - precRefiner: PrecRefiner, - pruneStrategy: PruneStrategy, - logger: Logger - ) : super(exprTraceChecker, precRefiner, pruneStrategy, logger) - - private constructor( - exprTraceChecker: ExprTraceChecker, - precRefiner: PrecRefiner, - pruneStrategy: PruneStrategy, - logger: Logger, - nodePruner: NodePruner - ) : super(exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner) - - private fun findPoppedState(trace: Trace): Pair>? { - trace.states.forEachIndexed { i, s -> - val state = s as XcfaState - state.processes.entries.find { (_, processState) -> processState.popped != null } - ?.let { (pid, processState) -> - val stackBeforePop = LinkedList(processState.locs) - stackBeforePop.push(processState.popped) - val processesBeforePop = state.processes.toMutableMap() - processesBeforePop[pid] = processState.copy(locs = stackBeforePop) - val stateBeforePop = state.copy(processes = processesBeforePop) - return Pair(i, stateBeforePop) - } + SingleExprTraceRefiner { + + private constructor( + exprTraceChecker: ExprTraceChecker, + precRefiner: PrecRefiner, + pruneStrategy: PruneStrategy, + logger: Logger, + ) : super(exprTraceChecker, precRefiner, pruneStrategy, logger) + + private constructor( + exprTraceChecker: ExprTraceChecker, + precRefiner: PrecRefiner, + pruneStrategy: PruneStrategy, + logger: Logger, + nodePruner: NodePruner, + ) : super(exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner) + + private fun findPoppedState(trace: Trace): Pair>? { + trace.states.forEachIndexed { i, s -> + val state = s as XcfaState + state.processes.entries + .find { (_, processState) -> processState.popped != null } + ?.let { (pid, processState) -> + val stackBeforePop = LinkedList(processState.locs) + stackBeforePop.push(processState.popped) + val processesBeforePop = state.processes.toMutableMap() + processesBeforePop[pid] = processState.copy(locs = stackBeforePop) + val stateBeforePop = state.copy(processes = processesBeforePop) + return Pair(i, stateBeforePop) } - return null } - - fun refineTemp(arg: ARG, prec: P?): RefinerResult> { - Preconditions.checkNotNull(arg) - Preconditions.checkNotNull(prec) - assert(!arg.isSafe) { "ARG must be unsafe" } - val optionalNewCex = arg.cexs.findFirst() - val cexToConcretize = optionalNewCex.get() - val rawTrace = cexToConcretize.toTrace() - val (_, states, actions) = rawTrace.actions.foldIndexed( - Triple(Pair(emptyMap(), 0), listOf(rawTrace.getState(0)), - listOf())) { i: Int, (wTripleCnt: Pair, states: List, actions: List): Triple, List, List>, a: A -> - val (wTriple, cnt) = wTripleCnt - val newA = (a as XcfaAction).withLastWrites(wTriple, cnt) - val newState = (rawTrace.getState(i + 1) as XcfaState>).let { - it.withState(PtrState(it.sGlobal.innerState.patch(newA.nextWriteTriples()))) - } - Triple(Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), states + (newState as S), - actions + (newA as A)) + return null + } + + fun refineTemp(arg: ARG, prec: P?): RefinerResult> { + Preconditions.checkNotNull(arg) + Preconditions.checkNotNull(prec) + assert(!arg.isSafe) { "ARG must be unsafe" } + val optionalNewCex = arg.cexs.findFirst() + val cexToConcretize = optionalNewCex.get() + val rawTrace = cexToConcretize.toTrace() + val (_, states, actions) = + rawTrace.actions.foldIndexed( + Triple(Pair(emptyMap(), 0), listOf(rawTrace.getState(0)), listOf()) + ) { + i: Int, + (wTripleCnt: Pair, states: List, actions: List): Triple< + Pair, + List, + List, + >, + a: A -> + val (wTriple, cnt) = wTripleCnt + val newA = (a as XcfaAction).withLastWrites(wTriple, cnt) + val newState = + (rawTrace.getState(i + 1) as XcfaState>).let { + it.withState(PtrState(it.sGlobal.innerState.patch(newA.nextWriteTriples()))) + } + Triple( + Pair(newA.nextWriteTriples(), newA.cnts.values.maxOrNull() ?: newA.inCnt), + states + (newState as S), + actions + (newA as A), + ) + } + val traceToConcretize = Trace.of(states, actions) + + logger.write(Logger.Level.INFO, "| | Trace length: %d%n", traceToConcretize.length()) + logger.write(Logger.Level.DETAIL, "| | Trace: %s%n", traceToConcretize) + logger.write(Logger.Level.SUBSTEP, "| | Checking trace...") + val cexStatus = exprTraceChecker.check(traceToConcretize) + logger.write(Logger.Level.SUBSTEP, "done, result: %s%n", cexStatus) + assert(cexStatus.isFeasible() || cexStatus.isInfeasible()) { "Unknown CEX status" } + return if (cexStatus.isFeasible()) { + RefinerResult.unsafe(traceToConcretize) + } else { + val refutation = cexStatus.asInfeasible().refutation + logger.write(Logger.Level.DETAIL, "| | | Refutation: %s%n", refutation) + val refinedPrec = precRefiner.refine(prec, traceToConcretize, refutation) + val pruneIndex = refutation.getPruneIndex() + assert(0 <= pruneIndex) { "Pruning index must be non-negative" } + assert(pruneIndex <= cexToConcretize.length()) { "Pruning index larger than cex length" } + when (pruneStrategy) { + PruneStrategy.LAZY -> { + logger.write(Logger.Level.SUBSTEP, "| | Pruning from index %d...", pruneIndex) + val nodeToPrune = cexToConcretize.node(pruneIndex) + nodePruner.prune(arg, nodeToPrune) } - val traceToConcretize = Trace.of(states, actions) - - logger.write(Logger.Level.INFO, "| | Trace length: %d%n", traceToConcretize.length()) - logger.write(Logger.Level.DETAIL, "| | Trace: %s%n", traceToConcretize) - logger.write(Logger.Level.SUBSTEP, "| | Checking trace...") - val cexStatus = exprTraceChecker.check(traceToConcretize) - logger.write(Logger.Level.SUBSTEP, "done, result: %s%n", cexStatus) - assert(cexStatus.isFeasible() || cexStatus.isInfeasible()) { "Unknown CEX status" } - return if (cexStatus.isFeasible()) { - RefinerResult.unsafe(traceToConcretize) - } else { - val refutation = cexStatus.asInfeasible().refutation - logger.write(Logger.Level.DETAIL, "| | | Refutation: %s%n", refutation) - val refinedPrec = precRefiner.refine(prec, traceToConcretize, refutation) - val pruneIndex = refutation.getPruneIndex() - assert(0 <= pruneIndex) { "Pruning index must be non-negative" } - assert(pruneIndex <= cexToConcretize.length()) { "Pruning index larger than cex length" } - when (pruneStrategy) { - PruneStrategy.LAZY -> { - logger.write(Logger.Level.SUBSTEP, "| | Pruning from index %d...", pruneIndex) - val nodeToPrune = cexToConcretize.node(pruneIndex) - nodePruner.prune(arg, nodeToPrune) - } - - PruneStrategy.FULL -> { - logger.write(Logger.Level.SUBSTEP, "| | Pruning whole ARG", pruneIndex) - arg.pruneAll() - } - - else -> throw java.lang.UnsupportedOperationException("Unsupported pruning strategy") - } - logger.write(Logger.Level.SUBSTEP, "done%n") - RefinerResult.spurious(refinedPrec) + + PruneStrategy.FULL -> { + logger.write(Logger.Level.SUBSTEP, "| | Pruning whole ARG", pruneIndex) + arg.pruneAll() } - } - override fun refine(arg: ARG, prec: P?): RefinerResult> { - Preconditions.checkNotNull(arg) - Preconditions.checkNotNull

(prec) - assert(!arg.isSafe) { "ARG must be unsafe" } - - val optionalNewCex = arg.cexs.findFirst() - val cexToConcretize = optionalNewCex.get() - val traceToConcretize = cexToConcretize.toTrace() - - val refinerResult = refineTemp(arg, prec) //super.refine(arg, prec) - val checkForPop = !(traceToConcretize.states.first() as XcfaState<*>).xcfa!!.isInlined - - return if (checkForPop && refinerResult.isUnsafe) findPoppedState(traceToConcretize)?.let { (i, state) -> - when (pruneStrategy) { - PruneStrategy.LAZY -> { - logger.write(Logger.Level.SUBSTEP, "| | Pruning from index %d...", i) - val nodeToPrune = cexToConcretize.node(i) - nodePruner.prune(arg, nodeToPrune) - } - - PruneStrategy.FULL -> { - logger.write(Logger.Level.SUBSTEP, "| | Pruning whole ARG", i) - arg.pruneAll() - } - - else -> throw UnsupportedOperationException("Unsupported pruning strategy") - } - - val refinedPrec = (prec as XcfaPrec

).copy() - refinedPrec.noPop.add(state) - RefinerResult.spurious(refinedPrec as P?) - } ?: refinerResult else refinerResult + else -> throw java.lang.UnsupportedOperationException("Unsupported pruning strategy") + } + logger.write(Logger.Level.SUBSTEP, "done%n") + RefinerResult.spurious(refinedPrec) } - - companion object { - - fun create( - exprTraceChecker: ExprTraceChecker, precRefiner: PrecRefiner, - pruneStrategy: PruneStrategy, logger: Logger - ): XcfaSingleExprTraceRefiner { - return XcfaSingleExprTraceRefiner(exprTraceChecker, precRefiner, pruneStrategy, logger) + } + + override fun refine(arg: ARG, prec: P?): RefinerResult> { + Preconditions.checkNotNull(arg) + Preconditions.checkNotNull

(prec) + assert(!arg.isSafe) { "ARG must be unsafe" } + + val optionalNewCex = arg.cexs.findFirst() + val cexToConcretize = optionalNewCex.get() + val traceToConcretize = cexToConcretize.toTrace() + + val refinerResult = refineTemp(arg, prec) // super.refine(arg, prec) + val checkForPop = !(traceToConcretize.states.first() as XcfaState<*>).xcfa!!.isInlined + + return if (checkForPop && refinerResult.isUnsafe) + findPoppedState(traceToConcretize)?.let { (i, state) -> + when (pruneStrategy) { + PruneStrategy.LAZY -> { + logger.write(Logger.Level.SUBSTEP, "| | Pruning from index %d...", i) + val nodeToPrune = cexToConcretize.node(i) + nodePruner.prune(arg, nodeToPrune) + } + + PruneStrategy.FULL -> { + logger.write(Logger.Level.SUBSTEP, "| | Pruning whole ARG", i) + arg.pruneAll() + } + + else -> throw UnsupportedOperationException("Unsupported pruning strategy") } - fun create( - exprTraceChecker: ExprTraceChecker, precRefiner: PrecRefiner, - pruneStrategy: PruneStrategy, logger: Logger, nodePruner: NodePruner - ): XcfaSingleExprTraceRefiner { - return XcfaSingleExprTraceRefiner(exprTraceChecker, precRefiner, pruneStrategy, logger, nodePruner) - } + val refinedPrec = (prec as XcfaPrec

).copy() + refinedPrec.noPop.add(state) + RefinerResult.spurious(refinedPrec as P?) + } ?: refinerResult + else refinerResult + } + + companion object { + + fun create( + exprTraceChecker: ExprTraceChecker, + precRefiner: PrecRefiner, + pruneStrategy: PruneStrategy, + logger: Logger, + ): XcfaSingleExprTraceRefiner { + return XcfaSingleExprTraceRefiner(exprTraceChecker, precRefiner, pruneStrategy, logger) + } + + fun create( + exprTraceChecker: ExprTraceChecker, + precRefiner: PrecRefiner, + pruneStrategy: PruneStrategy, + logger: Logger, + nodePruner: NodePruner, + ): XcfaSingleExprTraceRefiner { + return XcfaSingleExprTraceRefiner( + exprTraceChecker, + precRefiner, + pruneStrategy, + logger, + nodePruner, + ) } + } }