Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add support for Strings and Rationals to the Princess backend #391

Merged
merged 117 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from 110 commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
ccc281a
Start working on string theory for Princess
serras Dec 6, 2021
1f7be15
Rationals in Princess
serras Dec 6, 2021
99337b7
formatting code.
kfriedberger Dec 15, 2021
625a0b6
Merge remote-tracking branch 'origin/master' into 'serras/master'
kfriedberger Dec 15, 2021
b7bbc3c
Princess: revert from Scala 2.13 to Scala 2.12.
kfriedberger Dec 15, 2021
53a1885
adding dependency for Ostrich into JavaSMT.
kfriedberger Dec 16, 2021
6f62e05
Use Ostrich for strings
serras Dec 16, 2021
d59e56c
Do not use 'floor' for rationals in Princess
serras Dec 16, 2021
adaa89c
add Ostrich library into IntelliJ config.
kfriedberger Jan 14, 2022
27faaa7
formatting and smaller cleanup
kfriedberger Jan 14, 2022
f8b0c3d
Princess: allow FLOOR for plain Integer theory.
kfriedberger Jan 14, 2022
5df33fe
Princess: improve MULT and DIV for Rationals.
kfriedberger Jan 14, 2022
9a7e920
Princess: improve support and model evaluation for Rationals.
kfriedberger Jan 14, 2022
451b0f3
Princess: fix for last commit.
kfriedberger Jan 14, 2022
3aaf54b
small update on internal documentation.
kfriedberger Jan 16, 2022
34b71ed
update copyright notice for IntelliJ.
kfriedberger Jan 16, 2022
0ad41d3
Princess/Ostrich: add Automaton library into IntelliJ module-/classpath.
kfriedberger Jan 16, 2022
e9707d1
Princess: improve support for string values in the model.
kfriedberger Jan 16, 2022
f7f9da5
adding improved model test for Real theory with formula evaluation.
kfriedberger Jan 16, 2022
53c0b4b
Merge remote-tracking branch 'origin/master' into HEAD
kfriedberger Nov 12, 2023
ebe926f
change Scala from 2.12 to 2.13
kfriedberger Nov 18, 2023
8b906ec
OpenSMT: exclude OpenSMT from some rational-based tests.
kfriedberger Nov 19, 2023
1936c40
improve precondition checks non formula-creation and make them more v…
kfriedberger Nov 19, 2023
dac5ac4
Princess: fix Checkstyle warnings and rename method for better docume…
kfriedberger Nov 19, 2023
2df018b
Princess: disable some tests for formula structure with rational/real…
kfriedberger Nov 19, 2023
449a87c
Princess: fix UF application on non-rational arguments like integers.
kfriedberger Nov 19, 2023
2eb9dbf
Princess: move utility method to one place.
kfriedberger Nov 19, 2023
4871bdc
Princess: exclude Princess from division-by-zero-tests.
kfriedberger Nov 19, 2023
4652de9
Princess: improve tests on nested arrays.
kfriedberger Nov 19, 2023
2dde64b
Princess: fix model-evaluation for integral rationals.
kfriedberger Nov 19, 2023
8c9f2b8
Princess: improve string-theory.
kfriedberger Nov 19, 2023
d680735
fix Compiler warning for ambiguous type usage.
kfriedberger Nov 19, 2023
a40f42a
Princess: improve visitation of constant rational and string-based te…
kfriedberger Nov 19, 2023
13c01a6
Princess: improve visitation of string operation STR_LE.
kfriedberger Nov 19, 2023
ec6ebaf
Merge branch 'master' into 257-more-theories-for-princess
daniel-raffler Sep 6, 2024
262bb96
Princess: Fetch Ostrich 1.3.5 from Maven. This is a temporary fix tha…
daniel-raffler Sep 6, 2024
b503024
Princess: Disable two tests in StringFormulaManagerTest that will tim…
daniel-raffler Sep 6, 2024
3175cf1
Princess: Add missing dependencies for parsing
daniel-raffler Sep 7, 2024
0210289
Princess: Fix StringFormulaManager.concat(..) when there are more tha…
daniel-raffler Sep 7, 2024
29d25c3
Princess: Disable String test that use (escaped) Unicode literals. Pr…
daniel-raffler Sep 7, 2024
85ebb3d
Princess: Use str.< to define PrincessStringFormulaManager.lessThan d…
daniel-raffler Sep 7, 2024
f99740d
Princess: Add a native test class for Princess to help with debugging
daniel-raffler Sep 7, 2024
8eee565
Princess: Fix two issues from earlier commits
daniel-raffler Sep 7, 2024
abc11e5
Princess: Replace "a str.<= b" with "a str.< b | a == b" to work arou…
daniel-raffler Sep 7, 2024
1610229
Princess: Added native tests for str.contains
daniel-raffler Sep 7, 2024
076d626
Princess: Added more native tests
daniel-raffler Sep 7, 2024
5df2ce6
Princess: Fix handling of unicode escape sequences
daniel-raffler Sep 7, 2024
9c6ca0e
Princess: Avoid using Scala Seq in PrincessStringFormulaManager to av…
daniel-raffler Sep 8, 2024
c546357
Princess: Rewrite a line of code to avoid CI complaints
daniel-raffler Sep 8, 2024
7767d2a
Princess: Add a missing dot
daniel-raffler Sep 8, 2024
51bec64
Princess: Add test cases from the bug reports written by @kfriedberge…
daniel-raffler Sep 8, 2024
fd9ae85
Princess: Moved a comment to the right test
daniel-raffler Sep 9, 2024
0ea532a
Princess: Add missing assertions for the tests
daniel-raffler Sep 10, 2024
9f4d16c
Princess: Add workarounds for the broken rational theory tests
daniel-raffler Sep 10, 2024
c89c6ac
Princess: Disable a test in ArrayFormulaManagerTest for Princess. The…
daniel-raffler Sep 10, 2024
a65769c
Princess: Clean up code in PrincessNativeAPITest
daniel-raffler Sep 10, 2024
47def53
Princess: Removed default arguments for OFlags in PrincessNativeAPITe…
daniel-raffler Sep 10, 2024
96c4d61
Princess: Disable a test in SolverTheoriesTest that uses rational num…
daniel-raffler Sep 10, 2024
296d8e4
Princess: Renamed list of (non-boolean) variables in PrincessAbstract…
daniel-raffler Sep 10, 2024
5b77984
Princess: Add a workaround to evaluate rational formulas with Princes…
daniel-raffler Sep 10, 2024
da11b8f
Princess: Remove unnecessary parenthesis
daniel-raffler Sep 11, 2024
0ea2941
Princess: Fix some bugs from 5b7798454aa0f7708be85770dc7030a18b2a237c
daniel-raffler Sep 11, 2024
6eb0f67
Princess: Fix two more bugs
daniel-raffler Sep 11, 2024
f5dffee
Princess: Remove an unnecessary cast
daniel-raffler Sep 11, 2024
30c1fe7
Princess: Fix format
daniel-raffler Sep 11, 2024
9569292
Princess: Disable all tests that require use operations with only non…
daniel-raffler Sep 11, 2024
f843131
Princess: Re-enable testStringPrefixSuffix from StringFormulaManagerT…
daniel-raffler Sep 11, 2024
76efd95
Princess: Re-enable native prefixSuffixTest in PrincessNativeAPITest.…
daniel-raffler Sep 11, 2024
f661c10
Princess: Fix makeNumberImpl for integer arguments
daniel-raffler Sep 11, 2024
2e570a2
Princess: Removed `Rational.int` and `Rational.frac` from the list of…
daniel-raffler Sep 11, 2024
d761b17
Princess: Add a case for (IFunApp "true" []) in convertValue
daniel-raffler Sep 11, 2024
2d7df5f
Princess: Fix handling of if-then-else expressions in getFormulaType
daniel-raffler Sep 11, 2024
3bc04a8
Princess: Disable term abbreviations as they seem to cause Princess t…
daniel-raffler Sep 12, 2024
2c06c70
Princess: Remove parameters 14 and 15 for the OFlags constructor. Tho…
daniel-raffler Sep 12, 2024
c83063e
Princess: Remove workaround for a bug in Ostrich. The str.<= operatio…
daniel-raffler Sep 12, 2024
a1764de
Princess: Added a note about rational values in the model
daniel-raffler Sep 12, 2024
3b7229a
Princess: Fix evalImpl() for formulas that are equations over rationa…
daniel-raffler Sep 12, 2024
4c78733
Merge remote-tracking branch 'origin/master' into 257-more-theories-f…
daniel-raffler Sep 12, 2024
2636f5e
Princess: Added a todo
daniel-raffler Sep 12, 2024
1e8176f
Princess: Remove the native API test
daniel-raffler Sep 12, 2024
3e1dad8
Princess: Cleaned up some function names
daniel-raffler Sep 13, 2024
bbf9b9c
Princess: Added a todo
daniel-raffler Sep 13, 2024
e950269
Princess: Added missing dots for checkstyle
daniel-raffler Sep 13, 2024
872944f
Princess: Fix visitors for rational values
daniel-raffler Sep 13, 2024
c161f00
Princess: Resolve checkstyle issues
daniel-raffler Sep 15, 2024
f3a277e
Revert "Princess: Fix evalImpl() for formulas that are equations over…
daniel-raffler Sep 15, 2024
c2b685b
Princess: Move comments to their own if-then-else branch
daniel-raffler Sep 16, 2024
6beb6f5
Princess: Fix PrincessRationalFormulaManager.makeNumberImpl() for int…
daniel-raffler Sep 16, 2024
9e1d69d
Princess: Renamed IntegerFormulaManager in PrincessRationalFormulaMan…
daniel-raffler Sep 16, 2024
ea21421
Princess: Work around a bug in princess where multiplying a rational …
daniel-raffler Sep 16, 2024
6351613
Princess: Enabled tests for arrays with rational indices/elements. Th…
daniel-raffler Sep 18, 2024
6fc4b9a
Princess: Add two comments about failed tests in FomulaClassifierTest…
daniel-raffler Sep 18, 2024
43c2c83
Princess: Added a comment to testDivisionByZero test. Princess does s…
daniel-raffler Sep 18, 2024
3b6102d
Princess: Fix evaluation of (boolean) formulas
daniel-raffler Sep 18, 2024
fa38940
Revert "Princess: Disable term abbreviations as they seem to cause Pr…
daniel-raffler Sep 21, 2024
e075090
Princess: Clean up dependencies and prepare for upgrading Princess/Os…
daniel-raffler Oct 16, 2024
ce2e7f9
Princess: Add a comment about the default values for OFlags
daniel-raffler Oct 16, 2024
52fd628
Princess: Throw and UnsupportedOperationExcpetion in PrincessRational…
daniel-raffler Oct 16, 2024
98e49f7
Princess: Remove a duplicate requireRationalFloor()
daniel-raffler Oct 16, 2024
bcb696d
Princess: Add unit tests for PrincessStringFormulaManager.unescapeString
daniel-raffler Oct 19, 2024
9320257
Princess: Fix handling of broken Unicode sequences "\\u{" with no clo…
daniel-raffler Oct 19, 2024
3648bf0
Princess: Throw an exception in PrincessStringFormulaManager.unescape…
daniel-raffler Oct 19, 2024
441e947
Princess: Fix spelling
daniel-raffler Oct 19, 2024
0e949d7
Princess: Skip internal variable "Rat_denom" when generating the model
daniel-raffler Oct 19, 2024
ba486a5
Princess: Removed an outdated note
daniel-raffler Oct 20, 2024
21abead
Princess: Stopped using the partial model for Model.evaluate()
daniel-raffler Oct 20, 2024
5cfbef7
Solved a concurrent modification issues in AbstractProver when models…
daniel-raffler Oct 20, 2024
7ea3b68
Princess: Update Princess to version 2024-11-08 and Ostrich to 1.4.1
daniel-raffler Nov 13, 2024
a2d2497
remove transitive dependency from Ostrich to JavaCup.
kfriedberger Nov 16, 2024
922dd53
Merge remote-tracking branch 'origin/master' into 257-more-theories-f…
kfriedberger Nov 16, 2024
fd8e810
ignore potential resource leak, as for models of other solvers.
kfriedberger Nov 16, 2024
ae05a8b
Princess: Restore ivysettings.xml to its original version
daniel-raffler Nov 16, 2024
1b4ff68
revert whitespace changes in branch.
kfriedberger Nov 17, 2024
669743f
simplify model tracking for Princess.
kfriedberger Nov 17, 2024
69517ec
fix import of Builder
kfriedberger Nov 17, 2024
e6bc8f1
improve documentation
kfriedberger Nov 17, 2024
0c70424
improve counter by making it non-static.
kfriedberger Nov 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ SPDX-License-Identifier: Apache-2.0
<classpathentry kind="lib" path="lib/java/runtime-princess/scala-library.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/princess-smt-parser_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/java-cup-runtime.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/automaton.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/org.sat4j.core.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/ostrich_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/ostrich-ecma2020-parser_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-z3/com.microsoft.z3.jar" sourcepath="lib/java-contrib/com.microsoft.z3-sources.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-cvc4/CVC4.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-cvc5/cvc5.jar"/>
Expand Down
18 changes: 18 additions & 0 deletions .idea/JavaSMT.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions build/ivysettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@ SPDX-License-Identifier: Apache-2.0
Keep this file synchronized with
https://gitlab.com/sosy-lab/software/java-project-template
-->
<settings defaultResolver="Sosy-Lab"/>
<settings defaultResolver="Repos"/>
<property name="repo.dir" value="${basedir}/repository"/>
<resolvers>
<!-- Resolver for downloading dependencies -->
<url name="Sosy-Lab" descriptor="required">
<ivy pattern="${ivy.repo.url}/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="${ivy.repo.url}/[organisation]/[module]/[artifact]-[revision](-[classifier]).[ext]" />
</url>
<chain name="Repos">
<url name="Sosy-Lab">
<ivy pattern="${ivy.repo.url}/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${ivy.repo.url}/[organisation]/[module]/[artifact]-[revision](-[classifier]).[ext]"/>
</url>
<url name="Maven-Repo" m2compatible="true">
<ivy pattern="https://repo1.maven.org/maven2/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="https://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
</url>
</chain>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this change or is this just for development?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it was for development only. Once everything is in our repository it can be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've restored the original version now.


