mirror of
https://github.com/Z3Prover/z3
synced 2025-04-19 15:19:01 +00:00
Merge branch 'master' into polysat
This commit is contained in:
commit
1df749ad33
2
.github/workflows/android-build.yml
vendored
2
.github/workflows/android-build.yml
vendored
|
@ -27,7 +27,7 @@ jobs:
|
|||
run: |
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_ARCH_ABI=${{ matrix.android-abi }} "-DCMAKE_ANDROID_NDK=$ANDROID_NDK_LATEST_HOME" -DZ3_BUILD_JAVA_BINDINGS=TRUE -G "Unix Makefiles" -DJAVA_AWT_LIBRARY=NotNeeded -DJAVA_JVM_LIBRARY=NotNeeded -DJAVA_INCLUDE_PATH2=NotNeeded -DJAVA_AWT_INCLUDE_PATH=NotNeeded ../
|
||||
cmake -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_API=21 -DCMAKE_ANDROID_ARCH_ABI=${{ matrix.android-abi }} "-DCMAKE_ANDROID_NDK=$ANDROID_NDK_LATEST_HOME" -DZ3_BUILD_JAVA_BINDINGS=TRUE -G "Unix Makefiles" ../
|
||||
make -j $(nproc)
|
||||
tar -cvf z3-build-${{ matrix.android-abi }}.tar *.jar *.so
|
||||
|
||||
|
|
2
.github/workflows/docker-image.yml
vendored
2
.github/workflows/docker-image.yml
vendored
|
@ -41,7 +41,7 @@ jobs:
|
|||
type=edge
|
||||
type=sha,prefix=ubuntu-20.04-bare-z3-sha-
|
||||
- name: Build and push Bare Z3 Docker Image
|
||||
uses: docker/build-push-action@v3.1.0
|
||||
uses: docker/build-push-action@v3.1.1
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
|
20
.github/workflows/msvc-static-build.yml
vendored
Normal file
20
.github/workflows/msvc-static-build.yml
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
name: MSVC Static Build
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2019
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
steps:
|
||||
- name: Checkout Repo
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Build
|
||||
run: |
|
||||
cmake -B build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DZ3_BUILD_LIBZ3_SHARED=OFF -DZ3_BUILD_LIBZ3_MSVC_STATIC=ON
|
||||
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
|
||||
|
3
.github/workflows/wasm-release.yml
vendored
3
.github/workflows/wasm-release.yml
vendored
|
@ -12,6 +12,9 @@ defaults:
|
|||
env:
|
||||
EM_VERSION: 3.1.15
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
|
|
3
.github/workflows/wasm.yml
vendored
3
.github/workflows/wasm.yml
vendored
|
@ -12,6 +12,9 @@ defaults:
|
|||
env:
|
||||
EM_VERSION: 3.1.15
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Check
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -91,4 +91,5 @@ examples/**/obj
|
|||
CMakeSettings.json
|
||||
# Editor temp files
|
||||
*.swp
|
||||
.DS_Store
|
||||
.DS_Store
|
||||
dbg/**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
cmake_minimum_required(VERSION 3.4)
|
||||
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cxx_compiler_flags_overrides.cmake")
|
||||
project(Z3 VERSION 4.11.0.0 LANGUAGES CXX C)
|
||||
project(Z3 VERSION 4.11.3.0 LANGUAGES CXX C)
|
||||
|
||||
################################################################################
|
||||
# Project version
|
||||
|
@ -304,6 +304,7 @@ endif()
|
|||
# Option to control what type of library we build
|
||||
################################################################################
|
||||
option(Z3_BUILD_LIBZ3_SHARED "Build libz3 as a shared library if true, otherwise build a static library" ON)
|
||||
option(Z3_BUILD_LIBZ3_MSVC_STATIC "Build libz3 as a statically-linked runtime library" OFF)
|
||||
|
||||
|
||||
################################################################################
|
||||
|
|
605
Parameters.md
Normal file
605
Parameters.md
Normal file
|
@ -0,0 +1,605 @@
|
|||
## Module pi
|
||||
|
||||
Description: pattern inference (heuristics) for universal formulas (without annotation)
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
arith | unsigned int | 0 - do not infer patterns with arithmetic terms, 1 - use patterns with arithmetic terms if there is no other pattern, 2 - always use patterns with arithmetic terms | 1
|
||||
arith_weight | unsigned int | default weight for quantifiers where the only available pattern has nested arithmetic terms | 5
|
||||
block_loop_patterns | bool | block looping patterns during pattern inference | true
|
||||
max_multi_patterns | unsigned int | when patterns are not provided, the prover uses a heuristic to infer them, this option sets the threshold on the number of extra multi-patterns that can be created; by default, the prover creates at most one multi-pattern when there is no unary pattern | 0
|
||||
non_nested_arith_weight | unsigned int | default weight for quantifiers where the only available pattern has non nested arithmetic terms | 10
|
||||
pull_quantifiers | bool | pull nested quantifiers, if no pattern was found | true
|
||||
use_database | bool | use pattern database | false
|
||||
warnings | bool | enable/disable warning messages in the pattern inference module | false
|
||||
|
||||
## Module tactic
|
||||
|
||||
Description: tactic parameters
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
blast_term_ite.max_inflation | unsigned int | multiplicative factor of initial term size. | 4294967295
|
||||
blast_term_ite.max_steps | unsigned int | maximal number of steps allowed for tactic. | 4294967295
|
||||
default_tactic | symbol | overwrite default tactic in strategic solver |
|
||||
propagate_values.max_rounds | unsigned int | maximal number of rounds to propagate values. | 4
|
||||
solve_eqs.context_solve | bool | solve equalities within disjunctions. | true
|
||||
solve_eqs.ite_solver | bool | use if-then-else solvers. | true
|
||||
solve_eqs.max_occs | unsigned int | maximum number of occurrences for considering a variable for gaussian eliminations. | 4294967295
|
||||
solve_eqs.theory_solver | bool | use theory solvers. | true
|
||||
|
||||
## Module pp
|
||||
|
||||
Description: pretty printer
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
bounded | bool | ignore characters exceeding max width | false
|
||||
bv_literals | bool | use Bit-Vector literals (e.g, #x0F and #b0101) during pretty printing | true
|
||||
bv_neg | bool | use bvneg when displaying Bit-Vector literals where the most significant bit is 1 | false
|
||||
decimal | bool | pretty print real numbers using decimal notation (the output may be truncated). Z3 adds a ? if the value is not precise | false
|
||||
decimal_precision | unsigned int | maximum number of decimal places to be used when pp.decimal=true | 10
|
||||
fixed_indent | bool | use a fixed indentation for applications | false
|
||||
flat_assoc | bool | flat associative operators (when pretty printing SMT2 terms/formulas) | true
|
||||
fp_real_literals | bool | use real-numbered floating point literals (e.g, +1.0p-1) during pretty printing | false
|
||||
max_depth | unsigned int | max. term depth (when pretty printing SMT2 terms/formulas) | 5
|
||||
max_indent | unsigned int | max. indentation in pretty printer | 4294967295
|
||||
max_num_lines | unsigned int | max. number of lines to be displayed in pretty printer | 4294967295
|
||||
max_ribbon | unsigned int | max. ribbon (width - indentation) in pretty printer | 80
|
||||
max_width | unsigned int | max. width in pretty printer | 80
|
||||
min_alias_size | unsigned int | min. size for creating an alias for a shared term (when pretty printing SMT2 terms/formulas) | 10
|
||||
pretty_proof | bool | use slower, but prettier, printer for proofs | false
|
||||
simplify_implies | bool | simplify nested implications for pretty printing | true
|
||||
single_line | bool | ignore line breaks when true | false
|
||||
|
||||
## Module sat
|
||||
|
||||
Description: propositional SAT solver
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
abce | bool | eliminate blocked clauses using asymmetric literals | false
|
||||
acce | bool | eliminate covered clauses using asymmetric added literals | false
|
||||
anf | bool | enable ANF based simplification in-processing | false
|
||||
anf.delay | unsigned int | delay ANF simplification by in-processing round | 2
|
||||
anf.exlin | bool | enable extended linear simplification | false
|
||||
asymm_branch | bool | asymmetric branching | true
|
||||
asymm_branch.all | bool | asymmetric branching on all literals per clause | false
|
||||
asymm_branch.delay | unsigned int | number of simplification rounds to wait until invoking asymmetric branch simplification | 1
|
||||
asymm_branch.limit | unsigned int | approx. maximum number of literals visited during asymmetric branching | 100000000
|
||||
asymm_branch.rounds | unsigned int | maximal number of rounds to run asymmetric branch simplifications if progress is made | 2
|
||||
asymm_branch.sampled | bool | use sampling based asymmetric branching based on binary implication graph | true
|
||||
ate | bool | asymmetric tautology elimination | true
|
||||
backtrack.conflicts | unsigned int | number of conflicts before enabling chronological backtracking | 4000
|
||||
backtrack.scopes | unsigned int | number of scopes to enable chronological backtracking | 100
|
||||
bca | bool | blocked clause addition - add blocked binary clauses | false
|
||||
bce | bool | eliminate blocked clauses | false
|
||||
bce_at | unsigned int | eliminate blocked clauses only once at the given simplification round | 2
|
||||
bce_delay | unsigned int | delay eliminate blocked clauses until simplification round | 2
|
||||
binspr | bool | enable SPR inferences of binary propagation redundant clauses. This inprocessing step eliminates models | false
|
||||
blocked_clause_limit | unsigned int | maximum number of literals visited during blocked clause elimination | 100000000
|
||||
branching.anti_exploration | bool | apply anti-exploration heuristic for branch selection | false
|
||||
branching.heuristic | symbol | branching heuristic vsids, chb | vsids
|
||||
burst_search | unsigned int | number of conflicts before first global simplification | 100
|
||||
cardinality.encoding | symbol | encoding used for at-most-k constraints: grouped, bimander, ordered, unate, circuit | grouped
|
||||
cardinality.solver | bool | use cardinality solver | true
|
||||
cce | bool | eliminate covered clauses | false
|
||||
core.minimize | bool | minimize computed core | false
|
||||
core.minimize_partial | bool | apply partial (cheap) core minimization | false
|
||||
cut | bool | enable AIG based simplification in-processing | false
|
||||
cut.aig | bool | extract aigs (and ites) from cluases for cut simplification | false
|
||||
cut.delay | unsigned int | delay cut simplification by in-processing round | 2
|
||||
cut.dont_cares | bool | integrate dont cares with cuts | true
|
||||
cut.force | bool | force redoing cut-enumeration until a fixed-point | false
|
||||
cut.lut | bool | extract luts from clauses for cut simplification | false
|
||||
cut.npn3 | bool | extract 3 input functions from clauses for cut simplification | false
|
||||
cut.redundancies | bool | integrate redundancy checking of cuts | true
|
||||
cut.xor | bool | extract xors from clauses for cut simplification | false
|
||||
ddfw.init_clause_weight | unsigned int | initial clause weight for DDFW local search | 8
|
||||
ddfw.reinit_base | unsigned int | increment basis for geometric backoff scheme of re-initialization of weights | 10000
|
||||
ddfw.restart_base | unsigned int | number of flips used a starting point for hessitant restart backoff | 100000
|
||||
ddfw.threads | unsigned int | number of ddfw threads to run in parallel with sat solver | 0
|
||||
ddfw.use_reward_pct | unsigned int | percentage to pick highest reward variable when it has reward 0 | 15
|
||||
ddfw_search | bool | use ddfw local search instead of CDCL | false
|
||||
dimacs.core | bool | extract core from DIMACS benchmarks | false
|
||||
drat.activity | bool | dump variable activities | false
|
||||
drat.binary | bool | use Binary DRAT output format | false
|
||||
drat.check_sat | bool | build up internal trace, check satisfying model | false
|
||||
drat.check_unsat | bool | build up internal proof and check | false
|
||||
drat.file | symbol | file to dump DRAT proofs |
|
||||
drup.trim | bool | build and trim drup proof | false
|
||||
dyn_sub_res | bool | dynamic subsumption resolution for minimizing learned clauses | true
|
||||
elim_vars | bool | enable variable elimination using resolution during simplification | true
|
||||
elim_vars_bdd | bool | enable variable elimination using BDD recompilation during simplification | true
|
||||
elim_vars_bdd_delay | unsigned int | delay elimination of variables using BDDs until after simplification round | 3
|
||||
enable_pre_simplify | bool | enable pre simplifications before the bounded search | false
|
||||
euf | bool | enable euf solver (this feature is preliminary and not ready for general consumption) | false
|
||||
force_cleanup | bool | force cleanup to remove tautologies and simplify clauses | false
|
||||
gc | symbol | garbage collection strategy: psm, glue, glue_psm, dyn_psm | glue_psm
|
||||
gc.burst | bool | perform eager garbage collection during initialization | false
|
||||
gc.defrag | bool | defragment clauses when garbage collecting | true
|
||||
gc.increment | unsigned int | increment to the garbage collection threshold | 500
|
||||
gc.initial | unsigned int | learned clauses garbage collection frequency | 20000
|
||||
gc.k | unsigned int | learned clauses that are inactive for k gc rounds are permanently deleted (only used in dyn_psm) | 7
|
||||
gc.small_lbd | unsigned int | learned clauses with small LBD are never deleted (only used in dyn_psm) | 3
|
||||
inprocess.max | unsigned int | maximal number of inprocessing passes | 4294967295
|
||||
inprocess.out | symbol | file to dump result of the first inprocessing step and exit |
|
||||
local_search | bool | use local search instead of CDCL | false
|
||||
local_search_dbg_flips | bool | write debug information for number of flips | false
|
||||
local_search_mode | symbol | local search algorithm, either default wsat or qsat | wsat
|
||||
local_search_threads | unsigned int | number of local search threads to find satisfiable solution | 0
|
||||
lookahead.cube.cutoff | symbol | cutoff type used to create lookahead cubes: depth, freevars, psat, adaptive_freevars, adaptive_psat | depth
|
||||
lookahead.cube.depth | unsigned int | cut-off depth to create cubes. Used when lookahead.cube.cutoff is depth. | 1
|
||||
lookahead.cube.fraction | double | adaptive fraction to create lookahead cubes. Used when lookahead.cube.cutoff is adaptive_freevars or adaptive_psat | 0.4
|
||||
lookahead.cube.freevars | double | cube free variable fraction. Used when lookahead.cube.cutoff is freevars | 0.8
|
||||
lookahead.cube.psat.clause_base | double | clause base for PSAT cutoff | 2
|
||||
lookahead.cube.psat.trigger | double | trigger value to create lookahead cubes for PSAT cutoff. Used when lookahead.cube.cutoff is psat | 5
|
||||
lookahead.cube.psat.var_exp | double | free variable exponent for PSAT cutoff | 1
|
||||
lookahead.delta_fraction | double | number between 0 and 1, the smaller the more literals are selected for double lookahead | 1.0
|
||||
lookahead.double | bool | enable doubld lookahead | true
|
||||
lookahead.global_autarky | bool | prefer to branch on variables that occur in clauses that are reduced | false
|
||||
lookahead.preselect | bool | use pre-selection of subset of variables for branching | false
|
||||
lookahead.reward | symbol | select lookahead heuristic: ternary, heule_schur (Heule Schur), heuleu (Heule Unit), unit, or march_cu | march_cu
|
||||
lookahead.use_learned | bool | use learned clauses when selecting lookahead literal | false
|
||||
lookahead_scores | bool | extract lookahead scores. A utility that can only be used from the DIMACS front-end | false
|
||||
lookahead_simplify | bool | use lookahead solver during simplification | false
|
||||
lookahead_simplify.bca | bool | add learned binary clauses as part of lookahead simplification | true
|
||||
max_conflicts | unsigned int | maximum number of conflicts | 4294967295
|
||||
max_memory | unsigned int | maximum amount of memory in megabytes | 4294967295
|
||||
minimize_lemmas | bool | minimize learned clauses | true
|
||||
override_incremental | bool | override incremental safety gaps. Enable elimination of blocked clauses and variables even if solver is reused | false
|
||||
pb.lemma_format | symbol | generate either cardinality or pb lemmas | cardinality
|
||||
pb.min_arity | unsigned int | minimal arity to compile pb/cardinality constraints to CNF | 9
|
||||
pb.resolve | symbol | resolution strategy for boolean algebra solver: cardinality, rounding | cardinality
|
||||
pb.solver | symbol | method for handling Pseudo-Boolean constraints: circuit (arithmetical circuit), sorting (sorting circuit), totalizer (use totalizer encoding), binary_merge, segmented, solver (use native solver) | solver
|
||||
phase | symbol | phase selection strategy: always_false, always_true, basic_caching, random, caching | caching
|
||||
phase.sticky | bool | use sticky phase caching | true
|
||||
prob_search | bool | use probsat local search instead of CDCL | false
|
||||
probing | bool | apply failed literal detection during simplification | true
|
||||
probing_binary | bool | probe binary clauses | true
|
||||
probing_cache | bool | add binary literals as lemmas | true
|
||||
probing_cache_limit | unsigned int | cache binaries unless overall memory usage exceeds cache limit | 1024
|
||||
probing_limit | unsigned int | limit to the number of probe calls | 5000000
|
||||
propagate.prefetch | bool | prefetch watch lists for assigned literals | true
|
||||
random_freq | double | frequency of random case splits | 0.01
|
||||
random_seed | unsigned int | random seed | 0
|
||||
reorder.activity_scale | unsigned int | scaling factor for activity update | 100
|
||||
reorder.base | unsigned int | number of conflicts per random reorder | 4294967295
|
||||
reorder.itau | double | inverse temperature for softmax | 4.0
|
||||
rephase.base | unsigned int | number of conflicts per rephase | 1000
|
||||
resolution.cls_cutoff1 | unsigned int | limit1 - total number of problems clauses for the second cutoff of Boolean variable elimination | 100000000
|
||||
resolution.cls_cutoff2 | unsigned int | limit2 - total number of problems clauses for the second cutoff of Boolean variable elimination | 700000000
|
||||
resolution.limit | unsigned int | approx. maximum number of literals visited during variable elimination | 500000000
|
||||
resolution.lit_cutoff_range1 | unsigned int | second cutoff (total number of literals) for Boolean variable elimination, for problems containing less than res_cls_cutoff1 clauses | 700
|
||||
resolution.lit_cutoff_range2 | unsigned int | second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than res_cls_cutoff1 and less than res_cls_cutoff2 | 400
|
||||
resolution.lit_cutoff_range3 | unsigned int | second cutoff (total number of literals) for Boolean variable elimination, for problems containing more than res_cls_cutoff2 | 300
|
||||
resolution.occ_cutoff | unsigned int | first cutoff (on number of positive/negative occurrences) for Boolean variable elimination | 10
|
||||
resolution.occ_cutoff_range1 | unsigned int | second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing less than res_cls_cutoff1 clauses | 8
|
||||
resolution.occ_cutoff_range2 | unsigned int | second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than res_cls_cutoff1 and less than res_cls_cutoff2 | 5
|
||||
resolution.occ_cutoff_range3 | unsigned int | second cutoff (number of positive/negative occurrences) for Boolean variable elimination, for problems containing more than res_cls_cutoff2 | 3
|
||||
restart | symbol | restart strategy: static, luby, ema or geometric | ema
|
||||
restart.emafastglue | double | ema alpha factor for fast moving average | 0.03
|
||||
restart.emaslowglue | double | ema alpha factor for slow moving average | 1e-05
|
||||
restart.factor | double | restart increment factor for geometric strategy | 1.5
|
||||
restart.fast | bool | use fast restart approach only removing less active literals. | true
|
||||
restart.initial | unsigned int | initial restart (number of conflicts) | 2
|
||||
restart.margin | double | margin between fast and slow restart factors. For ema | 1.1
|
||||
restart.max | unsigned int | maximal number of restarts. | 4294967295
|
||||
retain_blocked_clauses | bool | retain blocked clauses as lemmas | true
|
||||
scc | bool | eliminate Boolean variables by computing strongly connected components | true
|
||||
scc.tr | bool | apply transitive reduction, eliminate redundant binary clauses | true
|
||||
search.sat.conflicts | unsigned int | period for solving for sat (in number of conflicts) | 400
|
||||
search.unsat.conflicts | unsigned int | period for solving for unsat (in number of conflicts) | 400
|
||||
simplify.delay | unsigned int | set initial delay of simplification by a conflict count | 0
|
||||
subsumption | bool | eliminate subsumed clauses | true
|
||||
subsumption.limit | unsigned int | approx. maximum number of literals visited during subsumption (and subsumption resolution) | 100000000
|
||||
threads | unsigned int | number of parallel threads to use | 1
|
||||
variable_decay | unsigned int | multiplier (divided by 100) for the VSIDS activity increment | 110
|
||||
|
||||
## Module solver
|
||||
|
||||
Description: solver parameters
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
axioms2files | bool | print negated theory axioms to separate files during search | false
|
||||
cancel_backup_file | symbol | file to save partial search state if search is canceled |
|
||||
lemmas2console | bool | print lemmas during search | false
|
||||
smtlib2_log | symbol | file to save solver interaction |
|
||||
timeout | unsigned int | timeout on the solver object; overwrites a global timeout | 4294967295
|
||||
|
||||
## Module opt
|
||||
|
||||
Description: optimization parameters
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
dump_benchmarks | bool | dump benchmarks for profiling | false
|
||||
dump_models | bool | display intermediary models to stdout | false
|
||||
elim_01 | bool | eliminate 01 variables | true
|
||||
enable_core_rotate | bool | enable core rotation to both sample cores and correction sets | false
|
||||
enable_lns | bool | enable LNS during weighted maxsat | false
|
||||
enable_sat | bool | enable the new SAT core for propositional constraints | true
|
||||
enable_sls | bool | enable SLS tuning during weighted maxsat | false
|
||||
incremental | bool | set incremental mode. It disables pre-processing and enables adding constraints in model event handler | false
|
||||
lns_conflicts | unsigned int | initial conflict count for LNS search | 1000
|
||||
maxlex.enable | bool | enable maxlex heuristic for lexicographic MaxSAT problems | true
|
||||
maxres.add_upper_bound_block | bool | restict upper bound with constraint | false
|
||||
maxres.hill_climb | bool | give preference for large weight cores | true
|
||||
maxres.max_core_size | unsigned int | break batch of generated cores if size reaches this number | 3
|
||||
maxres.max_correction_set_size | unsigned int | allow generating correction set constraints up to maximal size | 3
|
||||
maxres.max_num_cores | unsigned int | maximal number of cores per round | 200
|
||||
maxres.maximize_assignment | bool | find an MSS/MCS to improve current assignment | false
|
||||
maxres.pivot_on_correction_set | bool | reduce soft constraints if the current correction set is smaller than current core | true
|
||||
maxres.wmax | bool | use weighted theory solver to constrain upper bounds | false
|
||||
maxsat_engine | symbol | select engine for maxsat: 'core_maxsat', 'wmax', 'maxres', 'pd-maxres', 'maxres-bin', 'rc2' | maxres
|
||||
optsmt_engine | symbol | select optimization engine: 'basic', 'symba' | basic
|
||||
pb.compile_equality | bool | compile arithmetical equalities into pseudo-Boolean equality (instead of two inequalites) | false
|
||||
pp.neat | bool | use neat (as opposed to less readable, but faster) pretty printer when displaying context | true
|
||||
pp.wcnf | bool | print maxsat benchmark into wcnf format | false
|
||||
priority | symbol | select how to priortize objectives: 'lex' (lexicographic), 'pareto', 'box' | lex
|
||||
rc2.totalizer | bool | use totalizer for rc2 encoding | true
|
||||
rlimit | unsigned int | resource limit (0 means no limit) | 0
|
||||
solution_prefix | symbol | path prefix to dump intermediary, but non-optimal, solutions |
|
||||
timeout | unsigned int | timeout (in milliseconds) (UINT_MAX and 0 mean no timeout) | 4294967295
|
||||
|
||||
## Module parallel
|
||||
|
||||
Description: parameters for parallel solver
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
conquer.backtrack_frequency | unsigned int | frequency to apply core minimization during conquer | 10
|
||||
conquer.batch_size | unsigned int | number of cubes to batch together for fast conquer | 100
|
||||
conquer.delay | unsigned int | delay of cubes until applying conquer | 10
|
||||
conquer.restart.max | unsigned int | maximal number of restarts during conquer phase | 5
|
||||
enable | bool | enable parallel solver by default on selected tactics (for QF_BV) | false
|
||||
simplify.exp | double | restart and inprocess max is multiplied by simplify.exp ^ depth | 1
|
||||
simplify.inprocess.max | unsigned int | maximal number of inprocessing steps during simplification | 2
|
||||
simplify.max_conflicts | unsigned int | maximal number of conflicts during simplifcation phase | 4294967295
|
||||
simplify.restart.max | unsigned int | maximal number of restarts during simplification phase | 5000
|
||||
threads.max | unsigned int | caps maximal number of threads below the number of processors | 10000
|
||||
|
||||
## Module nnf
|
||||
|
||||
Description: negation normal form
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
ignore_labels | bool | remove/ignore labels in the input formula, this option is ignored if proofs are enabled | false
|
||||
max_memory | unsigned int | maximum amount of memory in megabytes | 4294967295
|
||||
mode | symbol | NNF translation mode: skolem (skolem normal form), quantifiers (skolem normal form + quantifiers in NNF), full | skolem
|
||||
sk_hack | bool | hack for VCC | false
|
||||
|
||||
## Module algebraic
|
||||
|
||||
Description: real algebraic number package. Non-default parameter settings are not supported
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
factor | bool | use polynomial factorization to simplify polynomials representing algebraic numbers | true
|
||||
factor_max_prime | unsigned int | parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter limits the maximum prime number p to be used in the first step | 31
|
||||
factor_num_primes | unsigned int | parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. The search space may be reduced by factoring the polynomial in different GF(p)'s. This parameter specify the maximum number of finite factorizations to be considered, before lifiting and searching | 1
|
||||
factor_search_size | unsigned int | parameter for the polynomial factorization procedure in the algebraic number module. Z3 polynomial factorization is composed of three steps: factorization in GF(p), lifting and search. This parameter can be used to limit the search space | 5000
|
||||
min_mag | unsigned int | Z3 represents algebraic numbers using a (square-free) polynomial p and an isolating interval (which contains one and only one root of p). This interval may be refined during the computations. This parameter specifies whether to cache the value of a refined interval or not. It says the minimal size of an interval for caching purposes is 1/2^16 | 16
|
||||
zero_accuracy | unsigned int | one of the most time-consuming operations in the real algebraic number module is determining the sign of a polynomial evaluated at a sample point with non-rational algebraic number values. Let k be the value of this option. If k is 0, Z3 uses precise computation. Otherwise, the result of a polynomial evaluation is considered to be 0 if Z3 can show it is inside the interval (-1/2^k, 1/2^k) | 0
|
||||
|
||||
## Module combined_solver
|
||||
|
||||
Description: combines two solvers: non-incremental (solver1) and incremental (solver2)
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
ignore_solver1 | bool | if true, solver 2 is always used | false
|
||||
solver2_timeout | unsigned int | fallback to solver 1 after timeout even when in incremental model | 4294967295
|
||||
solver2_unknown | unsigned int | what should be done when solver 2 returns unknown: 0 - just return unknown, 1 - execute solver 1 if quantifier free problem, 2 - execute solver 1 | 1
|
||||
|
||||
## Module rcf
|
||||
|
||||
Description: real closed fields
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
clean_denominators | bool | clean denominators before root isolation | true
|
||||
inf_precision | unsigned int | a value k that is the initial interval size (i.e., (0, 1/2^l)) used as an approximation for infinitesimal values | 24
|
||||
initial_precision | unsigned int | a value k that is the initial interval size (as 1/2^k) when creating transcendentals and approximated division | 24
|
||||
lazy_algebraic_normalization | bool | during sturm-seq and square-free polynomial computations, only normalize algebraic polynomial expressions when the defining polynomial is monic | true
|
||||
max_precision | unsigned int | during sign determination we switch from interval arithmetic to complete methods when the interval size is less than 1/2^k, where k is the max_precision | 128
|
||||
use_prem | bool | use pseudo-remainder instead of remainder when computing GCDs and Sturm-Tarski sequences | true
|
||||
ERROR: unknown module 'rewriter, description: new formula simplification module used in the tactic framework'
|
||||
|
||||
## Module ackermannization
|
||||
|
||||
Description: solving UF via ackermannization
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
eager | bool | eagerly instantiate all congruence rules | true
|
||||
inc_sat_backend | bool | use incremental SAT | false
|
||||
sat_backend | bool | use SAT rather than SMT in qfufbv_ackr_tactic | false
|
||||
|
||||
## Module nlsat
|
||||
|
||||
Description: nonlinear solver
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
check_lemmas | bool | check lemmas on the fly using an independent nlsat solver | false
|
||||
factor | bool | factor polynomials produced during conflict resolution. | true
|
||||
inline_vars | bool | inline variables that can be isolated from equations (not supported in incremental mode) | false
|
||||
lazy | unsigned int | how lazy the solver is. | 0
|
||||
log_lemmas | bool | display lemmas as self-contained SMT formulas | false
|
||||
max_conflicts | unsigned int | maximum number of conflicts. | 4294967295
|
||||
max_memory | unsigned int | maximum amount of memory in megabytes | 4294967295
|
||||
minimize_conflicts | bool | minimize conflicts | false
|
||||
randomize | bool | randomize selection of a witness in nlsat. | true
|
||||
reorder | bool | reorder variables. | true
|
||||
seed | unsigned int | random seed. | 0
|
||||
shuffle_vars | bool | use a random variable order. | false
|
||||
simplify_conflicts | bool | simplify conflicts using equalities before resolving them in nlsat solver. | true
|
||||
|
||||
|
||||
## Module fp
|
||||
|
||||
Description: fixedpoint parameters
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
bmc.linear_unrolling_depth | unsigned int | Maximal level to explore | 4294967295
|
||||
datalog.all_or_nothing_deltas | bool | compile rules so that it is enough for the delta relation in union and widening operations to determine only whether the updated relation was modified or not | false
|
||||
datalog.check_relation | symbol | name of default relation to check. operations on the default relation will be verified using SMT solving | null
|
||||
datalog.compile_with_widening | bool | widening will be used to compile recursive rules | false
|
||||
datalog.dbg_fpr_nonempty_relation_signature | bool | if true, finite_product_relation will attempt to avoid creating inner relation with empty signature by putting in half of the table columns, if it would have been empty otherwise | false
|
||||
datalog.default_relation | symbol | default relation implementation: external_relation, pentagon | pentagon
|
||||
datalog.default_table | symbol | default table implementation: sparse, hashtable, bitvector, interval | sparse
|
||||
datalog.default_table_checked | bool | if true, the default table will be default_table inside a wrapper that checks that its results are the same as of default_table_checker table | false
|
||||
datalog.default_table_checker | symbol | see default_table_checked | null
|
||||
datalog.explanations_on_relation_level | bool | if true, explanations are generated as history of each relation, rather than per fact (generate_explanations must be set to true for this option to have any effect) | false
|
||||
datalog.generate_explanations | bool | produce explanations for produced facts when using the datalog engine | false
|
||||
datalog.initial_restart_timeout | unsigned int | length of saturation run before the first restart (in ms), zero means no restarts | 0
|
||||
datalog.magic_sets_for_queries | bool | magic set transformation will be used for queries | false
|
||||
datalog.output_profile | bool | determines whether profile information should be output when outputting Datalog rules or instructions | false
|
||||
datalog.print.tuples | bool | determines whether tuples for output predicates should be output | true
|
||||
datalog.profile_timeout_milliseconds | unsigned int | instructions and rules that took less than the threshold will not be printed when printed the instruction/rule list | 0
|
||||
datalog.similarity_compressor | bool | rules that differ only in values of constants will be merged into a single rule | true
|
||||
datalog.similarity_compressor_threshold | unsigned int | if similarity_compressor is on, this value determines how many similar rules there must be in order for them to be merged | 11
|
||||
datalog.subsumption | bool | if true, removes/filters predicates with total transitions | true
|
||||
datalog.timeout | unsigned int | Time limit used for saturation | 0
|
||||
datalog.unbound_compressor | bool | auxiliary relations will be introduced to avoid unbound variables in rule heads | true
|
||||
datalog.use_map_names | bool | use names from map files when displaying tuples | true
|
||||
engine | symbol | Select: auto-config, datalog, bmc, spacer | auto-config
|
||||
generate_proof_trace | bool | trace for 'sat' answer as proof object | false
|
||||
print_aig | symbol | Dump clauses in AIG text format (AAG) to the given file name |
|
||||
print_answer | bool | print answer instance(s) to query | false
|
||||
print_boogie_certificate | bool | print certificate for reachability or non-reachability using a format understood by Boogie | false
|
||||
print_certificate | bool | print certificate for reachability or non-reachability | false
|
||||
print_fixedpoint_extensions | bool | use SMT-LIB2 fixedpoint extensions, instead of pure SMT2, when printing rules | true
|
||||
print_low_level_smt2 | bool | use (faster) low-level SMT2 printer (the printer is scalable but the result may not be as readable) | false
|
||||
print_statistics | bool | print statistics | false
|
||||
print_with_variable_declarations | bool | use variable declarations when displaying rules (instead of attempting to use original names) | true
|
||||
spacer.arith.solver | unsigned int | arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination 4 - utvpi, 5 - infinitary lra, 6 - lra solver | 2
|
||||
spacer.blast_term_ite_inflation | unsigned int | Maximum inflation for non-Boolean ite-terms expansion: 0 (none), k (multiplicative) | 3
|
||||
spacer.ctp | bool | Enable counterexample-to-pushing | true
|
||||
spacer.dump_benchmarks | bool | Dump SMT queries as benchmarks | false
|
||||
spacer.dump_threshold | double | Threshold in seconds on dumping benchmarks | 5.0
|
||||
spacer.elim_aux | bool | Eliminate auxiliary variables in reachability facts | true
|
||||
spacer.eq_prop | bool | Enable equality and bound propagation in arithmetic | true
|
||||
spacer.gpdr | bool | Use GPDR solving strategy for non-linear CHC | false
|
||||
spacer.gpdr.bfs | bool | Use BFS exploration strategy for expanding model search | true
|
||||
spacer.ground_pobs | bool | Ground pobs by using values from a model | true
|
||||
spacer.iuc | unsigned int | 0 = use old implementation of unsat-core-generation, 1 = use new implementation of IUC generation, 2 = use new implementation of IUC + min-cut optimization | 1
|
||||
spacer.iuc.arith | unsigned int | 0 = use simple Farkas plugin, 1 = use simple Farkas plugin with constant from other partition (like old unsat-core-generation),2 = use Gaussian elimination optimization (broken), 3 = use additive IUC plugin | 1
|
||||
spacer.iuc.debug_proof | bool | prints proof used by unsat-core-learner for debugging purposes (debugging) | false
|
||||
spacer.iuc.old_hyp_reducer | bool | use old hyp reducer instead of new implementation, for debugging only | false
|
||||
spacer.iuc.print_farkas_stats | bool | prints for each proof how many Farkas lemmas it contains and how many of these participate in the cut (for debugging) | false
|
||||
spacer.iuc.split_farkas_literals | bool | Split Farkas literals | false
|
||||
spacer.keep_proxy | bool | keep proxy variables (internal parameter) | true
|
||||
spacer.logic | symbol | SMT-LIB logic to configure internal SMT solvers |
|
||||
spacer.max_level | unsigned int | Maximum level to explore | 4294967295
|
||||
spacer.max_num_contexts | unsigned int | maximal number of contexts to create | 500
|
||||
spacer.mbqi | bool | Enable mbqi | true
|
||||
spacer.min_level | unsigned int | Minimal level to explore | 0
|
||||
spacer.native_mbp | bool | Use native mbp of Z3 | true
|
||||
spacer.order_children | unsigned int | SPACER: order of enqueuing children in non-linear rules : 0 (original), 1 (reverse), 2 (random) | 0
|
||||
spacer.p3.share_invariants | bool | Share invariants lemmas | false
|
||||
spacer.p3.share_lemmas | bool | Share frame lemmas | false
|
||||
spacer.print_json | symbol | Print pobs tree in JSON format to a given file |
|
||||
spacer.propagate | bool | Enable propagate/pushing phase | true
|
||||
spacer.push_pob | bool | push blocked pobs to higher level | false
|
||||
spacer.push_pob_max_depth | unsigned int | Maximum depth at which push_pob is enabled | 4294967295
|
||||
spacer.q3 | bool | Allow quantified lemmas in frames | true
|
||||
spacer.q3.instantiate | bool | Instantiate quantified lemmas | true
|
||||
spacer.q3.qgen.normalize | bool | normalize cube before quantified generalization | true
|
||||
spacer.q3.use_qgen | bool | use quantified lemma generalizer | false
|
||||
spacer.random_seed | unsigned int | Random seed to be used by SMT solver | 0
|
||||
spacer.reach_dnf | bool | Restrict reachability facts to DNF | true
|
||||
spacer.reset_pob_queue | bool | SPACER: reset pob obligation queue when entering a new level | true
|
||||
spacer.restart_initial_threshold | unsigned int | Initial threshold for restarts | 10
|
||||
spacer.restarts | bool | Enable resetting obligation queue | false
|
||||
spacer.simplify_lemmas_post | bool | simplify derived lemmas after inductive propagation | false
|
||||
spacer.simplify_lemmas_pre | bool | simplify derived lemmas before inductive propagation | false
|
||||
spacer.simplify_pob | bool | simplify pobs by removing redundant constraints | false
|
||||
spacer.trace_file | symbol | Log file for progress events |
|
||||
spacer.use_array_eq_generalizer | bool | SPACER: attempt to generalize lemmas with array equalities | true
|
||||
spacer.use_bg_invs | bool | Enable external background invariants | false
|
||||
spacer.use_derivations | bool | SPACER: using derivation mechanism to cache intermediate results for non-linear rules | true
|
||||
spacer.use_euf_gen | bool | Generalize lemmas and pobs using implied equalities | false
|
||||
spacer.use_inc_clause | bool | Use incremental clause to represent trans | true
|
||||
spacer.use_inductive_generalizer | bool | generalize lemmas using induction strengthening | true
|
||||
spacer.use_lemma_as_cti | bool | SPACER: use a lemma instead of a CTI in flexible_trace | false
|
||||
spacer.use_lim_num_gen | bool | Enable limit numbers generalizer to get smaller numbers | false
|
||||
spacer.validate_lemmas | bool | Validate each lemma after generalization | false
|
||||
spacer.weak_abs | bool | Weak abstraction | true
|
||||
tab.selection | symbol | selection method for tabular strategy: weight (default), first, var-use | weight
|
||||
validate | bool | validate result (by proof checking or model checking) | false
|
||||
xform.array_blast | bool | try to eliminate local array terms using Ackermannization -- some array terms may remain | false
|
||||
xform.array_blast_full | bool | eliminate all local array variables by QE | false
|
||||
xform.bit_blast | bool | bit-blast bit-vectors | false
|
||||
xform.coalesce_rules | bool | coalesce rules | false
|
||||
xform.coi | bool | use cone of influence simplification | true
|
||||
xform.compress_unbound | bool | compress tails with unbound variables | true
|
||||
xform.elim_term_ite | bool | Eliminate term-ite expressions | false
|
||||
xform.elim_term_ite.inflation | unsigned int | Maximum inflation for non-Boolean ite-terms blasting: 0 (none), k (multiplicative) | 3
|
||||
xform.fix_unbound_vars | bool | fix unbound variables in tail | false
|
||||
xform.inline_eager | bool | try eager inlining of rules | true
|
||||
xform.inline_linear | bool | try linear inlining method | true
|
||||
xform.inline_linear_branch | bool | try linear inlining method with potential expansion | false
|
||||
xform.instantiate_arrays | bool | Transforms P(a) into P(i, a[i] a) | false
|
||||
xform.instantiate_arrays.enforce | bool | Transforms P(a) into P(i, a[i]), discards a from predicate | false
|
||||
xform.instantiate_arrays.nb_quantifier | unsigned int | Gives the number of quantifiers per array | 1
|
||||
xform.instantiate_arrays.slice_technique | symbol | <no-slicing>=> GetId(i) = i, <smash> => GetId(i) = true | no-slicing
|
||||
xform.instantiate_quantifiers | bool | instantiate quantified Horn clauses using E-matching heuristic | false
|
||||
xform.magic | bool | perform symbolic magic set transformation | false
|
||||
xform.quantify_arrays | bool | create quantified Horn clauses from clauses with arrays | false
|
||||
xform.scale | bool | add scaling variable to linear real arithmetic clauses | false
|
||||
xform.slice | bool | simplify clause set using slicing | true
|
||||
xform.subsumption_checker | bool | Enable subsumption checker (no support for model conversion) | true
|
||||
xform.tail_simplifier_pve | bool | propagate_variable_equivalences | true
|
||||
xform.transform_arrays | bool | Rewrites arrays equalities and applies select over store | false
|
||||
xform.unfold_rules | unsigned int | unfold rules statically using iterative squaring | 0
|
||||
|
||||
## Module smt
|
||||
|
||||
Description: smt solver based on lazy smt
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
arith.auto_config_simplex | bool | force simplex solver in auto_config | false
|
||||
arith.bprop_on_pivoted_rows | bool | propagate bounds on rows changed by the pivot operation | true
|
||||
arith.branch_cut_ratio | unsigned int | branch/cut ratio for linear integer arithmetic | 2
|
||||
arith.dump_lemmas | bool | dump arithmetic theory lemmas to files | false
|
||||
arith.eager_eq_axioms | bool | eager equality axioms | true
|
||||
arith.enable_hnf | bool | enable hnf (Hermite Normal Form) cuts | true
|
||||
arith.greatest_error_pivot | bool | Pivoting strategy | false
|
||||
arith.ignore_int | bool | treat integer variables as real | false
|
||||
arith.int_eq_branch | bool | branching using derived integer equations | false
|
||||
arith.min | bool | minimize cost | false
|
||||
arith.nl | bool | (incomplete) nonlinear arithmetic support based on Groebner basis and interval propagation, relevant only if smt.arith.solver=2 | true
|
||||
arith.nl.branching | bool | branching on integer variables in non linear clusters, relevant only if smt.arith.solver=2 | true
|
||||
arith.nl.delay | unsigned int | number of calls to final check before invoking bounded nlsat check | 500
|
||||
arith.nl.expp | bool | expensive patching | false
|
||||
arith.nl.gr_q | unsigned int | grobner's quota | 10
|
||||
arith.nl.grobner | bool | run grobner's basis heuristic | true
|
||||
arith.nl.grobner_cnfl_to_report | unsigned int | grobner's maximum number of conflicts to report | 1
|
||||
arith.nl.grobner_eqs_growth | unsigned int | grobner's number of equalities growth | 10
|
||||
arith.nl.grobner_expr_degree_growth | unsigned int | grobner's maximum expr degree growth | 2
|
||||
arith.nl.grobner_expr_size_growth | unsigned int | grobner's maximum expr size growth | 2
|
||||
arith.nl.grobner_frequency | unsigned int | grobner's call frequency | 4
|
||||
arith.nl.grobner_max_simplified | unsigned int | grobner's maximum number of simplifications | 10000
|
||||
arith.nl.grobner_subs_fixed | unsigned int | 0 - no subs, 1 - substitute, 2 - substitute fixed zeros only | 1
|
||||
arith.nl.horner | bool | run horner's heuristic | true
|
||||
arith.nl.horner_frequency | unsigned int | horner's call frequency | 4
|
||||
arith.nl.horner_row_length_limit | unsigned int | row is disregarded by the heuristic if its length is longer than the value | 10
|
||||
arith.nl.horner_subs_fixed | unsigned int | 0 - no subs, 1 - substitute, 2 - substitute fixed zeros only | 2
|
||||
arith.nl.nra | bool | call nra_solver when incremental linearization does not produce a lemma, this option is ignored when arith.nl=false, relevant only if smt.arith.solver=6 | true
|
||||
arith.nl.order | bool | run order lemmas | true
|
||||
arith.nl.rounds | unsigned int | threshold for number of (nested) final checks for non linear arithmetic, relevant only if smt.arith.solver=2 | 1024
|
||||
arith.nl.tangents | bool | run tangent lemmas | true
|
||||
arith.print_ext_var_names | bool | print external variable names | false
|
||||
arith.print_stats | bool | print statistic | false
|
||||
arith.propagate_eqs | bool | propagate (cheap) equalities | true
|
||||
arith.propagation_mode | unsigned int | 0 - no propagation, 1 - propagate existing literals, 2 - refine finite bounds | 1
|
||||
arith.random_initial_value | bool | use random initial values in the simplex-based procedure for linear arithmetic | false
|
||||
arith.rep_freq | unsigned int | the report frequency, in how many iterations print the cost and other info | 0
|
||||
arith.simplex_strategy | unsigned int | simplex strategy for the solver | 0
|
||||
arith.solver | unsigned int | arithmetic solver: 0 - no solver, 1 - bellman-ford based solver (diff. logic only), 2 - simplex based solver, 3 - floyd-warshall based solver (diff. logic only) and no theory combination 4 - utvpi, 5 - infinitary lra, 6 - lra solver | 6
|
||||
array.extensional | bool | extensional array theory | true
|
||||
array.weak | bool | weak array theory | false
|
||||
auto_config | bool | automatically configure solver | true
|
||||
bv.delay | bool | delay internalize expensive bit-vector operations | true
|
||||
bv.enable_int2bv | bool | enable support for int2bv and bv2int operators | true
|
||||
bv.eq_axioms | bool | enable redundant equality axioms for bit-vectors | true
|
||||
bv.reflect | bool | create enode for every bit-vector term | true
|
||||
bv.watch_diseq | bool | use watch lists instead of eager axioms for bit-vectors | false
|
||||
candidate_models | bool | create candidate models even when quantifier or theory reasoning is incomplete | false
|
||||
case_split | unsigned int | 0 - case split based on variable activity, 1 - similar to 0, but delay case splits created during the search, 2 - similar to 0, but cache the relevancy, 3 - case split based on relevancy (structural splitting), 4 - case split on relevancy and activity, 5 - case split on relevancy and current goal, 6 - activity-based case split with theory-aware branching activity | 1
|
||||
clause_proof | bool | record a clausal proof | false
|
||||
core.extend_nonlocal_patterns | bool | extend unsat cores with literals that have quantifiers with patterns that contain symbols which are not in the quantifier's body | false
|
||||
core.extend_patterns | bool | extend unsat core with literals that trigger (potential) quantifier instances | false
|
||||
core.extend_patterns.max_distance | unsigned int | limits the distance of a pattern-extended unsat core | 4294967295
|
||||
core.minimize | bool | minimize unsat core produced by SMT context | false
|
||||
core.validate | bool | [internal] validate unsat core produced by SMT context. This option is intended for debugging | false
|
||||
cube_depth | unsigned int | cube depth. | 1
|
||||
dack | unsigned int | 0 - disable dynamic ackermannization, 1 - expand Leibniz's axiom if a congruence is the root of a conflict, 2 - expand Leibniz's axiom if a congruence is used during conflict resolution | 1
|
||||
dack.eq | bool | enable dynamic ackermannization for transtivity of equalities | false
|
||||
dack.factor | double | number of instance per conflict | 0.1
|
||||
dack.gc | unsigned int | Dynamic ackermannization garbage collection frequency (per conflict) | 2000
|
||||
dack.gc_inv_decay | double | Dynamic ackermannization garbage collection decay | 0.8
|
||||
dack.threshold | unsigned int | number of times the congruence rule must be used before Leibniz's axiom is expanded | 10
|
||||
delay_units | bool | if true then z3 will not restart when a unit clause is learned | false
|
||||
delay_units_threshold | unsigned int | maximum number of learned unit clauses before restarting, ignored if delay_units is false | 32
|
||||
dt_lazy_splits | unsigned int | How lazy datatype splits are performed: 0- eager, 1- lazy for infinite types, 2- lazy | 1
|
||||
ematching | bool | E-Matching based quantifier instantiation | true
|
||||
induction | bool | enable generation of induction lemmas | false
|
||||
lemma_gc_strategy | unsigned int | lemma garbage collection strategy: 0 - fixed, 1 - geometric, 2 - at restart, 3 - none | 0
|
||||
logic | symbol | logic used to setup the SMT solver |
|
||||
macro_finder | bool | try to find universally quantified formulas that can be viewed as macros | false
|
||||
max_conflicts | unsigned int | maximum number of conflicts before giving up. | 4294967295
|
||||
mbqi | bool | model based quantifier instantiation (MBQI) | true
|
||||
mbqi.force_template | unsigned int | some quantifiers can be used as templates for building interpretations for functions. Z3 uses heuristics to decide whether a quantifier will be used as a template or not. Quantifiers with weight >= mbqi.force_template are forced to be used as a template | 10
|
||||
mbqi.id | string | Only use model-based instantiation for quantifiers with id's beginning with string |
|
||||
mbqi.max_cexs | unsigned int | initial maximal number of counterexamples used in MBQI, each counterexample generates a quantifier instantiation | 1
|
||||
mbqi.max_cexs_incr | unsigned int | increment for MBQI_MAX_CEXS, the increment is performed after each round of MBQI | 0
|
||||
mbqi.max_iterations | unsigned int | maximum number of rounds of MBQI | 1000
|
||||
mbqi.trace | bool | generate tracing messages for Model Based Quantifier Instantiation (MBQI). It will display a message before every round of MBQI, and the quantifiers that were not satisfied | false
|
||||
pb.conflict_frequency | unsigned int | conflict frequency for Pseudo-Boolean theory | 1000
|
||||
pb.learn_complements | bool | learn complement literals for Pseudo-Boolean theory | true
|
||||
phase_caching_off | unsigned int | number of conflicts while phase caching is off | 100
|
||||
phase_caching_on | unsigned int | number of conflicts while phase caching is on | 400
|
||||
phase_selection | unsigned int | phase selection heuristic: 0 - always false, 1 - always true, 2 - phase caching, 3 - phase caching conservative, 4 - phase caching conservative 2, 5 - random, 6 - number of occurrences, 7 - theory | 3
|
||||
pull_nested_quantifiers | bool | pull nested quantifiers | false
|
||||
q.lift_ite | unsigned int | 0 - don not lift non-ground if-then-else, 1 - use conservative ite lifting, 2 - use full lifting of if-then-else under quantifiers | 0
|
||||
q.lite | bool | Use cheap quantifier elimination during pre-processing | false
|
||||
qi.cost | string | expression specifying what is the cost of a given quantifier instantiation | (+ weight generation)
|
||||
qi.eager_threshold | double | threshold for eager quantifier instantiation | 10.0
|
||||
qi.lazy_threshold | double | threshold for lazy quantifier instantiation | 20.0
|
||||
qi.max_instances | unsigned int | maximum number of quantifier instantiations | 4294967295
|
||||
qi.max_multi_patterns | unsigned int | specify the number of extra multi patterns | 0
|
||||
qi.profile | bool | profile quantifier instantiation | false
|
||||
qi.profile_freq | unsigned int | how frequent results are reported by qi.profile | 4294967295
|
||||
qi.quick_checker | unsigned int | specify quick checker mode, 0 - no quick checker, 1 - using unsat instances, 2 - using both unsat and no-sat instances | 0
|
||||
quasi_macros | bool | try to find universally quantified formulas that are quasi-macros | false
|
||||
random_seed | unsigned int | random seed for the smt solver | 0
|
||||
refine_inj_axioms | bool | refine injectivity axioms | true
|
||||
relevancy | unsigned int | relevancy propagation heuristic: 0 - disabled, 1 - relevancy is tracked by only affects quantifier instantiation, 2 - relevancy is tracked, and an atom is only asserted if it is relevant | 2
|
||||
restart.max | unsigned int | maximal number of restarts. | 4294967295
|
||||
restart_factor | double | when using geometric (or inner-outer-geometric) progression of restarts, it specifies the constant used to multiply the current restart threshold | 1.1
|
||||
restart_strategy | unsigned int | 0 - geometric, 1 - inner-outer-geometric, 2 - luby, 3 - fixed, 4 - arithmetic | 1
|
||||
restricted_quasi_macros | bool | try to find universally quantified formulas that are restricted quasi-macros | false
|
||||
seq.max_unfolding | unsigned int | maximal unfolding depth for checking string equations and regular expressions | 1000000000
|
||||
seq.split_w_len | bool | enable splitting guided by length constraints | true
|
||||
seq.validate | bool | enable self-validation of theory axioms created by seq theory | false
|
||||
str.aggressive_length_testing | bool | prioritize testing concrete length values over generating more options | false
|
||||
str.aggressive_unroll_testing | bool | prioritize testing concrete regex unroll counts over generating more options | true
|
||||
str.aggressive_value_testing | bool | prioritize testing concrete string constant values over generating more options | false
|
||||
str.fast_length_tester_cache | bool | cache length tester constants instead of regenerating them | false
|
||||
str.fast_value_tester_cache | bool | cache value tester constants instead of regenerating them | true
|
||||
str.fixed_length_naive_cex | bool | construct naive counterexamples when fixed-length model construction fails for a given length assignment (Z3str3 only) | true
|
||||
str.fixed_length_refinement | bool | use abstraction refinement in fixed-length equation solver (Z3str3 only) | false
|
||||
str.overlap_priority | double | theory-aware priority for overlapping variable cases; use smt.theory_aware_branching=true | -0.1
|
||||
str.regex_automata_difficulty_threshold | unsigned int | difficulty threshold for regex automata heuristics | 1000
|
||||
str.regex_automata_failed_automaton_threshold | unsigned int | number of failed automaton construction attempts after which a full automaton is automatically built | 10
|
||||
str.regex_automata_failed_intersection_threshold | unsigned int | number of failed automaton intersection attempts after which intersection is always computed | 10
|
||||
str.regex_automata_intersection_difficulty_threshold | unsigned int | difficulty threshold for regex intersection heuristics | 1000
|
||||
str.regex_automata_length_attempt_threshold | unsigned int | number of length/path constraint attempts before checking unsatisfiability of regex terms | 10
|
||||
str.string_constant_cache | bool | cache all generated string constants generated from anywhere in theory_str | true
|
||||
str.strong_arrangements | bool | assert equivalences instead of implications when generating string arrangement axioms | true
|
||||
string_solver | symbol | solver for string/sequence theories. options are: 'z3str3' (specialized string solver), 'seq' (sequence solver), 'auto' (use static features to choose best solver), 'empty' (a no-op solver that forces an answer unknown if strings were used), 'none' (no solver) | seq
|
||||
theory_aware_branching | bool | Allow the context to use extra information from theory solvers regarding literal branching prioritization. | false
|
||||
theory_case_split | bool | Allow the context to use heuristics involving theory case splits, which are a set of literals of which exactly one can be assigned True. If this option is false, the context will generate extra axioms to enforce this instead. | false
|
||||
threads | unsigned int | maximal number of parallel threads. | 1
|
||||
threads.cube_frequency | unsigned int | frequency for using cubing | 2
|
||||
threads.max_conflicts | unsigned int | maximal number of conflicts between rounds of cubing for parallel SMT | 400
|
||||
|
||||
## Module sls
|
||||
|
||||
Description: Experimental Stochastic Local Search Solver (for QFBV only).
|
||||
Parameter | Type | Description | Default
|
||||
----------|------|-------------|--------
|
||||
early_prune | bool | use early pruning for score prediction | true
|
||||
max_memory | unsigned int | maximum amount of memory in megabytes | 4294967295
|
||||
max_restarts | unsigned int | maximum number of restarts | 4294967295
|
||||
paws_init | unsigned int | initial/minimum assertion weights | 40
|
||||
paws_sp | unsigned int | smooth assertion weights with probability paws_sp / 1024 | 52
|
||||
random_offset | bool | use random offset for candidate evaluation | true
|
||||
random_seed | unsigned int | random seed | 0
|
||||
rescore | bool | rescore/normalize top-level score every base restart interval | true
|
||||
restart_base | unsigned int | base restart interval given by moves per run | 100
|
||||
restart_init | bool | initialize to 0 or random value (= 1) after restart | false
|
||||
scale_unsat | double | scale score of unsat expressions by this factor | 0.5
|
||||
track_unsat | bool | keep a list of unsat assertions as done in SAT - currently disabled internally | false
|
||||
vns_mc | unsigned int | in local minima, try Monte Carlo sampling vns_mc many 2-bit-flips per bit | 0
|
||||
vns_repick | bool | in local minima, try picking a different assertion (only for walksat) | false
|
||||
walksat | bool | use walksat assertion selection (instead of gsat) | true
|
||||
walksat_repick | bool | repick assertion if randomizing in local minima | true
|
||||
walksat_ucb | bool | use bandit heuristic for walksat assertion selection (instead of random) | true
|
||||
walksat_ucb_constant | double | the ucb constant c in the term score + c * f(touched) | 20.0
|
||||
walksat_ucb_forget | double | scale touched by this factor every base restart interval | 1.0
|
||||
walksat_ucb_init | bool | initialize total ucb touched to formula size | false
|
||||
walksat_ucb_noise | double | add noise 0 <= 256 * ucb_noise to ucb score for assertion selection | 0.0002
|
||||
wp | unsigned int | random walk with probability wp / 1024 | 100
|
13
README.md
13
README.md
|
@ -105,6 +105,19 @@ Z3 has a build system using CMake. Read the [README-CMake.md](README-CMake.md)
|
|||
file for details. It is recommended for most build tasks,
|
||||
except for building OCaml bindings.
|
||||
|
||||
## Building Z3 using vcpkg
|
||||
|
||||
vcpkg is a full platform package manager, you can easily install libzmq with vcpkg.
|
||||
|
||||
Execute:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/microsoft/vcpkg.git
|
||||
./bootstrap-vcpkg.bat # For powershell
|
||||
./bootstrap-vcpkg.sh # For bash
|
||||
./vcpkg install z3
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
Z3 itself has few dependencies. It uses C++ runtime libraries, including pthreads for multi-threading.
|
||||
It is optionally possible to use GMP for multi-precision integers, but Z3 contains its own self-contained
|
||||
|
|
|
@ -10,9 +10,48 @@ Version 4.next
|
|||
- native word level bit-vector solving.
|
||||
- introduction of simple induction lemmas to handle a limited repertoire of induction proofs.
|
||||
|
||||
Version 4.11.2
|
||||
==============
|
||||
- add error handling to fromString method in JavaScript
|
||||
- fix regression in default parameters for CDCL, thanks to Nuno Lopes
|
||||
- fix model evaluation bugs for as-array nested under functions (data-type constructors)
|
||||
- add rewrite simplifications for datatypes with a single constructor
|
||||
- add "Global Guidance" capability to SPACER, thanks to Arie Gurfinkel and Hari Gorvind.
|
||||
The commit logs related to Global Guidance contain detailed information.
|
||||
- change proof logging format for the new core to use SMTLIB commands.
|
||||
The format was so far an extension of DRAT used by SAT solvers, but not well compatible
|
||||
with SMT format that is extensible. The resulting format is a mild extension of SMTLIB with
|
||||
three extra commands assume, learn, del. They track input clauses, generated clauses and deleted clauses.
|
||||
They are optionally augmented by proof hints. Two proof hints are used in the current version: "rup" and "farkas".
|
||||
"rup" is used whent the generated clause can be justified by reverse unit propagation. "farkas" is used when
|
||||
the clause can be justified by a combination of Farkas cutting planes. There is a built-in proof checker for the
|
||||
format. Quantifier instantiations are also tracked as proof hints.
|
||||
Other proof hints are to be added as the feature set is tested and developed. The fallback, buit-in,
|
||||
self-checker uses z3 to check that the generated clause is a consequence. Note that this is generally
|
||||
insufficient as generated clauses are in principle required to only be satisfiability preserving.
|
||||
Proof checking and tranformation operations is overall open ended.
|
||||
The log for the first commit introducing this change contains further information on the format.
|
||||
- fix to re-entrancy bug in user propagator (thanks to Clemens Eisenhofer).
|
||||
- handle _toExpr for quantified formulas in JS bindings
|
||||
|
||||
Version 4.11.1
|
||||
==============
|
||||
- skipped
|
||||
|
||||
Version 4.11.0
|
||||
==============
|
||||
- remove `Z3_bool`, `Z3_TRUE`, `Z3_FALSE` from the API. Use `bool`, `true`, `false` instead.
|
||||
- z3++.h no longer includes `<sstream>` as it did not use it.
|
||||
- add solver.axioms2files
|
||||
- prints negated theory axioms to files. Each file should be unsat
|
||||
- add solver.lemmas2console
|
||||
- prints lemmas to the console.
|
||||
- remove option smt.arith.dump_lemmas. It is replaced by solver.axioms2files
|
||||
- add option smt.bv.reduce_size.
|
||||
- it allows to apply incremental pre-processing of bit-vectors by identifying ranges that are known to be constant.
|
||||
This rewrite is beneficial, for instance, when bit-vectors are constrained to have many high-level bits set to 0.
|
||||
- add feature to model-based projection for arithmetic to handle integer division.
|
||||
- add fromString method to JavaScript solver object.
|
||||
|
||||
Version 4.10.2
|
||||
==============
|
||||
|
|
|
@ -21,7 +21,7 @@ jobs:
|
|||
- job: "LinuxPythonDebug"
|
||||
displayName: "Ubuntu build - python make - debug"
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
strategy:
|
||||
matrix:
|
||||
MT:
|
||||
|
@ -102,7 +102,7 @@ jobs:
|
|||
displayName: "Ubuntu build - cmake"
|
||||
condition: eq(0,1)
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
strategy:
|
||||
matrix:
|
||||
msanClang:
|
||||
|
@ -135,7 +135,7 @@ jobs:
|
|||
- job: "UbuntuCMake"
|
||||
displayName: "Ubuntu build - cmake"
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
strategy:
|
||||
matrix:
|
||||
releaseClang:
|
||||
|
|
|
@ -24,6 +24,7 @@ JS_API_PATH='../src/api/js'
|
|||
Z3PY_ENABLED=True
|
||||
DOTNET_ENABLED=True
|
||||
JAVA_ENABLED=True
|
||||
Z3OPTIONS_ENABLED=True
|
||||
DOTNET_API_SEARCH_PATHS=['../src/api/dotnet']
|
||||
JAVA_API_SEARCH_PATHS=['../src/api/java']
|
||||
SCRIPT_DIR=os.path.abspath(os.path.dirname(__file__))
|
||||
|
@ -237,6 +238,7 @@ try:
|
|||
else:
|
||||
print('Javascript documentation disabled')
|
||||
|
||||
|
||||
doxygen_config_file = temp_path('z3api.cfg')
|
||||
configure_file(
|
||||
doc_path('z3api.cfg.in'),
|
||||
|
|
64
doc/mk_params_doc.py
Normal file
64
doc/mk_params_doc.py
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Copyright (c) Microsoft Corporation 2015
|
||||
"""
|
||||
Z3 API documentation for parameters
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
BUILD_DIR='../build'
|
||||
OUTPUT_DIRECTORY=os.path.join(os.getcwd(), 'api')
|
||||
|
||||
def parse_options():
|
||||
global BUILD_DIR, OUTPUT_DIRECTORY
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('-b',
|
||||
'--build',
|
||||
default=BUILD_DIR,
|
||||
help='Directory where Z3 is built (default: %(default)s)',
|
||||
)
|
||||
parser.add_argument('--output-dir',
|
||||
dest='output_dir',
|
||||
default=OUTPUT_DIRECTORY,
|
||||
help='Path to output directory (default: %(default)s)',
|
||||
)
|
||||
|
||||
pargs = parser.parse_args()
|
||||
BUILD_DIR = pargs.build
|
||||
OUTPUT_DIRECTORY = pargs.output_dir
|
||||
|
||||
def help(ous):
|
||||
global BUILD_DIR
|
||||
ous.write("Z3 Options\n")
|
||||
z3_exe = BUILD_DIR + "/z3"
|
||||
out = subprocess.Popen([z3_exe, "-pm"],stdout=subprocess.PIPE).communicate()[0]
|
||||
modules = ["global"]
|
||||
if out != None:
|
||||
out = out.decode(sys.stdout.encoding)
|
||||
module_re = re.compile(r"\[module\] (.*)\,")
|
||||
lines = out.split("\n")
|
||||
for line in lines:
|
||||
m = module_re.search(line)
|
||||
if m:
|
||||
modules += [m.group(1)]
|
||||
for module in modules:
|
||||
out = subprocess.Popen([z3_exe, "-pmmd:%s" % module],stdout=subprocess.PIPE).communicate()[0]
|
||||
if out == None:
|
||||
continue
|
||||
out = out.decode(sys.stdout.encoding)
|
||||
out = out.replace("\r","")
|
||||
ous.write(out)
|
||||
|
||||
parse_options()
|
||||
|
||||
def mk_dir(d):
|
||||
if not os.path.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
mk_dir(os.path.join(OUTPUT_DIRECTORY, 'md'))
|
||||
|
||||
with open(OUTPUT_DIRECTORY + "/md/Parameters.md",'w') as ous:
|
||||
help(ous)
|
|
@ -5,6 +5,7 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
--*/
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include<vector>
|
||||
#include"z3++.h"
|
||||
|
||||
|
|
|
@ -2946,6 +2946,28 @@ void mk_model_example() {
|
|||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
void divides_example()
|
||||
{
|
||||
Z3_context ctx;
|
||||
Z3_solver s;
|
||||
Z3_ast x, number;
|
||||
Z3_ast c;
|
||||
|
||||
ctx = mk_context();
|
||||
s = mk_solver(ctx);
|
||||
|
||||
x = mk_int_var(ctx, "x");
|
||||
number = mk_int(ctx, 2);
|
||||
|
||||
c = Z3_mk_divides(ctx, number, x);
|
||||
Z3_solver_assert(ctx, s, c);
|
||||
|
||||
check2(ctx, s, Z3_L_TRUE);
|
||||
|
||||
del_solver(ctx, s);
|
||||
Z3_del_context(ctx);
|
||||
}
|
||||
|
||||
/**@}*/
|
||||
/**@}*/
|
||||
|
||||
|
@ -2955,6 +2977,7 @@ int main() {
|
|||
#ifdef LOG_Z3_CALLS
|
||||
Z3_open_log("z3.log");
|
||||
#endif
|
||||
divides_example();
|
||||
display_version();
|
||||
simple_example();
|
||||
demorgan();
|
||||
|
|
83
examples/python/simplify_formula.py
Normal file
83
examples/python/simplify_formula.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
from z3 import *
|
||||
|
||||
def is_atom(t):
|
||||
if not is_bool(t):
|
||||
return False
|
||||
if not is_app(t):
|
||||
return False
|
||||
k = t.decl().kind()
|
||||
if k == Z3_OP_AND or k == Z3_OP_OR or k == Z3_OP_IMPLIES:
|
||||
return False
|
||||
if k == Z3_OP_EQ and t.arg(0).is_bool():
|
||||
return False
|
||||
if k == Z3_OP_TRUE or k == Z3_OP_FALSE or k == Z3_OP_XOR or k == Z3_OP_NOT:
|
||||
return False
|
||||
return True
|
||||
|
||||
def atoms(fml):
|
||||
visited = set([])
|
||||
atms = set([])
|
||||
def atoms_rec(t, visited, atms):
|
||||
if t in visited:
|
||||
return
|
||||
visited |= { t }
|
||||
if is_atom(t):
|
||||
atms |= { t }
|
||||
for s in t.children():
|
||||
atoms_rec(s, visited, atms)
|
||||
atoms_rec(fml, visited, atms)
|
||||
return atms
|
||||
|
||||
def atom2literal(m, a):
|
||||
if is_true(m.eval(a)):
|
||||
return a
|
||||
return Not(a)
|
||||
|
||||
# Extract subset of atoms used to satisfy the negation
|
||||
# of a formula.
|
||||
# snot is a solver for Not(fml)
|
||||
# s is a solver for fml
|
||||
# m is a model for Not(fml)
|
||||
# evaluate each atom in fml using m and create
|
||||
# literals corresponding to the sign of the evaluation.
|
||||
# If the model evaluates atoms to false, the literal is
|
||||
# negated.
|
||||
#
|
||||
#
|
||||
def implicant(atoms, s, snot):
|
||||
m = snot.model()
|
||||
lits = [atom2literal(m, a) for a in atoms]
|
||||
is_sat = s.check(lits)
|
||||
assert is_sat == unsat
|
||||
core = s.unsat_core()
|
||||
return Or([mk_not(c) for c in core])
|
||||
|
||||
#
|
||||
# Extract a CNF representation of fml
|
||||
# The procedure uses two solvers
|
||||
# Enumerate models for Not(fml)
|
||||
# Use the enumerated model to identify literals
|
||||
# that imply Not(fml)
|
||||
# The CNF of fml is a conjunction of the
|
||||
# negation of these literals.
|
||||
#
|
||||
|
||||
def to_cnf(fml):
|
||||
atms = atoms(fml)
|
||||
s = Solver()
|
||||
snot = Solver()
|
||||
snot.add(Not(fml))
|
||||
s.add(fml)
|
||||
|
||||
while sat == snot.check():
|
||||
clause = implicant(atms, s, snot)
|
||||
yield clause
|
||||
snot.add(clause)
|
||||
|
||||
|
||||
a, b, c, = Bools('a b c')
|
||||
fml = Or(And(a, b), And(Not(a), c))
|
||||
|
||||
for clause in to_cnf(fml):
|
||||
print(clause)
|
||||
|
|
@ -15,6 +15,7 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
#include <string.h>
|
||||
#include <cstdlib>
|
||||
#include "z3++.h"
|
||||
|
|
|
@ -15,9 +15,9 @@ find_package(Z3
|
|||
)
|
||||
|
||||
################################################################################
|
||||
# Z3 C++ API bindings require C++11
|
||||
# Z3 C++ API bindings require C++11, but this code needs later.
|
||||
################################################################################
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
message(STATUS "Z3_FOUND: ${Z3_FOUND}")
|
||||
|
|
|
@ -22,6 +22,22 @@ jobs:
|
|||
python scripts\mk_win_dist.py
|
||||
--${{parameters.BuildArchitecture}}-only
|
||||
--dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Collect Symbols'
|
||||
inputs:
|
||||
sourceFolder: dist
|
||||
contents: '**/*.pdb'
|
||||
targetFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
# Publish symbol archive to match nuget package
|
||||
# Index your source code and publish symbols to a file share or Azure Artifacts symbol server
|
||||
- task: PublishSymbols@2
|
||||
inputs:
|
||||
symbolsFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
searchPattern: '**/*.pdb'
|
||||
indexSources: false # Github sources not supported
|
||||
publishSymbols: true
|
||||
symbolServerType: TeamServices
|
||||
detailedLog: true
|
||||
- task: EsrpCodeSigning@1
|
||||
displayName: Sign
|
||||
inputs:
|
||||
|
|
|
@ -12,7 +12,7 @@ stages:
|
|||
- job: UbuntuDoc
|
||||
displayName: "Ubuntu Doc build"
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
# TODO setup emscripten with no-install, then run
|
||||
- script: npm --prefix=src/api/js ci
|
||||
|
|
|
@ -886,8 +886,7 @@ def mk_hpp_from_pyg(pyg_file, output_dir):
|
|||
hpp = os.path.join(dirname, '%s.hpp' % class_name)
|
||||
out = open(hpp, 'w')
|
||||
out.write('// Automatically generated file\n')
|
||||
out.write('#ifndef __%s_HPP_\n' % class_name.upper())
|
||||
out.write('#define __%s_HPP_\n' % class_name.upper())
|
||||
out.write('#pragma once\n')
|
||||
out.write('#include "util/params.h"\n')
|
||||
if export:
|
||||
out.write('#include "util/gparams.h"\n')
|
||||
|
@ -919,7 +918,6 @@ def mk_hpp_from_pyg(pyg_file, output_dir):
|
|||
out.write(' %s %s() const { return p.%s("%s", %s); }\n' %
|
||||
(TYPE2CTYPE[param[1]], to_c_method(param[0]), TYPE2GETTER[param[1]], param[0], pyg_default_as_c_literal(param)))
|
||||
out.write('};\n')
|
||||
out.write('#endif\n')
|
||||
out.close()
|
||||
OUTPUT_HPP_FILE.append(hpp)
|
||||
|
||||
|
|
|
@ -21,7 +21,8 @@ def mk_dir(d):
|
|||
if not os.path.exists(d):
|
||||
os.makedirs(d)
|
||||
|
||||
os_info = { 'ubuntu-18' : ('so', 'linux-x64'),
|
||||
os_info = { 'ubuntu-latest' : ('so', 'linux-x64'),
|
||||
'ubuntu-18' : ('so', 'linux-x64'),
|
||||
'ubuntu-20' : ('so', 'linux-x64'),
|
||||
'glibc-2.31' : ('so', 'linux-x64'),
|
||||
'x64-win' : ('dll', 'win-x64'),
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
from mk_util import *
|
||||
|
||||
def init_version():
|
||||
set_version(4, 11, 0, 0)
|
||||
set_version(4, 11, 3, 0) # express a default build version or pick up ci build version
|
||||
|
||||
# Z3 Project definition
|
||||
def init_project_def():
|
||||
|
@ -27,7 +27,7 @@ def init_project_def():
|
|||
add_lib('params', ['util'])
|
||||
add_lib('smt_params', ['params'], 'smt/params')
|
||||
add_lib('grobner', ['ast', 'dd', 'simplex'], 'math/grobner')
|
||||
add_lib('sat', ['util', 'dd', 'grobner'])
|
||||
add_lib('sat', ['params', 'util', 'dd', 'grobner'])
|
||||
add_lib('nlsat', ['polynomial', 'sat'])
|
||||
add_lib('lp', ['util', 'nlsat', 'grobner', 'interval', 'smt_params'], 'math/lp')
|
||||
add_lib('rewriter', ['ast', 'polynomial', 'automata', 'params'], 'ast/rewriter')
|
||||
|
@ -38,7 +38,7 @@ def init_project_def():
|
|||
add_lib('substitution', ['ast', 'rewriter'], 'ast/substitution')
|
||||
add_lib('parser_util', ['ast'], 'parsers/util')
|
||||
add_lib('proofs', ['rewriter', 'util'], 'ast/proofs')
|
||||
add_lib('solver', ['model', 'tactic', 'proofs'])
|
||||
add_lib('solver', ['params', 'model', 'tactic', 'proofs'])
|
||||
add_lib('cmd_context', ['solver', 'rewriter', 'params'])
|
||||
add_lib('smt2parser', ['cmd_context', 'parser_util'], 'parsers/smt2')
|
||||
add_lib('pattern', ['normal_forms', 'smt2parser', 'rewriter'], 'ast/pattern')
|
||||
|
@ -87,7 +87,7 @@ def init_project_def():
|
|||
API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_fpa.h', 'z3_spacer.h']
|
||||
add_lib('api', ['portfolio', 'realclosure', 'opt'],
|
||||
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
|
||||
add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'qe', 'arith_tactics'], 'cmd_context/extra_cmds')
|
||||
add_lib('extra_cmds', ['cmd_context', 'subpaving_tactic', 'qe', 'euf', 'arith_tactics'], 'cmd_context/extra_cmds')
|
||||
add_exe('shell', ['api', 'sat', 'extra_cmds', 'opt'], exe_name='z3')
|
||||
add_exe('test', ['polysat','api', 'fuzzing', 'simplex', 'sat_smt'], exe_name='test-z3', install=False)
|
||||
_libz3Component = add_dll('api_dll', ['api', 'sat', 'extra_cmds'], 'api/dll',
|
||||
|
|
|
@ -91,6 +91,7 @@ TRACE = False
|
|||
PYTHON_ENABLED=False
|
||||
DOTNET_CORE_ENABLED=False
|
||||
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
|
||||
ASSEMBLY_VERSION=getenv("Z2_ASSEMBLY_VERSION", None)
|
||||
JAVA_ENABLED=False
|
||||
ML_ENABLED=False
|
||||
PYTHON_INSTALL_ENABLED=False
|
||||
|
@ -540,15 +541,33 @@ def find_c_compiler():
|
|||
raise MKException('C compiler was not found. Try to set the environment variable CC with the C compiler available in your system.')
|
||||
|
||||
def set_version(major, minor, build, revision):
|
||||
global VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK, GIT_DESCRIBE
|
||||
global ASSEMBLY_VERSION, VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK, GIT_DESCRIBE
|
||||
|
||||
# We need to give the assembly a build specific version
|
||||
# global version overrides local default expression
|
||||
if ASSEMBLY_VERSION is not None:
|
||||
versionSplits = ASSEMBLY_VERSION.split('.')
|
||||
if len(versionSplits) > 3:
|
||||
VER_MAJOR = versionSplits[0]
|
||||
VER_MINOR = versionSplits[1]
|
||||
VER_BUILD = versionSplits[2]
|
||||
VER_TWEAK = versionSplits[3]
|
||||
print("Set Assembly Version (BUILD):", VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK)
|
||||
return
|
||||
|
||||
# use parameters to set up version if not provided by script args
|
||||
VER_MAJOR = major
|
||||
VER_MINOR = minor
|
||||
VER_BUILD = build
|
||||
VER_TWEAK = revision
|
||||
|
||||
# update VER_TWEAK base on github
|
||||
if GIT_DESCRIBE:
|
||||
branch = check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD'])
|
||||
VER_TWEAK = int(check_output(['git', 'rev-list', '--count', 'HEAD']))
|
||||
|
||||
|
||||
print("Set Assembly Version (DEFAULT):", VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK)
|
||||
|
||||
def get_version():
|
||||
return (VER_MAJOR, VER_MINOR, VER_BUILD, VER_TWEAK)
|
||||
|
||||
|
@ -666,6 +685,7 @@ def display_help(exit_code):
|
|||
print(" --optimize generate optimized code during linking.")
|
||||
print(" --dotnet generate .NET platform bindings.")
|
||||
print(" --dotnet-key=<file> sign the .NET assembly using the private key in <file>.")
|
||||
print(" --assembly-version=<x.x.x.x> provide version number for build")
|
||||
print(" --java generate Java bindings.")
|
||||
print(" --ml generate OCaml bindings.")
|
||||
print(" --js generate JScript bindings.")
|
||||
|
@ -700,14 +720,14 @@ def display_help(exit_code):
|
|||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
|
||||
global DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
|
||||
global DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, ASSEMBLY_VERSION, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
|
||||
global LINUX_X64, SLOW_OPTIMIZE, LOG_SYNC, SINGLE_THREADED
|
||||
global GUARD_CF, ALWAYS_DYNAMIC_BASE, IS_ARCH_ARM64
|
||||
try:
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:],
|
||||
'b:df:sxa:hmcvtnp:gj',
|
||||
['build=', 'debug', 'silent', 'x64', 'arm64=', 'help', 'makefiles', 'showcpp', 'vsproj', 'guardcf',
|
||||
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof', 'js',
|
||||
'trace', 'dotnet', 'dotnet-key=', 'assembly-version=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof', 'js',
|
||||
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'pypkgdir=', 'python', 'staticbin', 'log-sync', 'single-threaded'])
|
||||
except:
|
||||
print("ERROR: Invalid command line option")
|
||||
|
@ -745,6 +765,8 @@ def parse_options():
|
|||
DOTNET_CORE_ENABLED = True
|
||||
elif opt in ('--dotnet-key'):
|
||||
DOTNET_KEY_FILE = arg
|
||||
elif opt in ('--assembly-version'):
|
||||
ASSEMBLY_VERSION = arg
|
||||
elif opt in ('--staticlib'):
|
||||
STATIC_LIB = True
|
||||
elif opt in ('--staticbin'):
|
||||
|
@ -1694,7 +1716,9 @@ class DotNetDLLComponent(Component):
|
|||
key = "<AssemblyOriginatorKeyFile>%s</AssemblyOriginatorKeyFile>" % self.key_file
|
||||
key += "\n<SignAssembly>true</SignAssembly>"
|
||||
|
||||
version = get_version_string(3)
|
||||
version = get_version_string(4)
|
||||
|
||||
print("Version output to csproj:", version)
|
||||
|
||||
core_csproj_str = """<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
|
@ -1702,7 +1726,7 @@ class DotNetDLLComponent(Component):
|
|||
<TargetFramework>netstandard1.4</TargetFramework>
|
||||
<LangVersion>8.0</LangVersion>
|
||||
<DefineConstants>$(DefineConstants);DOTNET_CORE</DefineConstants>
|
||||
<DebugType>portable</DebugType>
|
||||
<DebugType>full</DebugType>
|
||||
<AssemblyName>Microsoft.Z3</AssemblyName>
|
||||
<OutputType>Library</OutputType>
|
||||
<PackageId>Microsoft.Z3</PackageId>
|
||||
|
@ -2826,6 +2850,9 @@ def update_version():
|
|||
minor = VER_MINOR
|
||||
build = VER_BUILD
|
||||
revision = VER_TWEAK
|
||||
|
||||
print("UpdateVersion:", get_full_version_string(major, minor, build, revision))
|
||||
|
||||
if major is None or minor is None or build is None or revision is None:
|
||||
raise MKException("set_version(major, minor, build, revision) must be used before invoking update_version()")
|
||||
if not ONLY_MAKEFILES:
|
||||
|
|
|
@ -24,6 +24,7 @@ BUILD_X86_DIR=os.path.join('build-dist', 'x86')
|
|||
VERBOSE=True
|
||||
DIST_DIR='dist'
|
||||
FORCE_MK=False
|
||||
ASSEMBLY_VERSION=None
|
||||
DOTNET_CORE_ENABLED=True
|
||||
DOTNET_KEY_FILE=None
|
||||
JAVA_ENABLED=True
|
||||
|
@ -62,6 +63,7 @@ def display_help():
|
|||
print(" -s, --silent do not print verbose messages.")
|
||||
print(" -b <sudir>, --build=<subdir> subdirectory where x86 and x64 Z3 versions will be built (default: build-dist).")
|
||||
print(" -f, --force force script to regenerate Makefiles.")
|
||||
print(" --assembly-version assembly version for dll")
|
||||
print(" --nodotnet do not include .NET bindings in the binary distribution files.")
|
||||
print(" --dotnet-key=<file> strongname sign the .NET assembly with the private key in <file>.")
|
||||
print(" --nojava do not include Java bindings in the binary distribution files.")
|
||||
|
@ -74,7 +76,7 @@ def display_help():
|
|||
|
||||
# Parse configuration option for mk_make script
|
||||
def parse_options():
|
||||
global FORCE_MK, JAVA_ENABLED, ZIP_BUILD_OUTPUTS, GIT_HASH, DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, PYTHON_ENABLED, X86ONLY, X64ONLY
|
||||
global FORCE_MK, JAVA_ENABLED, ZIP_BUILD_OUTPUTS, GIT_HASH, DOTNET_CORE_ENABLED, DOTNET_KEY_FILE, ASSEMBLY_VERSION, PYTHON_ENABLED, X86ONLY, X64ONLY
|
||||
path = BUILD_DIR
|
||||
options, remainder = getopt.gnu_getopt(sys.argv[1:], 'b:hsf', ['build=',
|
||||
'help',
|
||||
|
@ -83,6 +85,7 @@ def parse_options():
|
|||
'nojava',
|
||||
'nodotnet',
|
||||
'dotnet-key=',
|
||||
'assembly-version=',
|
||||
'zip',
|
||||
'githash',
|
||||
'nopython',
|
||||
|
@ -102,6 +105,8 @@ def parse_options():
|
|||
FORCE_MK = True
|
||||
elif opt == '--nodotnet':
|
||||
DOTNET_CORE_ENABLED = False
|
||||
elif opt == '--assembly-version':
|
||||
ASSEMBLY_VERSION = arg
|
||||
elif opt == '--nopython':
|
||||
PYTHON_ENABLED = False
|
||||
elif opt == '--dotnet-key':
|
||||
|
@ -131,8 +136,10 @@ def mk_build_dir(path, x64):
|
|||
opts = ["python", os.path.join('scripts', 'mk_make.py'), parallel, "-b", path]
|
||||
if DOTNET_CORE_ENABLED:
|
||||
opts.append('--dotnet')
|
||||
if not DOTNET_KEY_FILE is None:
|
||||
if DOTNET_KEY_FILE is not None:
|
||||
opts.append('--dotnet-key=' + DOTNET_KEY_FILE)
|
||||
if ASSEMBLY_VERSION is not None:
|
||||
opts.append('--assembly-version=' + ASSEMBLY_VERSION)
|
||||
if JAVA_ENABLED:
|
||||
opts.append('--java')
|
||||
if x64:
|
||||
|
@ -196,6 +203,7 @@ def mk_z3s():
|
|||
|
||||
def get_z3_name(x64):
|
||||
major, minor, build, revision = get_version()
|
||||
print("Assembly version:", major, minor, build, revision)
|
||||
if x64:
|
||||
platform = "x64"
|
||||
else:
|
||||
|
@ -299,9 +307,10 @@ def cp_licenses():
|
|||
cp_license(False)
|
||||
|
||||
def init_flags():
|
||||
global DOTNET_KEY_FILE, JAVA_ENABLED, PYTHON_ENABLED
|
||||
global DOTNET_KEY_FILE, JAVA_ENABLED, PYTHON_ENABLED, ASSEMBLY_VERSION
|
||||
mk_util.DOTNET_CORE_ENABLED = True
|
||||
mk_util.DOTNET_KEY_FILE = DOTNET_KEY_FILE
|
||||
mk_util.ASSEMBLY_VERSION = ASSEMBLY_VERSION
|
||||
mk_util.JAVA_ENABLED = JAVA_ENABLED
|
||||
mk_util.PYTHON_ENABLED = PYTHON_ENABLED
|
||||
mk_util.ALWAYS_DYNAMIC_BASE = True
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
variables:
|
||||
|
||||
Major: '4'
|
||||
Minor: '11'
|
||||
Patch: '0'
|
||||
NightlyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId)-$(Build.DefinitionName)
|
||||
Patch: '3'
|
||||
AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId)
|
||||
NightlyVersion: $(AssemblyVersion)-$(Build.DefinitionName)
|
||||
|
||||
stages:
|
||||
- stage: Build
|
||||
jobs:
|
||||
|
||||
- job: Mac
|
||||
displayName: "Mac Build"
|
||||
pool:
|
||||
|
@ -23,7 +22,6 @@ stages:
|
|||
artifactName: 'Mac'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
|
||||
- job: MacArm64
|
||||
displayName: "Mac ARM64 Build"
|
||||
pool:
|
||||
|
@ -37,7 +35,6 @@ stages:
|
|||
artifactName: 'MacArm64'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
|
||||
- job: Ubuntu
|
||||
displayName: "Ubuntu build"
|
||||
pool:
|
||||
|
@ -55,7 +52,7 @@ stages:
|
|||
- job: UbuntuDoc
|
||||
displayName: "Ubuntu Doc build"
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- script: sudo apt-get install ocaml opam libgmp-dev
|
||||
- script: opam init -y
|
||||
|
@ -76,6 +73,7 @@ stages:
|
|||
eval `opam config env`
|
||||
cd doc
|
||||
python mk_api_doc.py --mld --z3py-package-path=../build/python/z3
|
||||
python mk_params_doc.py
|
||||
mkdir api/html/ml
|
||||
ocamldoc -html -d api/html/ml -sort -hide Z3 -I $( ocamlfind query zarith ) -I ../build/api/ml ../build/api/ml/z3enums.mli ../build/api/ml/z3.mli
|
||||
cd ..
|
||||
|
@ -92,7 +90,7 @@ stages:
|
|||
name: ManyLinux
|
||||
displayName: "ManyLinux build"
|
||||
pool:
|
||||
vmImage: "Ubuntu-18.04"
|
||||
vmImage: "ubuntu-latest"
|
||||
container: "quay.io/pypa/manylinux2010_x86_64:latest"
|
||||
steps:
|
||||
- script: $(python) scripts/mk_unix_dist.py --nodotnet --nojava
|
||||
|
@ -111,7 +109,7 @@ stages:
|
|||
# name: MuslLinux
|
||||
# displayName: "MuslLinux build"
|
||||
# pool:
|
||||
# vmImage: "Ubuntu-18.04"
|
||||
# vmImage: "ubuntu-latest"
|
||||
# container: "quay.io/pypa/musllinux_1_1_x86_64:latest"
|
||||
# steps:
|
||||
# - script: $(python) scripts/mk_unix_dist.py --nodotnet --nojava
|
||||
|
@ -123,7 +121,6 @@ stages:
|
|||
# artifactName: '$(name)Build'
|
||||
# targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
|
||||
- job: Windows32
|
||||
displayName: "Windows 32-bit build"
|
||||
pool:
|
||||
|
@ -134,6 +131,7 @@ stages:
|
|||
script:
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86 &
|
||||
python scripts\mk_win_dist.py
|
||||
--assembly-version=$(AssemblyVersion)
|
||||
--x86-only
|
||||
--dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk
|
||||
--zip
|
||||
|
@ -146,6 +144,22 @@ stages:
|
|||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: 'Windows32'
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Collect Symbols'
|
||||
inputs:
|
||||
sourceFolder: dist
|
||||
contents: '**/*.pdb'
|
||||
targetFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
# Publish symbol archive to match nuget package
|
||||
# Index your source code and publish symbols to a file share or Azure Artifacts symbol server
|
||||
- task: PublishSymbols@2
|
||||
inputs:
|
||||
symbolsFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
searchPattern: '**/*.pdb'
|
||||
indexSources: false # Github not supported
|
||||
publishSymbols: true
|
||||
symbolServerType: TeamServices
|
||||
detailedLog: true
|
||||
|
||||
- job: Windows64
|
||||
displayName: "Windows 64-bit build"
|
||||
|
@ -157,6 +171,7 @@ stages:
|
|||
script:
|
||||
call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64 &
|
||||
python scripts\mk_win_dist.py
|
||||
--assembly-version=$(AssemblyVersion)
|
||||
--x64-only
|
||||
--dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk
|
||||
--zip
|
||||
|
@ -169,8 +184,22 @@ stages:
|
|||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifactName: 'Windows64'
|
||||
|
||||
|
||||
- task: CopyFiles@2
|
||||
displayName: 'Collect Symbols'
|
||||
inputs:
|
||||
sourceFolder: dist
|
||||
contents: '**/*.pdb'
|
||||
targetFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
# Publish symbol archive to match nuget package
|
||||
# Index your source code and publish symbols to a file share or Azure Artifacts symbol server
|
||||
- task: PublishSymbols@2
|
||||
inputs:
|
||||
symbolsFolder: '$(Build.ArtifactStagingDirectory)/symbols'
|
||||
searchPattern: '**/*.pdb'
|
||||
indexSources: false # Github not supported
|
||||
publishSymbols: true
|
||||
symbolServerType: TeamServices
|
||||
detailedLog: true
|
||||
|
||||
- stage: Package
|
||||
jobs:
|
||||
|
@ -506,7 +535,7 @@ stages:
|
|||
- task: GitHubRelease@0
|
||||
continueOnError: true
|
||||
inputs:
|
||||
gitHubConnection: Z3GitHub
|
||||
gitHubConnection: Z3Prover
|
||||
repositoryName: 'Z3Prover/z3'
|
||||
action: 'delete'
|
||||
# target: '$(Build.SourceVersion)'
|
||||
|
@ -515,7 +544,7 @@ stages:
|
|||
- task: GitHubRelease@0
|
||||
continueOnError: true
|
||||
inputs:
|
||||
gitHubConnection: Z3GitHub
|
||||
gitHubConnection: Z3Prover
|
||||
repositoryName: 'Z3Prover/z3'
|
||||
action: 'create'
|
||||
# target: '$(Build.SourceVersion)'
|
||||
|
@ -555,15 +584,16 @@ stages:
|
|||
displayName: 'NuGet Nightly x64 push'
|
||||
inputs:
|
||||
command: push
|
||||
publishVstsFeed: 'Z3Nightly'
|
||||
publishVstsFeed: 'Z3Build/Z3-Nightly-Builds'
|
||||
packagesToPush: $(Agent.TempDirectory)/x64/*.nupkg
|
||||
allowPackageConflicts: true
|
||||
- task: NuGetCommand@2
|
||||
displayName: 'NuGet Nightly x86 push'
|
||||
inputs:
|
||||
command: push
|
||||
publishVstsFeed: 'Z3Nightly'
|
||||
publishVstsFeed: 'Z3Build/Z3-Nightly-Builds'
|
||||
packagesToPush: $(Agent.TempDirectory)/x86/*.nupkg
|
||||
allowPackageConflicts: true
|
||||
|
||||
|
||||
|
||||
# TBD: run regression tests on generated binaries.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
trigger: none
|
||||
|
||||
variables:
|
||||
ReleaseVersion: '4.11.0'
|
||||
ReleaseVersion: '4.11.3'
|
||||
|
||||
stages:
|
||||
|
||||
|
@ -56,8 +56,6 @@ stages:
|
|||
artifactName: 'MacArm64'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
|
||||
|
||||
- job: UbuntuBuild
|
||||
displayName: "Ubuntu build"
|
||||
pool:
|
||||
|
@ -87,11 +85,10 @@ stages:
|
|||
artifactName: 'UbuntuBuild'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
|
||||
- job: UbuntuDoc
|
||||
displayName: "Ubuntu Doc build"
|
||||
pool:
|
||||
vmImage: "Ubuntu-latest"
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- script: sudo apt-get install ocaml opam libgmp-dev
|
||||
- script: opam init -y
|
||||
|
@ -112,6 +109,7 @@ stages:
|
|||
eval `opam config env`
|
||||
cd doc
|
||||
python mk_api_doc.py --mld --z3py-package-path=../build/python/z3
|
||||
python mk_params_doc.py
|
||||
mkdir api/html/ml
|
||||
ocamldoc -html -d api/html/ml -sort -hide Z3 -I $( ocamlfind query zarith ) -I ../build/api/ml ../build/api/ml/z3enums.mli ../build/api/ml/z3.mli
|
||||
cd ..
|
||||
|
@ -168,6 +166,7 @@ stages:
|
|||
ReleaseVersion: $(ReleaseVersion)
|
||||
BuildArchitecture: 'x86'
|
||||
|
||||
|
||||
# Creates Z3 packages in various formats
|
||||
- stage: Package
|
||||
jobs:
|
||||
|
@ -485,7 +484,7 @@ stages:
|
|||
path: $(Agent.TempDirectory)
|
||||
- task: GitHubRelease@0
|
||||
inputs:
|
||||
gitHubConnection: Z3GitHub
|
||||
gitHubConnection: Z3Prover
|
||||
repositoryName: $(Build.Repository.Name)
|
||||
action: 'create'
|
||||
target: '$(Build.SourceVersion)'
|
||||
|
@ -498,7 +497,7 @@ stages:
|
|||
isDraft: true
|
||||
isPreRelease: true
|
||||
|
||||
# Enable on release (after fixing Nuget key)
|
||||
|
||||
- job: NuGetPublish
|
||||
condition: eq(1,0)
|
||||
displayName: "Publish to NuGet.org"
|
||||
|
@ -518,7 +517,6 @@ stages:
|
|||
nuGetFeedType: External
|
||||
publishFeedCredentials: $(NugetZ3)
|
||||
packagesToPush: $(Agent.TempDirectory)/*.nupkg
|
||||
|
||||
|
||||
# Enable on release:
|
||||
- job: PyPIPublish
|
||||
|
|
|
@ -776,6 +776,13 @@ def mk_java(java_src, java_dir, package_name):
|
|||
java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "I");\n')
|
||||
java_wrapper.write(' jenv->SetIntField(a%s, fid, (jint) _a%s);\n' % (i, i))
|
||||
java_wrapper.write(' }\n')
|
||||
elif param_type(param) == STRING:
|
||||
java_wrapper.write(' {\n')
|
||||
java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i)
|
||||
java_wrapper.write(' jfieldID fid = jenv->GetFieldID(mc, "value", "Ljava/lang/String;");')
|
||||
java_wrapper.write(' jstring fval = jenv->NewStringUTF(_a%s);\n' % i)
|
||||
java_wrapper.write(' jenv->SetObjectField(a%s, fid, fval);\n' % i)
|
||||
java_wrapper.write(' }\n')
|
||||
else:
|
||||
java_wrapper.write(' {\n')
|
||||
java_wrapper.write(' jclass mc = jenv->GetObjectClass(a%s);\n' % i)
|
||||
|
|
|
@ -118,6 +118,27 @@ if (Z3_BUILD_LIBZ3_SHARED)
|
|||
else()
|
||||
set(lib_type "STATIC")
|
||||
endif()
|
||||
# Enable static msvc runtime.
|
||||
if (MSVC AND Z3_BUILD_LIBZ3_MSVC_STATIC)
|
||||
set(CompilerFlags
|
||||
CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
)
|
||||
foreach(CompilerFlag ${CompilerFlags})
|
||||
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
|
||||
string(REPLACE "/MDd" "/MTd" ${CompilerFlag} "${${CompilerFlag}}")
|
||||
set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
|
||||
message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
|
||||
endforeach()
|
||||
endif(MSVC)
|
||||
add_library(libz3 ${lib_type} ${object_files})
|
||||
target_include_directories(libz3 INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/api>
|
||||
|
|
|
@ -22,6 +22,8 @@ Revision History:
|
|||
#include "ast/arith_decl_plugin.h"
|
||||
#include "math/polynomial/algebraic_numbers.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#define MK_ARITH_OP(NAME, OP) MK_NARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
#define MK_BINARY_ARITH_OP(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
#define MK_ARITH_PRED(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
|
@ -88,7 +90,25 @@ extern "C" {
|
|||
MK_ARITH_PRED(Z3_mk_gt, OP_GT);
|
||||
MK_ARITH_PRED(Z3_mk_le, OP_LE);
|
||||
MK_ARITH_PRED(Z3_mk_ge, OP_GE);
|
||||
MK_ARITH_PRED(Z3_mk_divides, OP_IDIVIDES);
|
||||
|
||||
Z3_ast Z3_API Z3_mk_divides(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_divides(c, n1, n2);
|
||||
RESET_ERROR_CODE();
|
||||
rational val;
|
||||
if (!is_expr(n1) || !mk_c(c)->autil().is_numeral(to_expr(n1), val) || !val.is_unsigned()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
RETURN_Z3(nullptr);
|
||||
}
|
||||
parameter p(val.get_unsigned());
|
||||
expr* arg = to_expr(n2);
|
||||
expr* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), OP_IDIVIDES, 1, &p, 1, &arg);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
MK_UNARY(Z3_mk_int2real, mk_c(c)->get_arith_fid(), OP_TO_REAL, SKIP);
|
||||
MK_UNARY(Z3_mk_real2int, mk_c(c)->get_arith_fid(), OP_TO_INT, SKIP);
|
||||
MK_UNARY(Z3_mk_is_int, mk_c(c)->get_arith_fid(), OP_IS_INT, SKIP);
|
||||
|
|
|
@ -294,14 +294,19 @@ extern "C" {
|
|||
return Z3_mk_store(c, set, elem, Z3_mk_false(c));
|
||||
}
|
||||
|
||||
static bool is_array_sort(Z3_context c, Z3_sort t) {
|
||||
return
|
||||
to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT;
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_domain(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, nullptr);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
|
||||
if (is_array_sort(c, t)) {
|
||||
Z3_sort r = of_sort(get_array_domain(to_sort(t), 0));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
|
@ -314,10 +319,8 @@ extern "C" {
|
|||
LOG_Z3_get_array_sort_domain_n(c, t, idx);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, nullptr);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT &&
|
||||
get_array_arity(to_sort(t)) > idx) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(get_array_domain(to_sort(t), idx));
|
||||
if (is_array_sort(c, t) && get_array_arity(to_sort(t)) > idx) {
|
||||
Z3_sort r = of_sort(get_array_domain(to_sort(t), idx));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
|
@ -330,10 +333,8 @@ extern "C" {
|
|||
LOG_Z3_get_array_sort_range(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, nullptr);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
unsigned n = to_sort(t)->get_num_parameters();
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(n-1).get_ast());
|
||||
if (is_array_sort(c, t)) {
|
||||
Z3_sort r = of_sort(get_array_range(to_sort(t)));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
|
|
|
@ -1178,7 +1178,7 @@ extern "C" {
|
|||
case OP_BSMOD: return Z3_OP_BSMOD;
|
||||
case OP_BSDIV0: return Z3_OP_BSDIV0;
|
||||
case OP_BUDIV0: return Z3_OP_BUDIV0;
|
||||
case OP_BSREM0: return Z3_OP_BUREM0;
|
||||
case OP_BSREM0: return Z3_OP_BSREM0;
|
||||
case OP_BUREM0: return Z3_OP_BUREM0;
|
||||
case OP_BSMOD0: return Z3_OP_BSMOD0;
|
||||
case OP_ULEQ: return Z3_OP_ULEQ;
|
||||
|
|
|
@ -153,7 +153,7 @@ namespace api {
|
|||
flush_objects();
|
||||
for (auto& kv : m_allocated_objects) {
|
||||
api::object* val = kv.m_value;
|
||||
DEBUG_CODE(warning_msg("Uncollected memory: %d: %s", kv.m_key, typeid(*val).name()););
|
||||
DEBUG_CODE(if (!m_concurrent_dec_ref) warning_msg("Uncollected memory: %d: %s", kv.m_key, typeid(*val).name()););
|
||||
dealloc(val);
|
||||
}
|
||||
if (m_params.owns_manager())
|
||||
|
|
|
@ -124,7 +124,7 @@ extern "C" {
|
|||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_parser_context_parse_stream(Z3_context c, scoped_ptr<cmd_context>& ctx, bool owned, std::istream& is) {
|
||||
static Z3_ast_vector Z3_parser_context_parse_stream(Z3_context c, scoped_ptr<cmd_context>& ctx, bool owned, std::istream& is) {
|
||||
Z3_TRY;
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
|
@ -163,6 +163,7 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
static
|
||||
Z3_ast_vector parse_smtlib2_stream(bool exec, Z3_context c, std::istream& is,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const _sort_names[],
|
||||
|
@ -242,6 +243,7 @@ extern "C" {
|
|||
std::istringstream is(s);
|
||||
ctx->set_regular_stream(ous);
|
||||
ctx->set_diagnostic_stream(ous);
|
||||
cmd_context::scoped_redirect _redirect(*ctx);
|
||||
try {
|
||||
if (!parse_smt2_commands(*ctx.get(), is)) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str());
|
||||
|
@ -256,6 +258,4 @@ extern "C" {
|
|||
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
|
||||
Z3_CATCH_RETURN(mk_c(c)->mk_external_string(ous.str()));
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ Revision History:
|
|||
#include "smt/smt_implied_equalities.h"
|
||||
#include "solver/smt_logics.h"
|
||||
#include "solver/tactic2solver.h"
|
||||
#include "solver/solver_params.hpp"
|
||||
#include "params/solver_params.hpp"
|
||||
#include "cmd_context/cmd_context.h"
|
||||
#include "parsers/smt2/smt2parser.h"
|
||||
#include "sat/dimacs.h"
|
||||
|
|
|
@ -28,7 +28,7 @@ extern "C" {
|
|||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_stats_ref(s).display_smt2(buffer);
|
||||
std::string result = buffer.str();
|
||||
std::string result = std::move(buffer).str();
|
||||
// Hack for removing the trailing '\n'
|
||||
SASSERT(result.size() > 0);
|
||||
result.resize(result.size()-1);
|
||||
|
|
|
@ -40,7 +40,7 @@ namespace api {
|
|||
context& m_context;
|
||||
public:
|
||||
object(context& c);
|
||||
virtual ~object() {}
|
||||
virtual ~object() = default;
|
||||
unsigned ref_count() const { return m_ref_count; }
|
||||
unsigned id() const { return m_id; }
|
||||
void inc_ref();
|
||||
|
|
|
@ -23,7 +23,6 @@ Notes:
|
|||
#include<cassert>
|
||||
#include<ostream>
|
||||
#include<string>
|
||||
#include<sstream>
|
||||
#include<memory>
|
||||
#include<vector>
|
||||
#include<z3.h>
|
||||
|
@ -88,7 +87,7 @@ namespace z3 {
|
|||
class exception : public std::exception {
|
||||
std::string m_msg;
|
||||
public:
|
||||
virtual ~exception() throw() {}
|
||||
virtual ~exception() throw() = default;
|
||||
exception(char const * msg):m_msg(msg) {}
|
||||
char const * msg() const { return m_msg.c_str(); }
|
||||
char const * what() const throw() { return m_msg.c_str(); }
|
||||
|
@ -4315,6 +4314,16 @@ namespace z3 {
|
|||
Z3_solver_propagate_consequence(ctx(), cb, fixed.size(), _fixed.ptr(), 0, nullptr, nullptr, conseq);
|
||||
}
|
||||
|
||||
void conflict(expr_vector const& fixed, expr_vector const& lhs, expr_vector const& rhs) {
|
||||
assert(cb);
|
||||
assert(lhs.size() == rhs.size());
|
||||
expr conseq = ctx().bool_val(false);
|
||||
array<Z3_ast> _fixed(fixed);
|
||||
array<Z3_ast> _lhs(lhs);
|
||||
array<Z3_ast> _rhs(rhs);
|
||||
Z3_solver_propagate_consequence(ctx(), cb, fixed.size(), _fixed.ptr(), lhs.size(), _lhs.ptr(), _rhs.ptr(), conseq);
|
||||
}
|
||||
|
||||
void propagate(expr_vector const& fixed, expr const& conseq) {
|
||||
assert(cb);
|
||||
assert((Z3_context)conseq.ctx() == (Z3_context)ctx());
|
||||
|
|
|
@ -208,37 +208,22 @@ namespace Microsoft.Z3
|
|||
internal AST(Context ctx) : base(ctx) { Debug.Assert(ctx != null); }
|
||||
internal AST(Context ctx, IntPtr obj) : base(ctx, obj) { Debug.Assert(ctx != null); }
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
// Console.WriteLine("AST IncRef()");
|
||||
if (Context == null || o == IntPtr.Zero)
|
||||
return;
|
||||
Context.AST_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
if (Context != null && o != IntPtr.Zero)
|
||||
Native.Z3_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
// Console.WriteLine("AST DecRef()");
|
||||
if (Context == null || o == IntPtr.Zero)
|
||||
return;
|
||||
Context.AST_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
if (Context != null && o != IntPtr.Zero)
|
||||
{
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static AST Create(Context ctx, IntPtr obj)
|
||||
|
|
|
@ -125,31 +125,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_ast_map_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_ast_map_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.ASTMap_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_ast_map_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.ASTMap_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_ast_map_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -233,31 +233,19 @@ namespace Microsoft.Z3
|
|||
internal ASTVector(Context ctx, IntPtr obj) : base(ctx, obj) { Debug.Assert(ctx != null); }
|
||||
internal ASTVector(Context ctx) : base(ctx, Native.Z3_mk_ast_vector(ctx.nCtx)) { Debug.Assert(ctx != null); }
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_ast_vector_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_ast_vector_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.ASTVector_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_ast_vector_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.ASTVector_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_ast_vector_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -67,31 +67,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_apply_result_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_apply_result_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.ApplyResult_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_apply_result_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.ApplyResult_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock(Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_apply_result_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@ set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE
|
|||
Context.cs
|
||||
DatatypeExpr.cs
|
||||
DatatypeSort.cs
|
||||
Deprecated.cs
|
||||
EnumSort.cs
|
||||
Expr.cs
|
||||
FiniteDomainExpr.cs
|
||||
|
@ -76,7 +75,6 @@ set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE
|
|||
FuncInterp.cs
|
||||
Global.cs
|
||||
Goal.cs
|
||||
IDecRefQueue.cs
|
||||
IntExpr.cs
|
||||
IntNum.cs
|
||||
IntSort.cs
|
||||
|
|
|
@ -42,6 +42,7 @@ namespace Microsoft.Z3
|
|||
lock (creation_lock)
|
||||
{
|
||||
m_ctx = Native.Z3_mk_context_rc(IntPtr.Zero);
|
||||
Native.Z3_enable_concurrent_dec_ref(m_ctx);
|
||||
InitContext();
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +76,7 @@ namespace Microsoft.Z3
|
|||
foreach (KeyValuePair<string, string> kv in settings)
|
||||
Native.Z3_set_param_value(cfg, kv.Key, kv.Value);
|
||||
m_ctx = Native.Z3_mk_context_rc(cfg);
|
||||
Native.Z3_enable_concurrent_dec_ref(m_ctx);
|
||||
Native.Z3_del_config(cfg);
|
||||
InitContext();
|
||||
}
|
||||
|
@ -124,7 +126,7 @@ namespace Microsoft.Z3
|
|||
/// </summary>
|
||||
internal Symbol[] MkSymbols(string[] names)
|
||||
{
|
||||
if (names == null) return null;
|
||||
if (names == null) return new Symbol[0];
|
||||
Symbol[] result = new Symbol[names.Length];
|
||||
for (int i = 0; i < names.Length; ++i) result[i] = MkSymbol(names[i]);
|
||||
return result;
|
||||
|
@ -4793,7 +4795,6 @@ namespace Microsoft.Z3
|
|||
PrintMode = Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT;
|
||||
m_n_err_handler = new Native.Z3_error_handler(NativeErrorHandler); // keep reference so it doesn't get collected.
|
||||
Native.Z3_set_error_handler(m_ctx, m_n_err_handler);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
internal void CheckContextMatch(Z3Object other)
|
||||
|
@ -4852,123 +4853,9 @@ namespace Microsoft.Z3
|
|||
|
||||
private void ObjectInvariant()
|
||||
{
|
||||
Debug.Assert(m_AST_DRQ != null);
|
||||
Debug.Assert(m_ASTMap_DRQ != null);
|
||||
Debug.Assert(m_ASTVector_DRQ != null);
|
||||
Debug.Assert(m_ApplyResult_DRQ != null);
|
||||
Debug.Assert(m_FuncEntry_DRQ != null);
|
||||
Debug.Assert(m_FuncInterp_DRQ != null);
|
||||
Debug.Assert(m_Goal_DRQ != null);
|
||||
Debug.Assert(m_Model_DRQ != null);
|
||||
Debug.Assert(m_Params_DRQ != null);
|
||||
Debug.Assert(m_ParamDescrs_DRQ != null);
|
||||
Debug.Assert(m_Probe_DRQ != null);
|
||||
Debug.Assert(m_Solver_DRQ != null);
|
||||
Debug.Assert(m_Statistics_DRQ != null);
|
||||
Debug.Assert(m_Tactic_DRQ != null);
|
||||
Debug.Assert(m_Fixedpoint_DRQ != null);
|
||||
Debug.Assert(m_Optimize_DRQ != null);
|
||||
// none
|
||||
}
|
||||
|
||||
readonly private AST.DecRefQueue m_AST_DRQ = new AST.DecRefQueue();
|
||||
readonly private ASTMap.DecRefQueue m_ASTMap_DRQ = new ASTMap.DecRefQueue(10);
|
||||
readonly private ASTVector.DecRefQueue m_ASTVector_DRQ = new ASTVector.DecRefQueue(10);
|
||||
readonly private ApplyResult.DecRefQueue m_ApplyResult_DRQ = new ApplyResult.DecRefQueue(10);
|
||||
readonly private FuncInterp.Entry.DecRefQueue m_FuncEntry_DRQ = new FuncInterp.Entry.DecRefQueue(10);
|
||||
readonly private FuncInterp.DecRefQueue m_FuncInterp_DRQ = new FuncInterp.DecRefQueue(10);
|
||||
readonly private Goal.DecRefQueue m_Goal_DRQ = new Goal.DecRefQueue(10);
|
||||
readonly private Model.DecRefQueue m_Model_DRQ = new Model.DecRefQueue(10);
|
||||
readonly private Params.DecRefQueue m_Params_DRQ = new Params.DecRefQueue(10);
|
||||
readonly private ParamDescrs.DecRefQueue m_ParamDescrs_DRQ = new ParamDescrs.DecRefQueue(10);
|
||||
readonly private Probe.DecRefQueue m_Probe_DRQ = new Probe.DecRefQueue(10);
|
||||
readonly private Solver.DecRefQueue m_Solver_DRQ = new Solver.DecRefQueue(10);
|
||||
readonly private Statistics.DecRefQueue m_Statistics_DRQ = new Statistics.DecRefQueue(10);
|
||||
readonly private Tactic.DecRefQueue m_Tactic_DRQ = new Tactic.DecRefQueue(10);
|
||||
readonly private Fixedpoint.DecRefQueue m_Fixedpoint_DRQ = new Fixedpoint.DecRefQueue(10);
|
||||
readonly private Optimize.DecRefQueue m_Optimize_DRQ = new Optimize.DecRefQueue(10);
|
||||
|
||||
/// <summary>
|
||||
/// AST DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue AST_DRQ { get { return m_AST_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// ASTMap DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue ASTMap_DRQ { get { return m_ASTMap_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// ASTVector DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue ASTVector_DRQ { get { return m_ASTVector_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// ApplyResult DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue ApplyResult_DRQ { get { return m_ApplyResult_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// FuncEntry DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue FuncEntry_DRQ { get { return m_FuncEntry_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// FuncInterp DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue FuncInterp_DRQ { get { return m_FuncInterp_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Goal DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Goal_DRQ { get { return m_Goal_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Model DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Model_DRQ { get { return m_Model_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Params DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Params_DRQ { get { return m_Params_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// ParamDescrs DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue ParamDescrs_DRQ { get { return m_ParamDescrs_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Probe DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Probe_DRQ { get { return m_Probe_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Solver DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Solver_DRQ { get { return m_Solver_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Statistics DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Statistics_DRQ { get { return m_Statistics_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Tactic DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Tactic_DRQ { get { return m_Tactic_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// FixedPoint DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Fixedpoint_DRQ { get { return m_Fixedpoint_DRQ; } }
|
||||
|
||||
/// <summary>
|
||||
/// Optimize DRQ
|
||||
/// </summary>
|
||||
public IDecRefQueue Optimize_DRQ { get { return m_Fixedpoint_DRQ; } }
|
||||
|
||||
internal long refCount = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Finalizer.
|
||||
/// </summary>
|
||||
|
@ -4984,22 +4871,6 @@ namespace Microsoft.Z3
|
|||
public void Dispose()
|
||||
{
|
||||
// Console.WriteLine("Context Dispose from " + System.Threading.Thread.CurrentThread.ManagedThreadId);
|
||||
AST_DRQ.Clear(this);
|
||||
ASTMap_DRQ.Clear(this);
|
||||
ASTVector_DRQ.Clear(this);
|
||||
ApplyResult_DRQ.Clear(this);
|
||||
FuncEntry_DRQ.Clear(this);
|
||||
FuncInterp_DRQ.Clear(this);
|
||||
Goal_DRQ.Clear(this);
|
||||
Model_DRQ.Clear(this);
|
||||
Params_DRQ.Clear(this);
|
||||
ParamDescrs_DRQ.Clear(this);
|
||||
Probe_DRQ.Clear(this);
|
||||
Solver_DRQ.Clear(this);
|
||||
Statistics_DRQ.Clear(this);
|
||||
Tactic_DRQ.Clear(this);
|
||||
Fixedpoint_DRQ.Clear(this);
|
||||
Optimize_DRQ.Clear(this);
|
||||
|
||||
if (m_boolSort != null) m_boolSort.Dispose();
|
||||
if (m_intSort != null) m_intSort.Dispose();
|
||||
|
@ -5011,16 +4882,19 @@ namespace Microsoft.Z3
|
|||
m_realSort = null;
|
||||
m_stringSort = null;
|
||||
m_charSort = null;
|
||||
if (refCount == 0 && m_ctx != IntPtr.Zero)
|
||||
if (m_ctx != IntPtr.Zero)
|
||||
{
|
||||
m_n_err_handler = null;
|
||||
IntPtr ctx = m_ctx;
|
||||
m_ctx = IntPtr.Zero;
|
||||
if (!is_external)
|
||||
Native.Z3_del_context(ctx);
|
||||
lock (this)
|
||||
{
|
||||
m_n_err_handler = null;
|
||||
m_ctx = IntPtr.Zero;
|
||||
}
|
||||
if (!is_external)
|
||||
Native.Z3_del_context(ctx);
|
||||
}
|
||||
else
|
||||
GC.ReRegisterForFinalize(this);
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
Deprecated.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Expose deprecated features for use from the managed API
|
||||
those who use them for experiments.
|
||||
|
||||
Author:
|
||||
|
||||
Christoph Wintersteiger (cwinter) 2012-03-15
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// The main interaction with Z3 happens via the Context.
|
||||
/// </summary>
|
||||
public class Deprecated
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -318,31 +318,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_fixedpoint_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_fixedpoint_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Fixedpoint_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_fixedpoint_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Fixedpoint_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_fixedpoint_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -85,31 +85,18 @@ namespace Microsoft.Z3
|
|||
#region Internal
|
||||
internal Entry(Context ctx, IntPtr obj) : base(ctx, obj) { Debug.Assert(ctx != null); }
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_func_entry_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_func_entry_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.FuncEntry_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_func_entry_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.FuncEntry_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_func_entry_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
};
|
||||
|
@ -190,31 +177,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_func_interp_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_func_interp_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.FuncInterp_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_func_interp_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.FuncInterp_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_func_interp_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -252,33 +252,20 @@ namespace Microsoft.Z3
|
|||
: base(ctx, Native.Z3_mk_goal(ctx.nCtx, (byte)(models ? 1 : 0), (byte)(unsatCores ? 1 : 0), (byte)(proofs ? 1 : 0)))
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_goal_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_goal_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Goal_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_goal_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Goal_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_goal_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
DecRefQueue.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 Managed API: DecRef Queues
|
||||
|
||||
Author:
|
||||
|
||||
Christoph Wintersteiger (cwinter) 2012-03-16
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// DecRefQueue interface
|
||||
/// </summary>
|
||||
public abstract class IDecRefQueue
|
||||
{
|
||||
#region Object invariant
|
||||
|
||||
private void ObjectInvariant()
|
||||
{
|
||||
Debug.Assert(this.m_queue != null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
readonly private Object m_lock = new Object();
|
||||
readonly private List<IntPtr> m_queue = new List<IntPtr>();
|
||||
private uint m_move_limit;
|
||||
|
||||
internal IDecRefQueue(uint move_limit = 1024)
|
||||
{
|
||||
m_move_limit = move_limit;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the limit on numbers of objects that are kept back at GC collection.
|
||||
/// </summary>
|
||||
/// <param name="l"></param>
|
||||
public void SetLimit(uint l) { m_move_limit = l; }
|
||||
|
||||
internal abstract void IncRef(Context ctx, IntPtr obj);
|
||||
internal abstract void DecRef(Context ctx, IntPtr obj);
|
||||
|
||||
internal void IncAndClear(Context ctx, IntPtr o)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
|
||||
IncRef(ctx, o);
|
||||
if (m_queue.Count >= m_move_limit) Clear(ctx);
|
||||
}
|
||||
|
||||
internal void Add(IntPtr o)
|
||||
{
|
||||
if (o == IntPtr.Zero) return;
|
||||
|
||||
lock (m_lock)
|
||||
{
|
||||
m_queue.Add(o);
|
||||
}
|
||||
}
|
||||
|
||||
internal void Clear(Context ctx)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
|
||||
lock (m_lock)
|
||||
{
|
||||
foreach (IntPtr o in m_queue)
|
||||
DecRef(ctx, o);
|
||||
m_queue.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class DecRefQueueContracts : IDecRefQueue
|
||||
{
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -302,33 +302,20 @@ namespace Microsoft.Z3
|
|||
: base(ctx, obj)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_model_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_model_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Model_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_model_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Model_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_model_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -440,31 +440,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_optimize_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_optimize_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Optimize_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_optimize_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Optimize_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_optimize_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -91,33 +91,20 @@ namespace Microsoft.Z3
|
|||
: base(ctx, obj)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_param_descrs_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_param_descrs_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.ParamDescrs_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_param_descrs_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.ParamDescrs_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_param_descrs_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -147,33 +147,20 @@ namespace Microsoft.Z3
|
|||
: base(ctx, Native.Z3_mk_params(ctx.nCtx))
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_params_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_params_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Params_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_params_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Params_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_params_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -70,31 +70,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_probe_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_probe_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Probe_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_probe_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Probe_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_probe_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -538,31 +538,18 @@ namespace Microsoft.Z3
|
|||
this.BacktrackLevel = uint.MaxValue;
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_solver_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_solver_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Solver_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_solver_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Solver_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_solver_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
|
||||
private Status lboolToStatus(Z3_lbool r)
|
||||
|
|
|
@ -19,8 +19,6 @@ Notes:
|
|||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
|
||||
|
@ -189,31 +187,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_stats_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_stats_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Statistics_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_stats_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Statistics_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_stats_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -107,34 +107,18 @@ namespace Microsoft.Z3
|
|||
Debug.Assert(ctx != null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DecRefQueue
|
||||
/// </summary>
|
||||
internal class DecRefQueue : IDecRefQueue
|
||||
{
|
||||
public DecRefQueue() : base() { }
|
||||
public DecRefQueue(uint move_limit) : base(move_limit) { }
|
||||
internal override void IncRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_tactic_inc_ref(ctx.nCtx, obj);
|
||||
}
|
||||
|
||||
internal override void DecRef(Context ctx, IntPtr obj)
|
||||
{
|
||||
Native.Z3_tactic_dec_ref(ctx.nCtx, obj);
|
||||
}
|
||||
};
|
||||
|
||||
internal override void IncRef(IntPtr o)
|
||||
{
|
||||
Context.Tactic_DRQ.IncAndClear(Context, o);
|
||||
base.IncRef(o);
|
||||
Native.Z3_tactic_inc_ref(Context.nCtx, o);
|
||||
}
|
||||
|
||||
internal override void DecRef(IntPtr o)
|
||||
{
|
||||
Context.Tactic_DRQ.Add(o);
|
||||
base.DecRef(o);
|
||||
lock (Context)
|
||||
{
|
||||
if (Context.nCtx != IntPtr.Zero)
|
||||
Native.Z3_tactic_dec_ref(Context.nCtx, o);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace Microsoft.Z3
|
|||
/// <summary>
|
||||
/// Propagator context for .Net
|
||||
/// </summary>
|
||||
public class UserPropagator
|
||||
public class UserPropagator : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate type for fixed callback
|
||||
|
@ -71,6 +71,7 @@ namespace Microsoft.Z3
|
|||
Solver solver;
|
||||
Context ctx;
|
||||
Z3_solver_callback callback = IntPtr.Zero;
|
||||
int callbackNesting = 0;
|
||||
FixedEh fixed_eh;
|
||||
Action final_eh;
|
||||
EqEh eq_eh;
|
||||
|
@ -91,6 +92,7 @@ namespace Microsoft.Z3
|
|||
|
||||
void Callback(Action fn, Z3_solver_callback cb)
|
||||
{
|
||||
this.callbackNesting++;
|
||||
this.callback = cb;
|
||||
try
|
||||
{
|
||||
|
@ -102,7 +104,9 @@ namespace Microsoft.Z3
|
|||
}
|
||||
finally
|
||||
{
|
||||
this.callback = IntPtr.Zero;
|
||||
callbackNesting--;
|
||||
if (callbackNesting == 0) // callbacks can be nested (e.g., internalizing new element in "created")
|
||||
this.callback = IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -201,10 +205,20 @@ namespace Microsoft.Z3
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release provate memory.
|
||||
/// Release private memory.
|
||||
/// </summary>
|
||||
~UserPropagator()
|
||||
{
|
||||
Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Must be called. The object will not be garbage collected automatically even if the context is disposed
|
||||
/// </summary>
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if (!gch.IsAllocated)
|
||||
return;
|
||||
gch.Free();
|
||||
if (solver == null)
|
||||
ctx.Dispose();
|
||||
|
|
|
@ -50,12 +50,7 @@ namespace Microsoft.Z3
|
|||
m_n_obj = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (m_ctx != null)
|
||||
{
|
||||
if (Interlocked.Decrement(ref m_ctx.refCount) == 0)
|
||||
GC.ReRegisterForFinalize(m_ctx);
|
||||
m_ctx = null;
|
||||
}
|
||||
m_ctx = null;
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
@ -76,19 +71,15 @@ namespace Microsoft.Z3
|
|||
internal Z3Object(Context ctx)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
|
||||
Interlocked.Increment(ref ctx.refCount);
|
||||
m_ctx = ctx;
|
||||
}
|
||||
|
||||
internal Z3Object(Context ctx, IntPtr obj)
|
||||
{
|
||||
Debug.Assert(ctx != null);
|
||||
|
||||
Interlocked.Increment(ref ctx.refCount);
|
||||
m_ctx = ctx;
|
||||
IncRef(obj);
|
||||
m_n_obj = obj;
|
||||
IncRef(obj);
|
||||
}
|
||||
|
||||
internal virtual void IncRef(IntPtr o) { }
|
||||
|
@ -109,7 +100,7 @@ namespace Microsoft.Z3
|
|||
|
||||
internal static IntPtr GetNativeObject(Z3Object s)
|
||||
{
|
||||
if (s == null) return new IntPtr();
|
||||
if (s == null) return IntPtr.Zero;
|
||||
return s.NativeObject;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,18 @@ public class ArraySort<D extends Sort, R extends Sort> extends Sort
|
|||
Native.getArraySortDomain(getContext().nCtx(), getNativeObject()));
|
||||
}
|
||||
|
||||
/**
|
||||
* The domain of a multi-dimensional array sort.
|
||||
* @throws Z3Exception
|
||||
* @throws Z3Exception on error
|
||||
* @return a sort
|
||||
**/
|
||||
public D getDomain(int idx)
|
||||
{
|
||||
return (D) Sort.create(getContext(),
|
||||
Native.getArraySortDomainN(getContext().nCtx(), getNativeObject(), idx));
|
||||
}
|
||||
|
||||
/**
|
||||
* The range of the array sort.
|
||||
* @throws Z3Exception
|
||||
|
|
|
@ -110,7 +110,7 @@ public class Context implements AutoCloseable {
|
|||
Symbol[] mkSymbols(String[] names)
|
||||
{
|
||||
if (names == null)
|
||||
return null;
|
||||
return new Symbol[0];
|
||||
Symbol[] result = new Symbol[names.length];
|
||||
for (int i = 0; i < names.length; ++i)
|
||||
result[i] = mkSymbol(names[i]);
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Arith, Bool, Model, Z3AssertionError, Z3HighLevel } from './types';
|
|||
*
|
||||
* **NOTE**: The set of solutions might be infinite.
|
||||
* Always ensure to limit amount generated, either by knowing that the
|
||||
* solution space is constrainted, or by taking only a specified
|
||||
* solution space is constrained, or by taking only a specified
|
||||
* amount of solutions
|
||||
* ```typescript
|
||||
* import { sliceAsync } from 'iter-tools';
|
||||
|
@ -46,7 +46,7 @@ async function* allSolutions<Name extends string>(...assertions: Bool<Name>[]):
|
|||
.filter(decl => decl.arity() === 0)
|
||||
.map(decl => {
|
||||
const term = decl.call();
|
||||
// TODO(ritave): Assert not an array / uinterpeted sort
|
||||
// TODO(ritave): Assert not an array / uninterpreted sort
|
||||
const value = model.eval(term, true);
|
||||
return term.neq(value);
|
||||
}),
|
||||
|
@ -109,6 +109,16 @@ describe('high-level', () => {
|
|||
expect(await solver.check()).toStrictEqual('unsat');
|
||||
});
|
||||
|
||||
it('test loading a solver state from a string', async () => {
|
||||
const { Solver, Not, Int } = api.Context('main');
|
||||
const solver = new Solver();
|
||||
solver.fromString("(declare-const x Int) (assert (and (< x 2) (> x 0)))")
|
||||
expect(await solver.check()).toStrictEqual('sat')
|
||||
const x = Int.const('x')
|
||||
solver.add(Not(x.eq(1)))
|
||||
expect(await solver.check()).toStrictEqual('unsat')
|
||||
});
|
||||
|
||||
it('disproves x = y implies g(g(x)) = g(y)', async () => {
|
||||
const { Solver, Int, Function, Implies, Not } = api.Context('main');
|
||||
const solver = new Solver();
|
||||
|
|
|
@ -224,6 +224,12 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
function _toExpr(ast: Z3_ast): Bool<Name> | IntNum<Name> | RatNum<Name> | Arith<Name> | Expr<Name> {
|
||||
const kind = check(Z3.get_ast_kind(contextPtr, ast));
|
||||
if (kind === Z3_ast_kind.Z3_QUANTIFIER_AST) {
|
||||
if (Z3.is_quantifier_forall(contextPtr, ast))
|
||||
return new BoolImpl(ast);
|
||||
if (Z3.is_quantifier_exists(contextPtr, ast))
|
||||
return new BoolImpl(ast);
|
||||
if (Z3.is_lambda(contextPtr, ast))
|
||||
return new ExprImpl(ast);
|
||||
assert(false);
|
||||
}
|
||||
const sortKind = check(Z3.get_sort_kind(contextPtr, Z3.get_sort(contextPtr, ast)));
|
||||
|
@ -1012,6 +1018,11 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
toString() {
|
||||
return check(Z3.solver_to_string(contextPtr, this.ptr));
|
||||
}
|
||||
|
||||
fromString(s : string) {
|
||||
Z3.solver_from_string(contextPtr, this.ptr, s);
|
||||
throwIfError();
|
||||
}
|
||||
}
|
||||
|
||||
class ModelImpl implements Model<Name> {
|
||||
|
|
|
@ -398,6 +398,7 @@ export interface Solver<Name extends string = 'main'> {
|
|||
add(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): void;
|
||||
addAndTrack(expr: Bool<Name>, constant: Bool<Name> | string): void;
|
||||
assertions(): AstVector<Name, Bool<Name>>;
|
||||
fromString(s : string): void;
|
||||
check(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): Promise<CheckSatResult>;
|
||||
model(): Model<Name>;
|
||||
}
|
||||
|
@ -616,7 +617,7 @@ export interface Arith<Name extends string = 'main'> extends Expr<Name, ArithSor
|
|||
*/
|
||||
mul(other: Arith<Name> | number | bigint | string): Arith<Name>;
|
||||
/**
|
||||
* Substract second number from the first one
|
||||
* Subtract second number from the first one
|
||||
*/
|
||||
sub(other: Arith<Name> | number | bigint | string): Arith<Name>;
|
||||
/**
|
||||
|
@ -708,7 +709,7 @@ export interface RatNum<Name extends string = 'main'> extends Arith<Name> {
|
|||
}
|
||||
|
||||
/**
|
||||
* A Sort represting Bit Vector numbers of specified {@link BitVecSort.size size}
|
||||
* A Sort representing Bit Vector numbers of specified {@link BitVecSort.size size}
|
||||
*
|
||||
* @typeParam Bits - A number representing amount of bits for this sort
|
||||
* @category Bit Vectors
|
||||
|
@ -877,42 +878,42 @@ export interface BitVec<Bits extends number = number, Name extends string = 'mai
|
|||
|
||||
/**
|
||||
* Creates a signed less-or-equal operation (`<=`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
sle(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates an unsigned less-or-equal operation (`<=`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
ule(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates a signed less-than operation (`<`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
slt(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates an unsigned less-than operation (`<`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
ult(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates a signed greater-or-equal operation (`>=`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
sge(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates an unsigned greater-or-equal operation (`>=`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
uge(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates a signed greater-than operation (`>`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
sgt(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
/**
|
||||
* Creates an unsigned greater-than operation (`>`)
|
||||
* @category Comparision
|
||||
* @category Comparison
|
||||
*/
|
||||
ugt(other: CoercibleToBitVec<Bits, Name>): Bool<Name>;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include "jlcxx/jlcxx.hpp"
|
||||
#include <sstream>
|
||||
#include "z3++.h"
|
||||
|
||||
using namespace z3;
|
||||
|
|
|
@ -39,7 +39,7 @@ $ ldd ./run
|
|||
/lib64/ld-linux-x86-64.so.2 (0x00007fb570de9000)
|
||||
```
|
||||
|
||||
The bytecode version will have a depedency on z3 and other external
|
||||
The bytecode version will have a dependency on z3 and other external
|
||||
libraries (packed as dlls and usually installed in opam switch):
|
||||
```
|
||||
$ ocamlobjinfo run | grep 'Used DLL' -A5
|
||||
|
@ -126,7 +126,7 @@ Using Dynlink
|
|||
-------------
|
||||
|
||||
The built z3ml.cmxs file is a self-contained shared library that
|
||||
doesn't have any depndencies on z3 (the z3 code is included in it) and
|
||||
doesn't have any dependencies on z3 (the z3 code is included in it) and
|
||||
could be loaded with `Dynlink.loadfile` in runtime.
|
||||
|
||||
Installation
|
||||
|
|
|
@ -122,7 +122,7 @@ bool array_decl_plugin::is_array_sort(sort* s) const {
|
|||
|
||||
func_decl * array_decl_plugin::mk_const(sort * s, unsigned arity, sort * const * domain) {
|
||||
if (arity != 1) {
|
||||
m_manager->raise_exception("invalid const array definition, invalid domain size");
|
||||
m_manager->raise_exception("invalid const array definition, expected one argument");
|
||||
return nullptr;
|
||||
}
|
||||
if (!is_array_sort(s)) {
|
||||
|
@ -326,7 +326,9 @@ func_decl * array_decl_plugin::mk_array_ext(unsigned arity, sort * const * domai
|
|||
}
|
||||
sort * r = to_sort(s->get_parameter(i).get_ast());
|
||||
parameter param(i);
|
||||
return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, func_decl_info(m_family_id, OP_ARRAY_EXT, 1, ¶m));
|
||||
func_decl_info info(func_decl_info(m_family_id, OP_ARRAY_EXT, 1, ¶m));
|
||||
info.set_commutative(true);
|
||||
return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, info);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -178,6 +178,7 @@ public:
|
|||
bool is_default(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_DEFAULT); }
|
||||
bool is_subset(expr const* n) const { return is_app_of(n, m_fid, OP_SET_SUBSET); }
|
||||
bool is_as_array(func_decl* f, func_decl*& g) const { return is_decl_of(f, m_fid, OP_AS_ARRAY) && (g = get_as_array_func_decl(f), true); }
|
||||
bool is_map(func_decl* f, func_decl*& g) const { return is_map(f) && (g = get_map_func_decl(f), true); }
|
||||
func_decl * get_as_array_func_decl(expr * n) const;
|
||||
func_decl * get_as_array_func_decl(func_decl* f) const;
|
||||
func_decl * get_map_func_decl(func_decl* f) const;
|
||||
|
|
|
@ -889,8 +889,10 @@ void basic_decl_plugin::set_manager(ast_manager * m, family_id id) {
|
|||
}
|
||||
|
||||
void basic_decl_plugin::get_sort_names(svector<builtin_name> & sort_names, symbol const & logic) {
|
||||
if (logic == symbol::null)
|
||||
if (logic == symbol::null) {
|
||||
sort_names.push_back(builtin_name("bool", BOOL_SORT));
|
||||
sort_names.push_back(builtin_name("Proof", PROOF_SORT)); // reserved name?
|
||||
}
|
||||
sort_names.push_back(builtin_name("Bool", BOOL_SORT));
|
||||
}
|
||||
|
||||
|
@ -3025,11 +3027,23 @@ proof * ast_manager::mk_unit_resolution(unsigned num_proofs, proof * const * pro
|
|||
found_complement = true;
|
||||
}
|
||||
}
|
||||
// patch to deal with lambdas introduced during search.
|
||||
// lambdas can occur in terms both internalized and in raw form.
|
||||
if (!found_complement && !is_or(f1) && num_proofs == 2) {
|
||||
args.push_back(proofs[0]);
|
||||
args.push_back(proofs[1]);
|
||||
args.push_back(mk_false());
|
||||
found_complement = true;
|
||||
}
|
||||
|
||||
if (!found_complement) {
|
||||
args.append(num_proofs, (expr**)proofs);
|
||||
CTRACE("mk_unit_resolution_bug", !is_or(f1), tout << mk_ll_pp(f1, *this) << "\n";
|
||||
for (unsigned i = 1; i < num_proofs; ++i)
|
||||
tout << mk_pp(proofs[i], *this) << "\n";
|
||||
tout << "facts\n";
|
||||
for (unsigned i = 0; i < num_proofs; ++i)
|
||||
tout << mk_pp(get_fact(proofs[i]), *this) << "\n";
|
||||
);
|
||||
SASSERT(is_or(f1));
|
||||
ptr_buffer<expr> new_lits;
|
||||
|
|
|
@ -531,6 +531,13 @@ public:
|
|||
#endif
|
||||
};
|
||||
|
||||
#define MATCH_QUATARY(_MATCHER_) \
|
||||
bool _MATCHER_(expr const* n, expr*& a1, expr*& a2, expr *& a3, expr *& a4) const { \
|
||||
if (_MATCHER_(n) && to_app(n)->get_num_args() == 4) { \
|
||||
a1 = to_app(n)->get_arg(0); a2 = to_app(n)->get_arg(1); a3 = to_app(n)->get_arg(2); a4 = to_app(n)->get_arg(3); return true; } \
|
||||
return false; \
|
||||
}
|
||||
|
||||
#define MATCH_TERNARY(_MATCHER_) \
|
||||
bool _MATCHER_(expr const* n, expr*& a1, expr*& a2, expr *& a3) const { \
|
||||
if (_MATCHER_(n) && to_app(n)->get_num_args() == 3) { \
|
||||
|
@ -1024,7 +1031,7 @@ protected:
|
|||
friend class ast_manager;
|
||||
|
||||
public:
|
||||
virtual ~decl_plugin() {}
|
||||
virtual ~decl_plugin() = default;
|
||||
virtual void finalize() {}
|
||||
|
||||
|
||||
|
@ -2582,7 +2589,7 @@ class ast_mark {
|
|||
obj_mark<expr> m_expr_marks;
|
||||
obj_mark<decl, bit_vector, decl2uint> m_decl_marks;
|
||||
public:
|
||||
virtual ~ast_mark() {}
|
||||
virtual ~ast_mark() = default;
|
||||
bool is_marked(ast * n) const;
|
||||
virtual void mark(ast * n, bool flag);
|
||||
virtual void reset();
|
||||
|
|
|
@ -64,6 +64,17 @@ void ast_pp_util::display_decls(std::ostream& out) {
|
|||
m_rec_decls = n;
|
||||
}
|
||||
|
||||
void ast_pp_util::display_skolem_decls(std::ostream& out) {
|
||||
ast_smt_pp pp(m);
|
||||
unsigned n = coll.get_num_decls();
|
||||
for (unsigned i = m_decls; i < n; ++i) {
|
||||
func_decl* f = coll.get_func_decls()[i];
|
||||
if (f->get_family_id() == null_family_id && !m_removed.contains(f) && f->is_skolem())
|
||||
ast_smt2_pp(out, f, m_env) << "\n";
|
||||
}
|
||||
m_decls = n;
|
||||
}
|
||||
|
||||
void ast_pp_util::remove_decl(func_decl* f) {
|
||||
m_removed.insert(f);
|
||||
}
|
||||
|
@ -118,6 +129,7 @@ void ast_pp_util::push() {
|
|||
m_rec_decls.push();
|
||||
m_decls.push();
|
||||
m_sorts.push();
|
||||
m_defined_lim.push_back(m_defined.size());
|
||||
}
|
||||
|
||||
void ast_pp_util::pop(unsigned n) {
|
||||
|
@ -125,4 +137,55 @@ void ast_pp_util::pop(unsigned n) {
|
|||
m_rec_decls.pop(n);
|
||||
m_decls.pop(n);
|
||||
m_sorts.pop(n);
|
||||
unsigned old_sz = m_defined_lim[m_defined_lim.size() - n];
|
||||
for (unsigned i = m_defined.size(); i-- > old_sz; )
|
||||
m_is_defined.mark(m_defined.get(i), false);
|
||||
m_defined.shrink(old_sz);
|
||||
m_defined_lim.shrink(m_defined_lim.size() - n);
|
||||
}
|
||||
|
||||
std::ostream& ast_pp_util::display_expr_def(std::ostream& out, expr* n) {
|
||||
if (is_app(n) && to_app(n)->get_num_args() == 0)
|
||||
return out << mk_pp(n, m);
|
||||
else
|
||||
return out << "$" << n->get_id();
|
||||
}
|
||||
|
||||
std::ostream& ast_pp_util::define_expr(std::ostream& out, expr* n) {
|
||||
ptr_buffer<expr> visit;
|
||||
visit.push_back(n);
|
||||
while (!visit.empty()) {
|
||||
n = visit.back();
|
||||
if (m_is_defined.is_marked(n)) {
|
||||
visit.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (is_app(n)) {
|
||||
bool all_visit = true;
|
||||
for (auto* e : *to_app(n)) {
|
||||
if (m_is_defined.is_marked(e))
|
||||
continue;
|
||||
all_visit = false;
|
||||
visit.push_back(e);
|
||||
}
|
||||
if (!all_visit)
|
||||
continue;
|
||||
m_defined.push_back(n);
|
||||
m_is_defined.mark(n, true);
|
||||
visit.pop_back();
|
||||
if (to_app(n)->get_num_args() > 0) {
|
||||
out << "(define-const $" << n->get_id() << " " << mk_pp(n->get_sort(), m) << " (";
|
||||
out << mk_ismt2_func(to_app(n)->get_decl(), m);
|
||||
for (auto* e : *to_app(n))
|
||||
display_expr_def(out << " ", e);
|
||||
out << "))\n";
|
||||
}
|
||||
continue;
|
||||
}
|
||||
out << "(define-const $" << n->get_id() << " " << mk_pp(n->get_sort(), m) << " " << mk_pp(n, m) << ")\n";
|
||||
m_defined.push_back(n);
|
||||
m_is_defined.mark(n, true);
|
||||
visit.pop_back();
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -30,15 +30,18 @@ class ast_pp_util {
|
|||
stacked_value<unsigned> m_rec_decls;
|
||||
stacked_value<unsigned> m_decls;
|
||||
stacked_value<unsigned> m_sorts;
|
||||
expr_mark m_is_defined;
|
||||
expr_ref_vector m_defined;
|
||||
unsigned_vector m_defined_lim;
|
||||
|
||||
public:
|
||||
|
||||
decl_collector coll;
|
||||
|
||||
ast_pp_util(ast_manager& m): m(m), m_env(m), m_rec_decls(0), m_decls(0), m_sorts(0), m_defined(m), coll(m) {}
|
||||
|
||||
ast_pp_util(ast_manager& m): m(m), m_env(m), m_rec_decls(0), m_decls(0), m_sorts(0), coll(m) {}
|
||||
|
||||
void reset() { coll.reset(); m_removed.reset(); m_sorts.clear(0u); m_decls.clear(0u); m_rec_decls.clear(0u); }
|
||||
|
||||
void reset() { coll.reset(); m_removed.reset(); m_sorts.clear(0u); m_decls.clear(0u); m_rec_decls.clear(0u);
|
||||
m_is_defined.reset(); m_defined.reset(); m_defined_lim.reset(); }
|
||||
|
||||
void collect(expr* e);
|
||||
|
||||
|
@ -50,6 +53,8 @@ class ast_pp_util {
|
|||
|
||||
void display_decls(std::ostream& out);
|
||||
|
||||
void display_skolem_decls(std::ostream& out);
|
||||
|
||||
void display_asserts(std::ostream& out, expr_ref_vector const& fmls, bool neat = true);
|
||||
|
||||
void display_assert(std::ostream& out, expr* f, bool neat = true);
|
||||
|
@ -58,6 +63,10 @@ class ast_pp_util {
|
|||
|
||||
std::ostream& display_expr(std::ostream& out, expr* f, bool neat = true);
|
||||
|
||||
std::ostream& define_expr(std::ostream& out, expr* f);
|
||||
|
||||
std::ostream& display_expr_def(std::ostream& out, expr* f);
|
||||
|
||||
void push();
|
||||
|
||||
void pop(unsigned n);
|
||||
|
|
|
@ -24,7 +24,7 @@ Revision History:
|
|||
|
||||
class ast_printer {
|
||||
public:
|
||||
virtual ~ast_printer() {}
|
||||
virtual ~ast_printer() = default;
|
||||
virtual void pp(sort * s, format_ns::format_ref & r) const { UNREACHABLE(); }
|
||||
virtual void pp(func_decl * f, format_ns::format_ref & r) const { UNREACHABLE(); }
|
||||
virtual void pp(expr * n, unsigned num_vars, char const * var_prefix, format_ns::format_ref & r, sbuffer<symbol> & var_names) const { UNREACHABLE(); }
|
||||
|
|
|
@ -46,7 +46,7 @@ protected:
|
|||
format_ns::format * pp_as(format_ns::format * fname, sort * s);
|
||||
format_ns::format * pp_signature(format_ns::format * f_name, func_decl * f);
|
||||
public:
|
||||
virtual ~smt2_pp_environment() {}
|
||||
virtual ~smt2_pp_environment() = default;
|
||||
virtual ast_manager & get_manager() const = 0;
|
||||
virtual arith_util & get_autil() = 0;
|
||||
virtual bv_util & get_bvutil() = 0;
|
||||
|
|
|
@ -620,7 +620,7 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
|
|||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
if (args[i]->get_sort() != r->get_domain(i)) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "Argument " << mk_pp(args[i], m) << " at position " << i << " does not match declaration " << mk_pp(r, m);
|
||||
buffer << "Argument " << mk_pp(args[i], m) << " at position " << i << " has sort " << mk_pp(args[i]->get_sort(), m) << " it does does not match declaration " << mk_pp(r, m);
|
||||
m.raise_exception(buffer.str());
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -635,6 +635,28 @@ namespace datatype {
|
|||
}
|
||||
}
|
||||
|
||||
bool plugin::are_distinct(app * a, app * b) const {
|
||||
if (a == b)
|
||||
return false;
|
||||
if (is_unique_value(a) && is_unique_value(b))
|
||||
return true;
|
||||
if (u().is_constructor(a) && u().is_constructor(b)) {
|
||||
if (a->get_decl() != b->get_decl())
|
||||
return true;
|
||||
for (unsigned i = a->get_num_args(); i-- > 0; ) {
|
||||
if (!is_app(a->get_arg(i)))
|
||||
continue;
|
||||
if (!is_app(b->get_arg(i)))
|
||||
continue;
|
||||
app* _a = to_app(a->get_arg(i));
|
||||
app* _b = to_app(b->get_arg(i));
|
||||
if (m_manager->are_distinct(_a, _b))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
expr * plugin::get_some_value(sort * s) {
|
||||
SASSERT(u().is_datatype(s));
|
||||
func_decl * c = u().get_non_rec_constructor(s);
|
||||
|
@ -882,18 +904,16 @@ namespace datatype {
|
|||
bool util::is_well_founded(unsigned num_types, sort* const* sorts) {
|
||||
buffer<bool> well_founded(num_types, false);
|
||||
obj_map<sort, unsigned> sort2id;
|
||||
for (unsigned i = 0; i < num_types; ++i) {
|
||||
for (unsigned i = 0; i < num_types; ++i)
|
||||
sort2id.insert(sorts[i], i);
|
||||
}
|
||||
unsigned num_well_founded = 0, id = 0;
|
||||
bool changed;
|
||||
ptr_vector<sort> subsorts;
|
||||
do {
|
||||
changed = false;
|
||||
for (unsigned tid = 0; tid < num_types; tid++) {
|
||||
if (well_founded[tid]) {
|
||||
if (well_founded[tid])
|
||||
continue;
|
||||
}
|
||||
sort* s = sorts[tid];
|
||||
def const& d = get_def(s);
|
||||
for (constructor const* c : d) {
|
||||
|
@ -901,9 +921,12 @@ namespace datatype {
|
|||
subsorts.reset();
|
||||
get_subsorts(a->range(), subsorts);
|
||||
for (sort* srt : subsorts) {
|
||||
if (sort2id.find(srt, id) && !well_founded[id]) {
|
||||
goto next_constructor;
|
||||
if (sort2id.find(srt, id)) {
|
||||
if (!well_founded[id])
|
||||
goto next_constructor;
|
||||
}
|
||||
else if (is_datatype(srt))
|
||||
break;
|
||||
}
|
||||
}
|
||||
changed = true;
|
||||
|
|
|
@ -105,7 +105,7 @@ namespace datatype {
|
|||
class size {
|
||||
unsigned m_ref{ 0 };
|
||||
public:
|
||||
virtual ~size() { }
|
||||
virtual ~size() = default;
|
||||
void inc_ref() { ++m_ref; }
|
||||
void dec_ref();
|
||||
static size* mk_offset(sort_size const& s);
|
||||
|
@ -233,6 +233,8 @@ namespace datatype {
|
|||
bool is_value(app* e) const override { return is_value_aux(false, e); }
|
||||
|
||||
bool is_unique_value(app * e) const override { return is_value_aux(true, e); }
|
||||
|
||||
bool are_distinct(app * a, app * b) const override;
|
||||
|
||||
void get_op_names(svector<builtin_name> & op_names, symbol const & logic) override;
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ bool decl_collector::is_bool(sort * s) {
|
|||
}
|
||||
|
||||
void decl_collector::visit_func(func_decl * n) {
|
||||
func_decl* g;
|
||||
if (!m_visited.is_marked(n)) {
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == null_family_id)
|
||||
|
@ -57,6 +58,8 @@ void decl_collector::visit_func(func_decl * n) {
|
|||
recfun::util u(m());
|
||||
m_todo.push_back(u.get_def(n).get_rhs());
|
||||
}
|
||||
else if (m_ar_util.is_as_array(n, g))
|
||||
m_todo.push_back(g);
|
||||
m_visited.mark(n, true);
|
||||
m_trail.push_back(n);
|
||||
}
|
||||
|
@ -65,7 +68,8 @@ void decl_collector::visit_func(func_decl * n) {
|
|||
decl_collector::decl_collector(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_trail(m),
|
||||
m_dt_util(m) {
|
||||
m_dt_util(m),
|
||||
m_ar_util(m) {
|
||||
m_basic_fid = m_manager.get_basic_family_id();
|
||||
m_dt_fid = m_dt_util.get_family_id();
|
||||
recfun::util rec_util(m);
|
||||
|
@ -156,8 +160,15 @@ void decl_collector::collect_deps(sort* s, sort_set& set) {
|
|||
for (unsigned i = 0; i < num_cnstr; i++) {
|
||||
func_decl * cnstr = m_dt_util.get_datatype_constructors(s)->get(i);
|
||||
set.insert(cnstr->get_range());
|
||||
for (unsigned j = 0; j < cnstr->get_arity(); ++j)
|
||||
set.insert(cnstr->get_domain(j));
|
||||
for (unsigned j = 0; j < cnstr->get_arity(); ++j) {
|
||||
sort* n = cnstr->get_domain(j);
|
||||
set.insert(n);
|
||||
for (unsigned i = n->get_num_parameters(); i-- > 0; ) {
|
||||
parameter const& p = n->get_parameter(i);
|
||||
if (p.is_ast() && is_sort(p.get_ast()))
|
||||
set.insert(to_sort(p.get_ast()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ Revision History:
|
|||
#include "util/lim_vector.h"
|
||||
#include "ast/ast.h"
|
||||
#include "ast/datatype_decl_plugin.h"
|
||||
#include "ast/array_decl_plugin.h"
|
||||
|
||||
class decl_collector {
|
||||
ast_manager & m_manager;
|
||||
|
@ -35,6 +36,7 @@ class decl_collector {
|
|||
family_id m_basic_fid;
|
||||
family_id m_dt_fid;
|
||||
datatype_util m_dt_util;
|
||||
array_util m_ar_util;
|
||||
family_id m_rec_fid;
|
||||
ptr_vector<ast> m_todo;
|
||||
|
||||
|
|
|
@ -27,14 +27,14 @@ Revision History:
|
|||
class i_expr_pred {
|
||||
public:
|
||||
virtual bool operator()(expr* e) = 0;
|
||||
virtual ~i_expr_pred() {}
|
||||
virtual ~i_expr_pred() = default;
|
||||
};
|
||||
|
||||
|
||||
class i_sort_pred {
|
||||
public:
|
||||
virtual bool operator()(sort* s) = 0;
|
||||
virtual ~i_sort_pred() {}
|
||||
virtual ~i_sort_pred() = default;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -147,11 +147,36 @@ void fpa2bv_converter::mk_distinct(func_decl * f, unsigned num, expr * const * a
|
|||
|
||||
void fpa2bv_converter::mk_numeral(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num == 0);
|
||||
SASSERT(f->get_num_parameters() == 1);
|
||||
SASSERT(f->get_parameter(0).is_external());
|
||||
unsigned p_id = f->get_parameter(0).get_ext_id();
|
||||
mpf const & v = m_plugin->get_value(p_id);
|
||||
mk_numeral(f->get_range(), v, result);
|
||||
sort* s = f->get_range();
|
||||
if (f->get_num_parameters() == 1) {
|
||||
SASSERT(f->get_parameter(0).is_external());
|
||||
unsigned p_id = f->get_parameter(0).get_ext_id();
|
||||
mpf const& v = m_plugin->get_value(p_id);
|
||||
mk_numeral(s, v, result);
|
||||
return;
|
||||
}
|
||||
scoped_mpf v(m_mpf_manager);
|
||||
unsigned ebits = m_util.get_ebits(s), sbits = m_util.get_sbits(s);
|
||||
switch (f->get_decl_kind()) {
|
||||
case OP_FPA_PLUS_INF:
|
||||
m_util.fm().mk_pinf(ebits, sbits, v);
|
||||
break;
|
||||
case OP_FPA_MINUS_INF:
|
||||
m_util.fm().mk_ninf(ebits, sbits, v);
|
||||
break;
|
||||
case OP_FPA_NAN:
|
||||
m_util.fm().mk_nan(ebits, sbits, v);
|
||||
break;
|
||||
case OP_FPA_PLUS_ZERO:
|
||||
m_util.fm().mk_pzero(ebits, sbits, v);
|
||||
break;
|
||||
case OP_FPA_MINUS_ZERO:
|
||||
m_util.fm().mk_nzero(ebits, sbits, v);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
mk_numeral(s, v, result);
|
||||
}
|
||||
|
||||
void fpa2bv_converter::mk_numeral(sort * s, mpf const & v, expr_ref & result) {
|
||||
|
@ -3406,8 +3431,14 @@ void fpa2bv_converter::mk_to_bv(func_decl * f, unsigned num, expr * const * args
|
|||
}
|
||||
else {
|
||||
expr_ref ll(m);
|
||||
ll = m_bv_util.mk_sign_extend(3, m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz-1)));
|
||||
ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, bv_sz-1)));
|
||||
ll = bv1;
|
||||
if (bv_sz > 1)
|
||||
ll = m_bv_util.mk_concat(bv1, m_bv_util.mk_numeral(0, bv_sz - 1));
|
||||
ll = m_bv_util.mk_sign_extend(3, ll);
|
||||
if (bv_sz > 1)
|
||||
ul = m_bv_util.mk_zero_extend(4, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, bv_sz - 1)));
|
||||
else
|
||||
ul = m_bv_util.mk_numeral(0, 4);
|
||||
ovfl = m.mk_or(ovfl, m_bv_util.mk_sle(pre_rounded, m_bv_util.mk_bv_neg(m_bv_util.mk_numeral(1, bv_sz + 3))));
|
||||
pre_rounded = m.mk_ite(x_is_neg, m_bv_util.mk_bv_neg(pre_rounded), pre_rounded);
|
||||
in_range = m.mk_and(m.mk_not(ovfl),
|
||||
|
|
|
@ -376,7 +376,17 @@ bool macro_finder::expand_macros(unsigned num, justified_expr const * fmls, vect
|
|||
return found_new_macro;
|
||||
}
|
||||
|
||||
void macro_finder::revert_unsafe_macros(vector<justified_expr>& new_fmls) {
|
||||
auto& unsafe_macros = m_macro_manager.unsafe_macros();
|
||||
for (auto* f : unsafe_macros) {
|
||||
quantifier* q = m_macro_manager.get_macro_quantifier(f);
|
||||
new_fmls.push_back(justified_expr(m, q, nullptr));
|
||||
}
|
||||
unsafe_macros.reset();
|
||||
}
|
||||
|
||||
void macro_finder::operator()(unsigned n, justified_expr const* fmls, vector<justified_expr>& new_fmls) {
|
||||
m_macro_manager.unsafe_macros().reset();
|
||||
TRACE("macro_finder", tout << "processing macros...\n";);
|
||||
vector<justified_expr> _new_fmls;
|
||||
if (expand_macros(n, fmls, _new_fmls)) {
|
||||
|
@ -388,6 +398,7 @@ void macro_finder::operator()(unsigned n, justified_expr const* fmls, vector<jus
|
|||
break;
|
||||
}
|
||||
}
|
||||
revert_unsafe_macros(_new_fmls);
|
||||
new_fmls.append(_new_fmls);
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ class macro_finder {
|
|||
|
||||
bool is_macro(expr * n, app_ref & head, expr_ref & def);
|
||||
|
||||
void revert_unsafe_macros(vector<justified_expr>& new_fmls);
|
||||
|
||||
public:
|
||||
macro_finder(ast_manager & m, macro_manager & mm);
|
||||
~macro_finder();
|
||||
|
|
|
@ -241,12 +241,14 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter
|
|||
struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
|
||||
ast_manager& m;
|
||||
macro_manager& mm;
|
||||
array_util a;
|
||||
expr_dependency_ref m_used_macro_dependencies;
|
||||
expr_ref_vector m_trail;
|
||||
|
||||
macro_expander_cfg(ast_manager& m, macro_manager& mm):
|
||||
m(m),
|
||||
mm(mm),
|
||||
a(m),
|
||||
m_used_macro_dependencies(m),
|
||||
m_trail(m)
|
||||
{}
|
||||
|
@ -296,7 +298,7 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
|
|||
return false;
|
||||
app * n = to_app(_n);
|
||||
quantifier * q = nullptr;
|
||||
func_decl * d = n->get_decl();
|
||||
func_decl * d = n->get_decl(), *d2 = nullptr;
|
||||
TRACE("macro_manager", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";);
|
||||
if (mm.m_decl2macro.find(d, q)) {
|
||||
app * head = nullptr;
|
||||
|
@ -343,6 +345,12 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
|
|||
m_used_macro_dependencies = m.mk_join(m_used_macro_dependencies, ed);
|
||||
return true;
|
||||
}
|
||||
else if (a.is_as_array(d, d2) && mm.m_decl2macro.find(d2, q)) {
|
||||
mm.unsafe_macros().insert(d2);
|
||||
}
|
||||
else if (a.is_map(d, d2) && mm.m_decl2macro.find(d2, q)) {
|
||||
mm.unsafe_macros().insert(d2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -29,7 +29,7 @@ Revision History:
|
|||
\brief Macros are universally quantified formulas of the form:
|
||||
(forall X (= (f X) T[X]))
|
||||
(forall X (iff (f X) T[X]))
|
||||
where T[X] does not contain X.
|
||||
where T[X] does not contain f.
|
||||
|
||||
This class is responsible for storing macros and expanding them.
|
||||
It has support for backtracking and tagging declarations in an expression as forbidded for being macros.
|
||||
|
@ -47,6 +47,7 @@ class macro_manager {
|
|||
expr_dependency_ref_vector m_macro_deps;
|
||||
obj_hashtable<func_decl> m_forbidden_set;
|
||||
func_decl_ref_vector m_forbidden;
|
||||
obj_hashtable<func_decl> m_unsafe_macros;
|
||||
struct scope {
|
||||
unsigned m_decls_lim;
|
||||
unsigned m_forbidden_lim;
|
||||
|
@ -86,7 +87,7 @@ public:
|
|||
quantifier * get_macro_quantifier(func_decl * f) const { quantifier * q = nullptr; m_decl2macro.find(f, q); return q; }
|
||||
void get_head_def(quantifier * q, func_decl * d, app * & head, expr_ref & def, bool& revert) const;
|
||||
void expand_macros(expr * n, proof * pr, expr_dependency * dep, expr_ref & r, proof_ref & new_pr, expr_dependency_ref & new_dep);
|
||||
|
||||
obj_hashtable<func_decl>& unsafe_macros() { return m_unsafe_macros; }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ protected:
|
|||
void collect_macro_candidates(quantifier* q);
|
||||
public:
|
||||
quantifier_macro_info(ast_manager& m, quantifier* q);
|
||||
virtual ~quantifier_macro_info() {}
|
||||
virtual ~quantifier_macro_info() = default;
|
||||
bool is_auf() const { return m_is_auf; }
|
||||
quantifier* get_flat_q() const { return m_flat_q; }
|
||||
bool has_cond_macros() const { return !m_cond_macros.empty(); }
|
||||
|
|
|
@ -31,7 +31,7 @@ public:
|
|||
elim_term_ite_cfg(ast_manager & m, defined_names & d): m(m), m_defined_names(d) {
|
||||
// TBD enable_ac_support(false);
|
||||
}
|
||||
virtual ~elim_term_ite_cfg() {}
|
||||
virtual ~elim_term_ite_cfg() = default;
|
||||
vector<justified_expr> const& new_defs() const { return m_new_defs; }
|
||||
br_status reduce_app(func_decl* f, unsigned n, expr *const* args, expr_ref& result, proof_ref& result_pr);
|
||||
void push() { m_lim.push_back(m_new_defs.size()); }
|
||||
|
|
|
@ -29,7 +29,7 @@ public:
|
|||
|
||||
class name_exprs {
|
||||
public:
|
||||
virtual ~name_exprs() {}
|
||||
virtual ~name_exprs() = default;
|
||||
virtual void operator()(expr * n, // [IN] expression that contain the sub-expressions to be named
|
||||
expr_ref_vector & new_defs, // [OUT] new definitions
|
||||
proof_ref_vector & new_def_proofs, // [OUT] proofs of the new definitions
|
||||
|
|
|
@ -66,7 +66,6 @@ void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p)
|
|||
bool single_line = p.single_line();
|
||||
|
||||
unsigned pos = 0;
|
||||
unsigned ribbon_pos = 0;
|
||||
unsigned line = 0;
|
||||
unsigned len;
|
||||
unsigned i;
|
||||
|
@ -92,7 +91,6 @@ void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p)
|
|||
break;
|
||||
}
|
||||
pos += len;
|
||||
ribbon_pos += len;
|
||||
out << f->get_decl()->get_parameter(0).get_symbol();
|
||||
break;
|
||||
case OP_INDENT:
|
||||
|
@ -121,7 +119,6 @@ void pp(std::ostream & out, format * f, ast_manager & m, params_ref const & _p)
|
|||
break;
|
||||
}
|
||||
pos = indent;
|
||||
ribbon_pos = 0;
|
||||
line++;
|
||||
if (line < max_num_lines) {
|
||||
out << "\n";
|
||||
|
|
|
@ -291,7 +291,11 @@ namespace recfun {
|
|||
expr * e = stack.back();
|
||||
stack.pop_back();
|
||||
|
||||
if (m.is_ite(e)) {
|
||||
expr* cond = nullptr, *th = nullptr, *el = nullptr;
|
||||
if (m.is_ite(e, cond, th, el) && contains_def(u, cond)) {
|
||||
// skip
|
||||
}
|
||||
else if (m.is_ite(e)) {
|
||||
// need to do a case split on `e`, forking the search space
|
||||
b.to_split = st.cons_ite(to_app(e), b.to_split);
|
||||
}
|
||||
|
@ -338,9 +342,8 @@ namespace recfun {
|
|||
|
||||
// substitute, to get rid of `ite` terms
|
||||
expr_ref case_rhs = subst(rhs);
|
||||
for (unsigned i = 0; i < conditions.size(); ++i) {
|
||||
for (unsigned i = 0; i < conditions.size(); ++i)
|
||||
conditions[i] = subst(conditions.get(i));
|
||||
}
|
||||
|
||||
// yield new case
|
||||
bool is_imm = is_i(case_rhs);
|
||||
|
@ -471,9 +474,8 @@ namespace recfun {
|
|||
|
||||
void plugin::set_definition(replace& r, promise_def & d, bool is_macro, unsigned n_vars, var * const * vars, expr * rhs) {
|
||||
u().set_definition(r, d, is_macro, n_vars, vars, rhs);
|
||||
for (case_def & c : d.get_def()->get_cases()) {
|
||||
for (case_def & c : d.get_def()->get_cases())
|
||||
m_case_defs.insert(c.get_decl(), &c);
|
||||
}
|
||||
}
|
||||
|
||||
bool plugin::has_defs() const {
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace recfun {
|
|||
|
||||
class replace {
|
||||
public:
|
||||
virtual ~replace() {}
|
||||
virtual ~replace() = default;
|
||||
virtual void reset() = 0;
|
||||
virtual void insert(expr* d, expr* r) = 0;
|
||||
virtual expr_ref operator()(expr* e) = 0;
|
||||
|
|
|
@ -706,6 +706,31 @@ br_status arith_rewriter::mk_eq_core(expr * arg1, expr * arg2, expr_ref & result
|
|||
return st;
|
||||
}
|
||||
|
||||
br_status arith_rewriter::mk_and_core(unsigned n, expr* const* args, expr_ref& result) {
|
||||
if (n <= 1)
|
||||
return BR_FAILED;
|
||||
expr* x, * y, * z, * u;
|
||||
rational a, b;
|
||||
if (m_util.is_le(args[0], x, y) && m_util.is_numeral(x, a)) {
|
||||
expr* arg0 = args[0];
|
||||
ptr_buffer<expr> rest;
|
||||
for (unsigned i = 1; i < n; ++i) {
|
||||
if (m_util.is_le(args[i], z, u) && u == y && m_util.is_numeral(z, b)) {
|
||||
if (b > a)
|
||||
arg0 = args[i];
|
||||
}
|
||||
else
|
||||
rest.push_back(args[i]);
|
||||
}
|
||||
if (rest.size() < n - 1) {
|
||||
rest.push_back(arg0);
|
||||
result = m().mk_and(rest);
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
}
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
||||
bool arith_rewriter::mk_eq_mod(expr* arg1, expr* arg2, expr_ref& result) {
|
||||
expr* x = nullptr, *y = nullptr, *z = nullptr, *u = nullptr;
|
||||
rational p, k, l;
|
||||
|
|
|
@ -149,6 +149,8 @@ public:
|
|||
|
||||
br_status mk_abs_core(expr * arg, expr_ref & result);
|
||||
|
||||
br_status mk_and_core(unsigned n, expr* const* args, expr_ref& result);
|
||||
|
||||
br_status mk_div_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result);
|
||||
br_status mk_idivides(unsigned k, expr * arg, expr_ref & result);
|
||||
|
|
|
@ -86,12 +86,11 @@ br_status array_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
|
|||
// l_true -- all equal
|
||||
// l_false -- at least one disequal
|
||||
// l_undef -- don't know
|
||||
template<bool CHECK_DISEQ>
|
||||
lbool array_rewriter::compare_args(unsigned num_args, expr * const * args1, expr * const * args2) {
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
if (args1[i] == args2[i])
|
||||
continue;
|
||||
if (CHECK_DISEQ && m().are_distinct(args1[i], args2[i]))
|
||||
if (m().are_distinct(args1[i], args2[i]))
|
||||
return l_false;
|
||||
return l_undef;
|
||||
}
|
||||
|
@ -102,9 +101,7 @@ br_status array_rewriter::mk_store_core(unsigned num_args, expr * const * args,
|
|||
SASSERT(num_args >= 3);
|
||||
|
||||
if (m_util.is_store(args[0])) {
|
||||
lbool r = m_sort_store ?
|
||||
compare_args<true>(num_args - 2, args + 1, to_app(args[0])->get_args() + 1) :
|
||||
compare_args<false>(num_args - 2, args + 1, to_app(args[0])->get_args() + 1);
|
||||
lbool r = compare_args(num_args - 2, args + 1, to_app(args[0])->get_args() + 1);
|
||||
switch (r) {
|
||||
case l_true: {
|
||||
//
|
||||
|
@ -118,12 +115,11 @@ br_status array_rewriter::mk_store_core(unsigned num_args, expr * const * args,
|
|||
return BR_DONE;
|
||||
}
|
||||
case l_false:
|
||||
SASSERT(m_sort_store);
|
||||
//
|
||||
// store(store(a,i,v),j,w) -> store(store(a,j,w),i,v)
|
||||
// if i, j are different, lt(i,j)
|
||||
//
|
||||
if (lex_lt(num_args-2, args+1, to_app(args[0])->get_args() + 1)) {
|
||||
//
|
||||
if (m_sort_store && lex_lt(num_args-2, args+1, to_app(args[0])->get_args() + 1)) {
|
||||
ptr_buffer<expr> new_args;
|
||||
new_args.push_back(to_app(args[0])->get_arg(0));
|
||||
new_args.append(num_args-1, args+1);
|
||||
|
@ -134,6 +130,9 @@ br_status array_rewriter::mk_store_core(unsigned num_args, expr * const * args,
|
|||
result = m().mk_app(get_fid(), OP_STORE, num_args, new_args.data());
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (squash_store(num_args, args, result))
|
||||
return BR_REWRITE2;
|
||||
|
||||
break;
|
||||
case l_undef:
|
||||
break;
|
||||
|
@ -155,7 +154,7 @@ br_status array_rewriter::mk_store_core(unsigned num_args, expr * const * args,
|
|||
// store(a, i, select(a, i)) --> a
|
||||
//
|
||||
if (m_util.is_select(v) &&
|
||||
compare_args<false>(num_args-1, args, to_app(v)->get_args())) {
|
||||
l_true == compare_args(num_args-1, args, to_app(v)->get_args())) {
|
||||
result = args[0];
|
||||
return BR_DONE;
|
||||
}
|
||||
|
@ -163,19 +162,52 @@ br_status array_rewriter::mk_store_core(unsigned num_args, expr * const * args,
|
|||
return BR_FAILED;
|
||||
}
|
||||
|
||||
bool array_rewriter::squash_store(unsigned n, expr* const* args, expr_ref& result) {
|
||||
ptr_buffer<expr> parents, sargs;
|
||||
expr* a = args[0];
|
||||
while (m_util.is_store(a)) {
|
||||
lbool r = compare_args(n - 2, args + 1, to_app(a)->get_args() + 1);
|
||||
switch (r) {
|
||||
case l_undef:
|
||||
return false;
|
||||
case l_true:
|
||||
result = to_app(a)->get_arg(0);
|
||||
for (unsigned i = parents.size(); i-- > 0; ) {
|
||||
expr* p = parents[i];
|
||||
sargs.reset();
|
||||
sargs.push_back(result);
|
||||
for (unsigned j = 1; j < to_app(p)->get_num_args(); ++j)
|
||||
sargs.push_back(to_app(p)->get_arg(j));
|
||||
result = m_util.mk_store(sargs.size(), sargs.data());
|
||||
}
|
||||
sargs.reset();
|
||||
sargs.push_back(result);
|
||||
for (unsigned j = 1; j < n; ++j)
|
||||
sargs.push_back(args[j]);
|
||||
result = m_util.mk_store(sargs.size(), sargs.data());
|
||||
return true;
|
||||
case l_false:
|
||||
parents.push_back(a);
|
||||
a = to_app(a)->get_arg(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args, expr_ref & result) {
|
||||
SASSERT(num_args >= 2);
|
||||
if (m_util.is_store(args[0])) {
|
||||
SASSERT(to_app(args[0])->get_num_args() == num_args+1);
|
||||
switch (compare_args<true>(num_args - 1, args+1, to_app(args[0])->get_args()+1)) {
|
||||
switch (compare_args(num_args - 1, args+1, to_app(args[0])->get_args()+1)) {
|
||||
case l_true:
|
||||
// select(store(a, I, v), I) --> v
|
||||
result = to_app(args[0])->get_arg(num_args);
|
||||
return BR_DONE;
|
||||
case l_false: {
|
||||
expr* arg0 = to_app(args[0])->get_arg(0);
|
||||
while (m_util.is_store(arg0) && compare_args<true>(num_args-1, args + 1, to_app(arg0)->get_args() + 1) == l_false) {
|
||||
while (m_util.is_store(arg0) && compare_args(num_args-1, args + 1, to_app(arg0)->get_args() + 1) == l_false) {
|
||||
arg0 = to_app(arg0)->get_arg(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@ Notes:
|
|||
*/
|
||||
class array_rewriter {
|
||||
array_util m_util;
|
||||
bool m_sort_store { false };
|
||||
bool m_blast_select_store { false };
|
||||
bool m_expand_select_store { false };
|
||||
bool m_expand_store_eq { false };
|
||||
bool m_expand_select_ite { false };
|
||||
bool m_expand_nested_stores { false };
|
||||
template<bool CHECK_DISEQ>
|
||||
bool m_sort_store = false;
|
||||
bool m_blast_select_store = false;
|
||||
bool m_expand_select_store = false;
|
||||
bool m_expand_store_eq = false;
|
||||
bool m_expand_select_ite = false;
|
||||
bool m_expand_nested_stores = false;
|
||||
|
||||
lbool compare_args(unsigned num_args, expr * const * args1, expr * const * args2);
|
||||
void mk_eq(expr* e, expr* lhs, expr* rhs, expr_ref_vector& fmls);
|
||||
|
||||
|
@ -45,6 +45,8 @@ class array_rewriter {
|
|||
bool is_expandable_store(expr* s);
|
||||
expr_ref expand_store(expr* s);
|
||||
|
||||
bool squash_store(unsigned n, expr* const* args, expr_ref& result);
|
||||
|
||||
public:
|
||||
array_rewriter(ast_manager & m, params_ref const & p = params_ref()):
|
||||
m_util(m) {
|
||||
|
|
|
@ -175,7 +175,7 @@ br_status bool_rewriter::mk_flat_and_core(unsigned num_args, expr * const * args
|
|||
}
|
||||
if (mk_nflat_and_core(flat_args.size(), flat_args.data(), result) == BR_FAILED)
|
||||
result = m().mk_and(flat_args);
|
||||
return BR_DONE;
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
return mk_nflat_and_core(num_args, args, result);
|
||||
}
|
||||
|
@ -874,7 +874,7 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
expr_ref tmp(m());
|
||||
mk_not(c, tmp);
|
||||
mk_and(tmp, e, result);
|
||||
return BR_DONE;
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
}
|
||||
if (m().is_true(e) && m_elim_ite) {
|
||||
|
@ -885,11 +885,11 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
}
|
||||
if (m().is_false(e) && m_elim_ite) {
|
||||
mk_and(c, t, result);
|
||||
return BR_DONE;
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
if (c == e && m_elim_ite) {
|
||||
mk_and(c, t, result);
|
||||
return BR_DONE;
|
||||
return BR_REWRITE1;
|
||||
}
|
||||
if (c == t && m_elim_ite) {
|
||||
mk_or(c, e, result);
|
||||
|
@ -912,13 +912,13 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
expr_ref a(m());
|
||||
mk_and(c, t2, a);
|
||||
result = m().mk_not(m().mk_eq(t1, a));
|
||||
return BR_REWRITE2;
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
if (m().is_not(t, t1) && m().is_eq(t1, t2, t1) && e == t1) {
|
||||
expr_ref a(m());
|
||||
mk_and(c, t2, a);
|
||||
result = m().mk_eq(t1, a);
|
||||
return BR_REWRITE2;
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -931,14 +931,14 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
expr_ref new_c(m());
|
||||
mk_and(c, not_c2, new_c);
|
||||
result = m().mk_ite(new_c, to_app(t)->get_arg(2), e);
|
||||
return BR_REWRITE1;
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
// (ite c1 (ite c2 t1 t2) t2) ==> (ite (and c1 c2) t1 t2)
|
||||
if (e == to_app(t)->get_arg(2)) {
|
||||
expr_ref new_c(m());
|
||||
mk_and(c, to_app(t)->get_arg(0), new_c);
|
||||
result = m().mk_ite(new_c, to_app(t)->get_arg(1), e);
|
||||
return BR_REWRITE1;
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
|
||||
|
@ -955,7 +955,7 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
expr_ref new_c(m());
|
||||
mk_or(and1, and2, new_c);
|
||||
result = m().mk_ite(new_c, to_app(t)->get_arg(1), to_app(t)->get_arg(2));
|
||||
return BR_REWRITE1;
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
|
||||
// (ite c1 (ite c2 t1 t2) (ite c3 t2 t1)) ==> (ite (or (and c1 c2) (and (not c1) (not c3))) t1 t2)
|
||||
|
@ -972,7 +972,7 @@ br_status bool_rewriter::mk_ite_core(expr * c, expr * t, expr * e, expr_ref & re
|
|||
expr_ref new_c(m());
|
||||
mk_or(and1, and2, new_c);
|
||||
result = m().mk_ite(new_c, to_app(t)->get_arg(1), to_app(t)->get_arg(2));
|
||||
return BR_REWRITE1;
|
||||
return BR_REWRITE3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,10 @@ br_status datatype_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr
|
|||
// simplify is_cons(nil) -> false
|
||||
//
|
||||
SASSERT(num_args == 1);
|
||||
if (m_util.get_datatype_num_constructors(args[0]->get_sort()) == 1) {
|
||||
result = m().mk_true();
|
||||
return BR_DONE;
|
||||
}
|
||||
if (!is_app(args[0]) || !m_util.is_constructor(to_app(args[0])))
|
||||
return BR_FAILED;
|
||||
if (to_app(args[0])->get_decl() == m_util.get_recognizer_constructor(f))
|
||||
|
|
|
@ -28,7 +28,7 @@ Notes:
|
|||
class expr_replacer {
|
||||
struct scoped_set_subst;
|
||||
public:
|
||||
virtual ~expr_replacer() {}
|
||||
virtual ~expr_replacer() = default;
|
||||
|
||||
virtual ast_manager & m() const = 0;
|
||||
virtual void set_substitution(expr_substitution * s) = 0;
|
||||
|
|
|
@ -190,3 +190,17 @@ void expr_safe_replace::apply_substitution(expr* s, expr* def, expr_ref& t) {
|
|||
(*this)(t, t);
|
||||
reset();
|
||||
}
|
||||
|
||||
void expr_safe_replace::push_scope() {
|
||||
m_limit.push_back(m_src.size());
|
||||
}
|
||||
|
||||
void expr_safe_replace::pop_scope(unsigned n) {
|
||||
unsigned old_sz = m_limit[m_limit.size() - n];
|
||||
if (old_sz != m_src.size()) {
|
||||
m_cache.clear();
|
||||
m_src.shrink(old_sz);
|
||||
m_dst.shrink(old_sz);
|
||||
}
|
||||
m_limit.shrink(m_limit.size() - n);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class expr_safe_replace {
|
|||
ast_manager& m;
|
||||
expr_ref_vector m_src;
|
||||
expr_ref_vector m_dst;
|
||||
unsigned_vector m_limit = 0;
|
||||
ptr_vector<expr> m_todo, m_args;
|
||||
expr_ref_vector m_refs;
|
||||
std::unordered_map<expr*,expr*> m_cache;
|
||||
|
@ -48,5 +49,9 @@ public:
|
|||
void reset();
|
||||
|
||||
bool empty() const { return m_src.empty(); }
|
||||
|
||||
void push_scope();
|
||||
|
||||
void pop_scope(unsigned n);
|
||||
};
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue