-
Notifications
You must be signed in to change notification settings - Fork 56
Add user propagator feature #349
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
Merged
Merged
Changes from all commits
Commits
Show all changes
31 commits
Select commit
Hold shift + click to select a range
6a37798
Added user propagators
ThomasHaas 0b7a8be
Cleanup of Z3UserPropagator
ThomasHaas 17bd762
Removed unused code in example
ThomasHaas c8a1d6b
Added user propagators
ThomasHaas 2673fc5
Cleanup of Z3UserPropagator
ThomasHaas 4e42194
Removed unused code in example
ThomasHaas 7e20470
Merge remote-tracking branch 'origin/userPropagator' into userPropagator
ThomasHaas 134e2fd
Temporary commit
ThomasHaas ac52ef4
Removed all functionality related to equality tracking (it was partia…
ThomasHaas 22fdefc
Improved user propagator documentation.
ThomasHaas 22376a9
Updated licensing information
ThomasHaas 0c7294f
Merge remote-tracking branch 'upstream/master' into userPropagator
ThomasHaas 225367d
- Added user propagator feature: onDecision callback.
ThomasHaas e3f2a0c
Updated SimpleUserPropagator example to use the new onDecision callback
ThomasHaas 78d7b8e
More efficient Z3UserPropagator implementation trying to reuse Boolea…
ThomasHaas efe8115
Changed signature of UserPropagator.onKnownValue.
ThomasHaas 2bf65c9
Fixed performance bottleneck in Nqueens+Propagator example.
ThomasHaas 511a562
More efficient Z3UserPropagator.encapsulate implementation.
ThomasHaas bf209de
Removed unused variable
ThomasHaas 1938a23
Removed more unused variables.
ThomasHaas 7fc347f
- Combined UserPropagator.initialize with UserPropagator.injectBackend.
ThomasHaas 84c109d
Replaced bitshift by bitwise rotation in Z3UserPropagator.encapsulate
ThomasHaas f147009
Evaluator: cleanup
kfriedberger e396610
#352: add model-evaluation for floating-point numbers.
kfriedberger d02a3c0
#357: replace check for boolean constants with direct pointer compari…
kfriedberger 887798e
reduce expiration time for artifact of build-dependencies.
kfriedberger a208911
include more information about segmentation faults in build artifacts.
kfriedberger edd6df1
format code and add some documentation.
kfriedberger 7f757b6
extend NQueens with ALL-SAT routine (which is as fast/slow as the pla…
kfriedberger 4221a04
fix simple styling issues.
kfriedberger 91f4293
small refactoring and adding a simple Junit test.
kfriedberger File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,130 @@ | ||
| // This file is part of JavaSMT, | ||
| // an API wrapper for a collection of SMT solvers: | ||
| // https://github.com/sosy-lab/java-smt | ||
| // | ||
| // SPDX-FileCopyrightText: 2024 Dirk Beyer <https://www.sosy-lab.org> | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package org.sosy_lab.java_smt.api; | ||
|
|
||
| import com.google.auto.value.AutoValue; | ||
| import com.google.common.base.Preconditions; | ||
| import com.google.errorprone.annotations.Immutable; | ||
| import java.math.BigInteger; | ||
| import java.util.BitSet; | ||
|
|
||
| /** | ||
| * Represents a floating-point number with customizable precision, consisting of sign, exponent, and | ||
| * mantissa components. | ||
| */ | ||
| @Immutable | ||
| @AutoValue | ||
| public abstract class FloatingPointNumber { | ||
|
|
||
| public static final int SINGLE_PRECISION_EXPONENT_SIZE = 8; | ||
| public static final int SINGLE_PRECISION_MANTISSA_SIZE = 23; | ||
| public static final int DOUBLE_PRECISION_EXPONENT_SIZE = 11; | ||
| public static final int DOUBLE_PRECISION_MANTISSA_SIZE = 52; | ||
|
|
||
| /** Whether the number is positive (TRUE) or negative (FALSE). */ | ||
| public abstract boolean getSign(); | ||
|
|
||
| /** The exponent of the floating-point number, given as numeric value. */ | ||
| public abstract BigInteger getExponent(); | ||
|
|
||
| /** The mantissa (aka significand) of the floating-point number, given as numeric value. */ | ||
| public abstract BigInteger getMantissa(); | ||
|
|
||
| public abstract int getExponentSize(); | ||
|
|
||
| public abstract int getMantissaSize(); | ||
|
|
||
| public static FloatingPointNumber of( | ||
| boolean sign, BigInteger exponent, BigInteger mantissa, int exponentSize, int mantissaSize) { | ||
| Preconditions.checkArgument(exponent.bitLength() <= exponentSize); | ||
| Preconditions.checkArgument(mantissa.bitLength() <= mantissaSize); | ||
| Preconditions.checkArgument(exponent.compareTo(BigInteger.ZERO) >= 0); | ||
| Preconditions.checkArgument(mantissa.compareTo(BigInteger.ZERO) >= 0); | ||
| return new AutoValue_FloatingPointNumber(sign, exponent, mantissa, exponentSize, mantissaSize); | ||
| } | ||
|
|
||
| public static FloatingPointNumber of(String bits, int exponentSize, int mantissaSize) { | ||
| Preconditions.checkArgument(0 < exponentSize); | ||
| Preconditions.checkArgument(0 < mantissaSize); | ||
| Preconditions.checkArgument(bits.length() == 1 + exponentSize + mantissaSize); | ||
| Preconditions.checkArgument(bits.chars().allMatch(c -> c == '0' || c == '1')); | ||
| boolean sign = bits.charAt(0) == '1'; | ||
| BigInteger exponent = new BigInteger(bits.substring(1, 1 + exponentSize), 2); | ||
| BigInteger mantissa = | ||
| new BigInteger(bits.substring(1 + exponentSize, 1 + exponentSize + mantissaSize), 2); | ||
| return of(sign, exponent, mantissa, exponentSize, mantissaSize); | ||
| } | ||
|
|
||
| private boolean isSinglePrecision() { | ||
| return getExponentSize() == SINGLE_PRECISION_EXPONENT_SIZE | ||
| && getMantissaSize() == SINGLE_PRECISION_MANTISSA_SIZE; | ||
| } | ||
|
|
||
| private boolean isDoublePrecision() { | ||
| return getExponentSize() == DOUBLE_PRECISION_EXPONENT_SIZE | ||
| && getMantissaSize() == DOUBLE_PRECISION_MANTISSA_SIZE; | ||
| } | ||
|
|
||
| /** compute a representation as Java-based float value, if possible. */ | ||
| public float floatValue() { | ||
| Preconditions.checkArgument( | ||
| isSinglePrecision(), | ||
| "Can not represent floating point number %s as Java-based float value.", | ||
| this); | ||
| var bits = getBits(); | ||
| return Float.intBitsToFloat(bits.length() == 0 ? 0 : (int) bits.toLongArray()[0]); | ||
| } | ||
|
|
||
| /** compute a representation as Java-based double value, if possible. */ | ||
| public double doubleValue() { | ||
| Preconditions.checkArgument( | ||
| isSinglePrecision() || isDoublePrecision(), | ||
| "Can not represent floating point number %s as Java-based double value.", | ||
| this); | ||
| if (isSinglePrecision()) { | ||
| // lets be nice to the user and automatically convert from single to double precision | ||
| return floatValue(); | ||
| } | ||
| var bits = getBits(); | ||
| return Double.longBitsToDouble(bits.length() == 0 ? 0 : getBits().toLongArray()[0]); | ||
| } | ||
|
|
||
| private BitSet getBits() { | ||
| var mantissaSize = getMantissaSize(); | ||
| var exponentSize = getExponentSize(); | ||
| var mantissa = getMantissa(); | ||
| var exponent = getExponent(); | ||
| var bits = new BitSet(1 + exponentSize + mantissaSize); | ||
| if (getSign()) { | ||
| bits.set(exponentSize + mantissaSize); | ||
| } | ||
| for (int i = 0; i < exponentSize; i++) { | ||
| bits.set(mantissaSize + i, exponent.testBit(i)); | ||
| } | ||
| for (int i = 0; i < mantissaSize; i++) { | ||
| bits.set(i, mantissa.testBit(i)); | ||
| } | ||
| return bits; | ||
| } | ||
|
|
||
| /** | ||
| * Return a bit-representation of sign-bit, exponent, and mantissa, i.e., a concatenation of their | ||
| * bit-representations in this exact ordering. | ||
| */ | ||
| @Override | ||
| public final String toString() { | ||
| var length = 1 + getExponentSize() + getMantissaSize(); | ||
| var str = new StringBuilder(length); | ||
| var bits = getBits(); | ||
| for (int i = 0; i < length; i++) { | ||
| str.append(bits.get(i) ? '1' : '0'); | ||
| } | ||
| return str.reverse().toString(); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| // This file is part of JavaSMT, | ||
| // an API wrapper for a collection of SMT solvers: | ||
| // https://github.com/sosy-lab/java-smt | ||
| // | ||
| // SPDX-FileCopyrightText: 2024 Dirk Beyer <https://www.sosy-lab.org> | ||
| // | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| package org.sosy_lab.java_smt.api; | ||
|
|
||
| import java.util.Optional; | ||
|
|
||
| /** | ||
| * The PropagatorBackend class is used by {@link UserPropagator} to implement custom user | ||
| * propagators. It contains functions to interact with the SAT/SMT core during solving, for example, | ||
| * it provides the ability to propagate conflicts and to influence the decision-making. | ||
| */ | ||
| public interface PropagatorBackend { | ||
|
|
||
| /** | ||
| * Registers an expression to be observed by a {@link UserPropagator}. See {@link | ||
| * UserPropagator#onKnownValue} and {@link UserPropagator#onDecision} for more information. | ||
| * | ||
| * @param theoryExpr The expression to observe. | ||
| */ | ||
| void registerExpression(BooleanFormula theoryExpr); | ||
|
|
||
| /** | ||
| * Raises a conflict caused by a set of conflicting assignments. Shall only be called from within | ||
| * a callback by {@link UserPropagator} such as {@link UserPropagator#onKnownValue} and {@link | ||
| * UserPropagator#onFinalCheck()}. | ||
| * | ||
| * <p>Effectively causes the solver to learn the implication "{@code conflictExpressions} => | ||
| * false" | ||
| * | ||
| * @param conflictExpressions A set of inconsistent assignments. | ||
| */ | ||
| void propagateConflict(BooleanFormula[] conflictExpressions); | ||
|
|
||
| /** | ||
| * Propagates a consequence implied by a set of assigned expressions. Shall only be called from | ||
| * within a callback by {@link UserPropagator} such as {@link UserPropagator#onKnownValue} and | ||
| * {@link UserPropagator#onFinalCheck()}. | ||
| * | ||
| * <p>Effectively causes the solver to learn the implication "/\ {@code assignedExpressions} => | ||
| * {@code consequence}" It is possible to have an empty set of {@code assignedExpressions} to | ||
| * generate a theory lemma. | ||
| * | ||
| * @param assignedExpressions A set of assigned expressions. | ||
| * @param consequence The consequence implied by the assigned expressions. | ||
| */ | ||
| void propagateConsequence(BooleanFormula[] assignedExpressions, BooleanFormula consequence); | ||
|
|
||
| /** | ||
| * Propagates a decision to be made by the solver. If called during {@link | ||
| * UserPropagator#onKnownValue}, will set the next decision to be made. If called during {@link | ||
| * UserPropagator#onDecision}, will overwrite the current decision to be made. | ||
| * | ||
| * @param expr The expression to assign to next. | ||
| * @param value The value to be assigned. If not given, the solver will decide. | ||
| * @return False, if the value of {@code expr} is already assigned. True, otherwise. Note that the | ||
| * value of {@code expr} may already be decided before being reported via {@link | ||
| * UserPropagator#onKnownValue}. | ||
| */ | ||
| boolean propagateNextDecision(BooleanFormula expr, Optional<Boolean> value); | ||
|
|
||
| /** | ||
| * Enables tracking of expression values for the associated {@link UserPropagator} via {@link | ||
| * UserPropagator#onKnownValue}. | ||
| * | ||
| * <p>This function is typically called from {@link UserPropagator#initializeWithBackend} if the | ||
| * theory solver needs to listen to the value of expressions registered by {@link | ||
| * #registerExpression}. | ||
| */ | ||
| void notifyOnKnownValue(); | ||
|
|
||
| /** | ||
| * Enables tracking of decisions made for the associated {@link UserPropagator} via {@link | ||
| * UserPropagator#onDecision(BooleanFormula, boolean)}. | ||
| * | ||
| * <p>This function is typically called from {@link UserPropagator#initializeWithBackend} if the | ||
| * theory solver needs to listen to and/or modify the decisions made by the solver on expressions | ||
| * registered by {@link #registerExpression}. | ||
| */ | ||
| void notifyOnDecision(); | ||
|
|
||
| /** | ||
| * Enables the final callback {@link UserPropagator#onFinalCheck()} that is invoked when the | ||
| * solver finds a full satisfying assignment. | ||
| * | ||
| * <p>This function is typically called from {@link UserPropagator#initializeWithBackend} if the | ||
| * theory solver needs to perform final consistency checks. | ||
| */ | ||
| void notifyOnFinalCheck(); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.