<!-- Resolver for publishing this project -->
<filesystem name="Sosy-Lab-Publish">
Expand Down
19 changes: 13 additions & 6 deletions lib/ivy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ SPDX-License-Identifier: Apache-2.0
<dependency org="org.apache.ivy" name="ivy" rev="${ivy.target_version}" conf="build->default"/>

<!-- Google Auto-Value
Library for auto-generating value types. --><dependency org="com.google.auto.value" name="auto-value" rev="1.11.0" conf="build->default"/>
Library for auto-generating value types. -->
<dependency org="com.google.auto.value" name="auto-value" rev="1.11.0" conf="build->default"/>
<dependency org="com.google.auto.value" name="auto-value-annotations" rev="1.11.0" conf="build->default; contrib->sources"/>

<!-- Annotations we use for @Nullable etc. -->
Expand Down Expand Up @@ -149,13 +150,19 @@ SPDX-License-Identifier: Apache-2.0
<dependency org="de.uni-freiburg.informatik.ultimate" name="smtinterpol" rev="2.5-1242-g5c50fb6d" conf="runtime-smtinterpol->master; contrib->sources"/>

<!-- Princess for our Maven release -->
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-01-12" conf="runtime-princess-with-javacup->default; contrib->sources"/>
<!-- Princess for our Ivy release-->
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-01-12" conf="runtime-princess->default; contrib->sources">
<!-- Exclude dependency on java-cup and replace it with java-cup-runtime, which is enough.
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-11-08" conf="runtime-princess-with-javacup->default; contrib->sources"/>
<!-- Princess and Ostrich for our Ivy release -->
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-11-08" conf="runtime-princess->default; contrib->sources">
<!-- Exclude dependency on java-cup and replace it with java-cup-runtime, which is enough.
We use the JAR that is published by us instead of the one from net.sf.squirrel-sql.thirdparty-non-maven
because the latter does not provide a separate JAR for java-cup-runtime. -->
<exclude org="net.sf.squirrel-sql.thirdparty-non-maven" name="java-cup"/>
<exclude org="net.sf.squirrel-sql.thirdparty-non-maven" name="java-cup"/>
</dependency>
<dependency org="io.github.uuverifiers" name="ostrich_2.13" rev="1.4.1" conf="runtime-princess->default; contrib->sources">
<!-- Exclude dependency on java-cup and replace it with java-cup-runtime, which is enough.
We use the JAR that is published by us instead of the one from net.sf.squirrel-sql.thirdparty-non-maven
because the latter does not provide a separate JAR for java-cup-runtime. -->
<exclude org="net.sf.squirrel-sql.thirdparty-non-maven" name="java-cup"/>
</dependency>
<dependency org="edu.tum.cs" name="java-cup" rev="11b-20160615" conf="runtime-princess->runtime"/>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected final FormulaCreator<TFormulaInfo, TType, TEnv, TFuncDecl> getFormulaC
return formulaCreator;
}

final TFormulaInfo extractInfo(Formula pBits) {
protected final TFormulaInfo extractInfo(Formula pBits) {
return getFormulaCreator().extractInfo(pBits);
}

Expand Down
3 changes: 2 additions & 1 deletion src/org/sosy_lab/java_smt/basicimpl/AbstractProver.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import static com.google.common.base.Preconditions.checkState;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.LinkedHashMultimap;
Expand Down Expand Up @@ -147,7 +148,7 @@ protected void unregisterEvaluator(Evaluator pEvaluator) {
}

protected void closeAllEvaluators() {
evaluators.forEach(Evaluator::close);
ImmutableList.copyOf(evaluators).forEach(Evaluator::close);
evaluators.clear();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ protected AbstractStringFormulaManager(
super(pCreator);
}

private StringFormula wrapString(TFormulaInfo formulaInfo) {
protected StringFormula wrapString(TFormulaInfo formulaInfo) {
return getFormulaCreator().encapsulateString(formulaInfo);
}

private RegexFormula wrapRegex(TFormulaInfo formulaInfo) {
protected RegexFormula wrapRegex(TFormulaInfo formulaInfo) {
return getFormulaCreator().encapsulateRegex(formulaInfo);
}

Expand Down
50 changes: 34 additions & 16 deletions src/org/sosy_lab/java_smt/basicimpl/FormulaCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,43 +137,59 @@ public final TType getRegexType() {
public abstract TFormulaInfo makeVariable(TType type, String varName);

public BooleanFormula encapsulateBoolean(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isBooleanType();
checkArgument(
getFormulaType(pTerm).isBooleanType(),
"Boolean formula has unexpected type: %s",
getFormulaType(pTerm));
return new BooleanFormulaImpl<>(pTerm);
}

protected BitvectorFormula encapsulateBitvector(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isBitvectorType();
checkArgument(
getFormulaType(pTerm).isBitvectorType(),
"Bitvector formula has unexpected type: %s",
getFormulaType(pTerm));
return new BitvectorFormulaImpl<>(pTerm);
}

protected FloatingPointFormula encapsulateFloatingPoint(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isFloatingPointType();
checkArgument(
getFormulaType(pTerm).isFloatingPointType(),
"Floatingpoint formula has unexpected type: %s",
getFormulaType(pTerm));
return new FloatingPointFormulaImpl<>(pTerm);
}

protected <TI extends Formula, TE extends Formula> ArrayFormula<TI, TE> encapsulateArray(
TFormulaInfo pTerm, FormulaType<TI> pIndexType, FormulaType<TE> pElementType) {
assert getFormulaType(pTerm).equals(FormulaType.getArrayType(pIndexType, pElementType))
: "Expected: "
+ getFormulaType(pTerm)
+ " but found: "
+ FormulaType.getArrayType(pIndexType, pElementType);

checkArgument(
getFormulaType(pTerm).equals(FormulaType.getArrayType(pIndexType, pElementType)),
"Array formula has unexpected type: %s",
getFormulaType(pTerm));
return new ArrayFormulaImpl<>(pTerm, pIndexType, pElementType);
}

protected StringFormula encapsulateString(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isStringType();
checkArgument(
getFormulaType(pTerm).isStringType(),
"String formula has unexpected type: %s",
getFormulaType(pTerm));
return new StringFormulaImpl<>(pTerm);
}

protected RegexFormula encapsulateRegex(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isRegexType();
checkArgument(
getFormulaType(pTerm).isRegexType(),
"Regex formula has unexpected type: %s",
getFormulaType(pTerm));
return new RegexFormulaImpl<>(pTerm);
}

protected EnumerationFormula encapsulateEnumeration(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isEnumerationType();
checkArgument(
getFormulaType(pTerm).isEnumerationType(),
"Enumeration formula has unexpected type: %s",
getFormulaType(pTerm));
return new EnumerationFormulaImpl<>(pTerm);
}

Expand All @@ -183,10 +199,12 @@ public Formula encapsulateWithTypeOf(TFormulaInfo pTerm) {

@SuppressWarnings("unchecked")
public <T extends Formula> T encapsulate(FormulaType<T> pType, TFormulaInfo pTerm) {
assert pType.equals(getFormulaType(pTerm))
: String.format(
"Trying to encapsulate formula %s of type %s as %s",
pTerm, getFormulaType(pTerm), pType);
checkArgument(
pType.equals(getFormulaType(pTerm)),
"Trying to encapsulate formula %s of type %s as %s",
pTerm,
getFormulaType(pTerm),
pType);
if (pType.isBooleanType()) {
return (T) new BooleanFormulaImpl<>(pTerm);
} else if (pType.isIntegerType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import org.sosy_lab.common.collect.PathCopyingPersistentTreeMap;
import org.sosy_lab.common.collect.PersistentMap;
import org.sosy_lab.java_smt.api.BooleanFormula;
import org.sosy_lab.java_smt.api.Formula;
import org.sosy_lab.java_smt.api.Model;
import org.sosy_lab.java_smt.api.SolverContext.ProverOptions;
import org.sosy_lab.java_smt.api.SolverException;
Expand All @@ -46,6 +47,15 @@ abstract class PrincessAbstractProver<E> extends AbstractProverWithAllSat<E> {
protected final PrincessFormulaManager mgr;
protected final Deque<Level> trackingStack = new ArrayDeque<>(); // symbols on all levels

/**
* Values returned by {@link Model#evaluate(Formula)}.
*
* <p>We need to record these to make sure that the values returned by the evaluator are
* consistant. Calling {@link #isUnsat()} will reset this list as the underlying model has been
* updated.
*/
protected final List<IFormula> evaluatedTerms = new ArrayList<>();

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a bigger issue for Princess.
Can we add a plain test for Princess (without this code) to see where Princess fails to be consistant?
Can we ask the authors to provide a consistant model?

Copy link
Contributor Author

@daniel-raffler daniel-raffler Nov 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This might be a bigger issue for Princess. Can we add a plain test for Princess (without this code) to see where Princess fails to be consistant? Can we ask the authors to provide a consistant model?

I'm afraid in this case the problem here is really with the work-around, and not with Princess. We effectively emulate (get-values (<expr>)) with a sequence of commands:

(push 1)
(assert (= <new_variable> <expr>))
(check-sat)
(get-model) 
// Now get the value from the entry for <new_variable>
(pop 1)

The problem is than the sat check causes the solver to forget the old model, and because of this it can choose a different assignment for the variables. For instance, if the only assertion on the stack is x < y then calling evaluate(x) twice may return different values as the solver simply chooses a different model each time. You can see this by replacing the code in PrincessAbstractProver.getEvaluatedTerms() with ImmutableList.of(). This should cause tests in ModelTest and SolverAllSatTest to fail as the model is not kept consistent across multiply calls to evaluate().

EDIT:
I did some testing earlier and we may not actually need the call to prover.addEvaluatedTerm() in PrincessModel.evalImpl(). Just adding the assignments from the model in PrincessAbstractProver.isUnsat() seems to be enough.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation of PrincessAbstractProver.isUnsat() should not depend on earlier model evaluations, because it can produce a completely different model. The current implementation seems to work well, even if its runtime is not optimal. We can improve this in the future.

// assign a unique partition number for eah added constraint, for unsat-core and interpolation.
protected final UniqueIdGenerator idGenerator = new UniqueIdGenerator();
protected final Deque<PersistentMap<Integer, BooleanFormula>> partitions = new ArrayDeque<>();
Expand Down Expand Up @@ -76,9 +86,11 @@ protected PrincessAbstractProver(
public boolean isUnsat() throws SolverException {
Preconditions.checkState(!closed);
wasLastSatCheckSat = false;
evaluatedTerms.clear();
final Value result = api.checkSat(true);
if (result.equals(SimpleAPI.ProverStatus$.MODULE$.Sat())) {
wasLastSatCheckSat = true;
evaluatedTerms.add(api.partialModelAsFormula());
return false;
} else if (result.equals(SimpleAPI.ProverStatus$.MODULE$.Unsat())) {
return true;
Expand Down Expand Up @@ -121,14 +133,28 @@ protected void popImpl() {
// we have to recreate symbols on lower levels, because JavaSMT assumes "global" symbols.
Level level = trackingStack.pop();
api.addBooleanVariables(asScala(level.booleanSymbols));
api.addConstants(asScala(level.intSymbols));
api.addConstants(asScala(level.theorySymbols));
level.functionSymbols.forEach(api::addFunction);
if (!trackingStack.isEmpty()) {
trackingStack.peek().mergeWithHigher(level);
}
partitions.pop();
}

/**
* Get a list of all terms that have been evaluated in the current model.
*
* <p>The formulas in this list are assignments that extend the original model.
*/
List<IFormula> getEvaluatedTerms() {
return evaluatedTerms;
}

/** Add a new term to the list of evaluated terms. */
void addEvaluatedTerm(IFormula pFormula) {
evaluatedTerms.add(pFormula);
}

@SuppressWarnings("resource")
@Override
public Model getModel() throws SolverException {
Expand All @@ -146,7 +172,7 @@ protected PrincessModel getEvaluatorWithoutChecks() throws SolverException {
} catch (SimpleAPIException ex) {
throw new SolverException(ex.getMessage(), ex);
}
return new PrincessModel(this, partialModel, creator, api);
return registerEvaluator(new PrincessModel(this, partialModel, creator, api));
}

/**
Expand Down Expand Up @@ -213,12 +239,12 @@ void addSymbol(IFormula f) {
}
}

/** add external definition: integer variable. */
/** add external definition: theory variable (integer, rational, string, etc). */
void addSymbol(ITerm f) {
Preconditions.checkState(!closed);
api.addConstant(f);
if (!trackingStack.isEmpty()) {
trackingStack.peek().intSymbols.add(f);
trackingStack.peek().theorySymbols.add(f);
}
}

Expand All @@ -233,21 +259,21 @@ void addSymbol(IFunction f) {

static class Level {
final List<IFormula> booleanSymbols = new ArrayList<>();
final List<ITerm> intSymbols = new ArrayList<>();
final List<ITerm> theorySymbols = new ArrayList<>();
final List<IFunction> functionSymbols = new ArrayList<>();

Level() {}

/** add higher level to current level, we keep the order of creating symbols. */
void mergeWithHigher(Level other) {
this.booleanSymbols.addAll(other.booleanSymbols);
this.intSymbols.addAll(other.intSymbols);
this.theorySymbols.addAll(other.theorySymbols);
this.functionSymbols.addAll(other.functionSymbols);
}

@Override
public String toString() {
return String.format("{%s, %s, %s}", booleanSymbols, intSymbols, functionSymbols);
return String.format("{%s, %s, %s}", booleanSymbols, theorySymbols, functionSymbols);
}
}
}
Loading