mirror of
https://github.com/Z3Prover/z3
synced 2025-04-20 07:36:38 +00:00
Merge branch 'master' into polysat
This commit is contained in:
commit
20b5455d08
3
.github/workflows/coverage.yml
vendored
3
.github/workflows/coverage.yml
vendored
|
@ -56,9 +56,10 @@ jobs:
|
|||
./test-z3 -a
|
||||
cd -
|
||||
|
||||
# Disabled: ${{github.workspace}}/build/examples/c_example_build_dir/c_example
|
||||
|
||||
- name: Run examples
|
||||
run: |
|
||||
${{github.workspace}}/build/examples/c_example_build_dir/c_example
|
||||
${{github.workspace}}/build/examples/cpp_example_build_dir/cpp_example
|
||||
${{github.workspace}}/build/examples/tptp_build_dir/z3_tptp5 --help
|
||||
${{github.workspace}}/build/examples/c_maxsat_example_build_dir/c_maxsat_example ${{github.workspace}}/examples/maxsat/ex.smt
|
||||
|
|
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.1
|
||||
uses: docker/build-push-action@v4.0.0
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
|
|
5
.github/workflows/msvc-static-build.yml
vendored
5
.github/workflows/msvc-static-build.yml
vendored
|
@ -1,9 +1,12 @@
|
|||
name: MSVC Static Build
|
||||
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read # to fetch code (actions/checkout)
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-2019
|
||||
|
|
2
.github/workflows/wasm-release.yml
vendored
2
.github/workflows/wasm-release.yml
vendored
|
@ -36,7 +36,7 @@ jobs:
|
|||
cp ../../../LICENSE.txt .
|
||||
|
||||
- name: Setup emscripten
|
||||
uses: mymindstorm/setup-emsdk@v11
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
with:
|
||||
no-install: true
|
||||
version: ${{env.EM_VERSION}}
|
||||
|
|
2
.github/workflows/wasm.yml
vendored
2
.github/workflows/wasm.yml
vendored
|
@ -29,7 +29,7 @@ jobs:
|
|||
node-version: "lts/*"
|
||||
|
||||
- name: Setup emscripten
|
||||
uses: mymindstorm/setup-emsdk@v11
|
||||
uses: mymindstorm/setup-emsdk@v12
|
||||
with:
|
||||
no-install: true
|
||||
version: ${{env.EM_VERSION}}
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -81,6 +81,8 @@ src/api/js/node_modules/
|
|||
src/api/js/build/
|
||||
src/api/js/**/*.__GENERATED__.*
|
||||
debug/*
|
||||
examples/python/z3
|
||||
examples/python/libz3.dll
|
||||
|
||||
out/**
|
||||
*.bak
|
||||
|
@ -93,3 +95,4 @@ CMakeSettings.json
|
|||
*.swp
|
||||
.DS_Store
|
||||
dbg/**
|
||||
*.wsp
|
||||
|
|
|
@ -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.3.0 LANGUAGES CXX C)
|
||||
project(Z3 VERSION 4.12.2.0 LANGUAGES CXX C)
|
||||
|
||||
################################################################################
|
||||
# Project version
|
||||
|
|
605
Parameters.md
605
Parameters.md
|
@ -1,605 +0,0 @@
|
|||
## 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
|
128
RELEASE_NOTES.md
128
RELEASE_NOTES.md
|
@ -10,6 +10,134 @@ Version 4.next
|
|||
- native word level bit-vector solving.
|
||||
- introduction of simple induction lemmas to handle a limited repertoire of induction proofs.
|
||||
|
||||
|
||||
Version 4.12.2
|
||||
==============
|
||||
- remove MSF (Microsoft Solver Foundation) plugin
|
||||
- updated propagate-ineqs tactic and implementing it as a simplifier, bound_simplifier.
|
||||
It now eliminates occurrences of "mod" operators when bounds information
|
||||
implies that the modulus is redundant. This tactic is useful for
|
||||
benchmarks created by converting bit-vector semantics to integer
|
||||
reasoning.
|
||||
- add API function Z3_mk_real_int64 to take two int64 as arguments. The Z3_mk_real function takes integers.
|
||||
- Add _simplifiers_ as optional incremental pre-processing to solvers.
|
||||
They are exposed over the SMTLIB API using the command [`set-simplifier`](https://microsoft.github.io/z3guide/docs/strategies/simplifiers).
|
||||
Simplifiers are similar to tactics, but they operate on solver state that can be incrementally updated.
|
||||
The exposed simplifiers cover all the pre-processing techniques used internally with some additional simplifiers, such as `solve-eqs`
|
||||
and `elim-predicates` that go beyond incremental pre-processing used internally. The advantage of using `solve-eqs` during pre-processing
|
||||
can be significant. Incremental pre-processing simplification using `solve-eqs` and other simplifiers that change interpretations
|
||||
was not possible before.
|
||||
|
||||
Version 4.12.1
|
||||
==============
|
||||
- change macos build to use explicit reference to Macos version 11. Hosted builds are migrating to macos-12 and it broke a user Issue #6539.
|
||||
|
||||
Version 4.12.0
|
||||
==============
|
||||
- add clause logging API.
|
||||
- The purpose of logging API and self-checking is to enable an array of use cases.
|
||||
- proof mining (what instantiations did Z3 use)?
|
||||
- A refresh of the AxiomProfiler could use the logging API.
|
||||
The (brittle) trace feature should be deprecated.
|
||||
- debugging
|
||||
- a built-in self certifier implements a custom proof checker for
|
||||
the format used by the new solver (sat.euf=true).
|
||||
- other potential options:
|
||||
- integration into certified tool chains
|
||||
- interpolation
|
||||
- Z3_register_on_clause (also exposed over C++, Python and .Net)
|
||||
- it applies to z3's main CDCL(T) core and a new CDCL(T) core (sat.euf=true).
|
||||
- The added API function allows to register a callback for when clauses
|
||||
are inferred. More precisely, when clauses are assumed (as part of input),
|
||||
deleted, or deduced.
|
||||
Clauses that are deduced by the CDCL SAT engine using standard
|
||||
inferences are marked as 'rup'.
|
||||
Clauses that are deduced by theories are marked by default
|
||||
by 'smt', and when more detailed information
|
||||
is available with proof hints or proof objects.
|
||||
Instantations are considered useful to track so they
|
||||
are logged using terms of the form
|
||||
|
||||
(inst (not (forall (x) body)) body[t/x] (bind t)), where
|
||||
|
||||
'inst' is a name of a function that produces a proof term representing
|
||||
the instantiation.
|
||||
- add options for proof logging, trimming, and checking for the new core.
|
||||
- sat.smt.proof (symbol) add SMT proof to file (default: )
|
||||
- sat.smt.proof.check (bool) check SMT proof while it is created (default: false)
|
||||
- it applies a custom self-validator. The self-validator comprises of
|
||||
several small checkers and represent a best-effort validation mechanism.
|
||||
If there are no custom validators associated with inferences, or the custom
|
||||
validators fail to certify inferences, the self-validator falls back to
|
||||
invoking z3 (SMT) solving on the lemma.
|
||||
- euf - propagations and conflicts from congruence closure
|
||||
(theory of equality and uninterpreted functions) are checked
|
||||
based on a proof format that tracks uses of congruence closure and
|
||||
equalities. It only performs union find operations.
|
||||
- tseitin - clausification steps are checked for Boolean operators.
|
||||
- farkas, bound, implies_eq - arithmetic inferences that can be justified using
|
||||
a combination of Farkas lemma and cuts are checked.
|
||||
Note: the arithmetic solver may produce proof hints that the proof
|
||||
checker cannot check. It is mainly a limitation
|
||||
of the arithmetic solver not pulling relevant information.
|
||||
Ensuring a tight coupling with proof hints and the validator
|
||||
capabilites is open ended future work and good material for theses.
|
||||
- bit-vector inferences - are treated as trusted
|
||||
(there is no validation, it always blindly succeeds)
|
||||
- arrays, datatypes - there is no custom validation for
|
||||
other theories at present. Lemmas are validated using SMT.
|
||||
- sat.smt.proof.check_rup (bool) apply forward RUP proof checking (default: true)
|
||||
- this option can incur significant runtime overhead.
|
||||
Effective proof checking relies on first trimming proofs into a
|
||||
format where dependencies are tracked and then checking relevant inferences.
|
||||
Turn this option off if you just want to check theory inferences.
|
||||
- add options to validate proofs offline. It applies to proofs
|
||||
saved when sat.smt.proof is set to a valid file name.
|
||||
- solver.proof.check (bool) check proof logs (default: true)
|
||||
- the option sat.smt.proof_check_rup can be used to control what is checked
|
||||
- solver.proof.save (bool) save proof log into a proof object
|
||||
that can be extracted using (get-proof) (default: false)
|
||||
- experimental: saves a proof log into a term
|
||||
- solver.proof.trim (bool) trim the offline proof and print the trimmed proof to the console
|
||||
- experimental: performs DRUP trimming to reduce the set of hypotheses
|
||||
and inferences relevant to derive the empty clause.
|
||||
- JS support for Arrays, thanks to Walden Yan
|
||||
- More portable memory allocation, thanks to Nuno Lopes
|
||||
(avoid custom handling to calculate memory usage)
|
||||
|
||||
- clause logging and proofs: many open-ended directions.
|
||||
Many directions and functionality features remain in an open-ended state,
|
||||
subject to fixes, improvements, and contributions.
|
||||
We list a few of them here:
|
||||
- comprehensive efficient self-validators for arithmetic, and other theories
|
||||
- an efficient proof checker when several theory solvers cooperate in a propagation or
|
||||
conflict. The theory combination case is currently delegated to the smt solver.
|
||||
The proper setup for integrating theory lemmas is in principle not complicated,
|
||||
but the implementation requires some changes.
|
||||
- external efficient proof validators (based on certified tool chains)
|
||||
can be integrated over the API.
|
||||
- dampening repeated clauses: A side-effect of conflict resolution is to
|
||||
log theory lemmas. It often happens that the theory lemma becomes
|
||||
the conflict clause, that is then logged as rup. Thus, two clauses are
|
||||
logged.
|
||||
- support for online trim so that proofs generated using clause logging can be used for SPACER
|
||||
- SPACER also would benefit from more robust proof hints for arithmetic
|
||||
lemmas (bounds and implied equalities are sometimes not logged correctly)
|
||||
- integration into axiom profiling through online and/or offline interfaces.
|
||||
- an online interface attaches a callback with a running solver. This is available.
|
||||
- an offline interface saves a clause proof to a file (currently just
|
||||
supported for sat.euf) and then reads the file in a separate process
|
||||
The separate process attaches a callback on inferred clauses.
|
||||
This is currently not available but a relatively small feature.
|
||||
- more detailed proof hints for the legacy solver clause logger.
|
||||
Other than quantifier instantiations, no detailed information is retained for
|
||||
theory clauses.
|
||||
- integration of pre-processing proofs with logging proofs. There is
|
||||
currently no supported bridge to create a end-to-end proof objects.
|
||||
- experimental API for accessing E-graphs. Exposed over Python. This API should be considered temporary
|
||||
and subject to be changed depending on use cases or removed. The functions are `Z3_solver_congruence_root`, `Z3_solver_congruence_next`.
|
||||
|
||||
|
||||
Version 4.11.2
|
||||
==============
|
||||
- add error handling to fromString method in JavaScript
|
||||
|
|
|
@ -202,7 +202,7 @@ jobs:
|
|||
setupCmd2: 'julia -e "using libcxxwrap_julia_jll; print(dirname(libcxxwrap_julia_jll.libcxxwrap_julia_path))" > tmp.env'
|
||||
setupCmd3: 'set /P JlCxxDir=<tmp.env'
|
||||
bindings: '-DJlCxx_DIR=%JlCxxDir%\..\lib\cmake\JlCxx $(cmakeJava) $(cmakeNet) $(cmakePy) -DCMAKE_BUILD_TYPE=RelWithDebInfo'
|
||||
runTests: 'True'
|
||||
runTests: 'False'
|
||||
arm64:
|
||||
arch: 'amd64_arm64'
|
||||
setupCmd1: ''
|
||||
|
|
|
@ -65,7 +65,7 @@ int parse(string const & filename, map<string, map_entry> & data) {
|
|||
inx != string::npos;
|
||||
inx = line.find(" : ", from)) {
|
||||
tokens[ti] = trim(line.substr(from, inx-from));
|
||||
from = inx+1;
|
||||
from = inx+3; //3 is the length of " : "
|
||||
ti++;
|
||||
}
|
||||
if (from != line.length() && ti < 4)
|
||||
|
|
129
doc/mk_tactic_doc.py
Normal file
129
doc/mk_tactic_doc.py
Normal file
|
@ -0,0 +1,129 @@
|
|||
# Copyright (c) Microsoft Corporation 2015
|
||||
"""
|
||||
Tactic documentation generator script
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
BUILD_DIR='../build'
|
||||
SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
|
||||
OUTPUT_DIRECTORY = os.path.join(os.getcwd(), 'api')
|
||||
|
||||
def doc_path(path):
|
||||
return os.path.join(SCRIPT_DIR, path)
|
||||
|
||||
is_doc = re.compile("Tactic Documentation")
|
||||
is_doc_end = re.compile("\-\-\*\/")
|
||||
is_tac_name = re.compile("## Tactic (.*)")
|
||||
is_simplifier = re.compile("ADD_SIMPLIFIER\(.*\"([^\"]*)\".*,.*\"([^\"]*)\".*,.*\"([^\"]*)\"\.*\)")
|
||||
|
||||
def is_ws(s):
|
||||
return all([0 for ch in s if ch != ' ' and ch != '\n'])
|
||||
|
||||
def extract_params(ous, tac):
|
||||
z3_exe = BUILD_DIR + "/z3"
|
||||
out = subprocess.Popen([z3_exe, f"-tacticsmd:{tac}"], stdout=subprocess.PIPE).communicate()[0]
|
||||
if not out:
|
||||
return
|
||||
out = out.decode(sys.stdout.encoding)
|
||||
if is_ws(out):
|
||||
return
|
||||
ous.write("### Parameters\n\n")
|
||||
for line in out:
|
||||
ous.write(line.replace("\r",""))
|
||||
ous.write("\n")
|
||||
|
||||
def generate_tactic_doc(ous, f, ins):
|
||||
tac_name = None
|
||||
for line in ins:
|
||||
m = is_tac_name.search(line)
|
||||
if m:
|
||||
tac_name = m.group(1)
|
||||
if is_doc_end.search(line):
|
||||
if tac_name:
|
||||
extract_params(ous, tac_name)
|
||||
break
|
||||
ous.write(line)
|
||||
|
||||
def extract_tactic_doc(ous, f):
|
||||
with open(f) as ins:
|
||||
for line in ins:
|
||||
if is_doc.search(line):
|
||||
generate_tactic_doc(ous, f, ins)
|
||||
|
||||
def generate_simplifier_doc(ous, name, desc):
|
||||
ous.write("## Simplifier [" + name + "](https://microsoft.github.io/z3guide/docs/strategies/summary/#tactic-" + name + ")\n")
|
||||
ous.write("### Description\n" + desc + "\n")
|
||||
|
||||
|
||||
def extract_simplifier_doc(ous, f):
|
||||
with open(f) as ins:
|
||||
for line in ins:
|
||||
m = is_simplifier.search(line)
|
||||
if m:
|
||||
generate_simplifier_doc(ous, m.group(1), m.group(2))
|
||||
|
||||
def find_tactic_name(path):
|
||||
with open(path) as ins:
|
||||
for line in ins:
|
||||
m = is_tac_name.search(line)
|
||||
if m:
|
||||
return m.group(1)
|
||||
print(f"no tactic in {path}")
|
||||
return ""
|
||||
|
||||
def find_simplifier_name(path):
|
||||
with open(path) as ins:
|
||||
for line in ins:
|
||||
m = is_simplifier.search(line)
|
||||
if m:
|
||||
return m.group(1)
|
||||
print(f"no simplifier in {path}")
|
||||
return ""
|
||||
|
||||
def presort_files(find_fn):
|
||||
tac_files = []
|
||||
for root, dirs, files in os.walk(doc_path("../src")):
|
||||
for f in files:
|
||||
if f.endswith("~"):
|
||||
continue
|
||||
if f.endswith("tactic.h") or "simplifiers" in root:
|
||||
tac_files += [(f, os.path.join(root, f))]
|
||||
tac_files = sorted(tac_files, key = lambda x: find_fn(x[1]))
|
||||
return tac_files
|
||||
|
||||
|
||||
def help(ous):
|
||||
ous.write("---\n")
|
||||
ous.write("title: Tactics Summary\n")
|
||||
ous.write("sidebar_position: 6\n")
|
||||
ous.write("---\n")
|
||||
tac_files = presort_files(find_tactic_name)
|
||||
for file, path in tac_files:
|
||||
extract_tactic_doc(ous, path)
|
||||
|
||||
|
||||
|
||||
def help_simplifier(ous):
|
||||
ous.write("---\n")
|
||||
ous.write("title: Simplifiers Summary\n")
|
||||
ous.write("sidebar_position: 7\n")
|
||||
ous.write("---\n")
|
||||
tac_files = presort_files(find_simplifier_name)
|
||||
for file, path in tac_files:
|
||||
extract_simplifier_doc(ous, path)
|
||||
|
||||
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/tactics-summary.md",'w') as ous:
|
||||
help(ous)
|
||||
|
||||
with open(OUTPUT_DIRECTORY + "/md/simplifier-summary.md",'w') as ous:
|
||||
help_simplifier(ous)
|
|
@ -561,6 +561,7 @@ void display_ast(Z3_context c, FILE * out, Z3_ast v)
|
|||
}
|
||||
case Z3_QUANTIFIER_AST: {
|
||||
fprintf(out, "quantifier");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(out, "#unknown");
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
In order to use Z3 MSF plugin, follow the following steps:
|
||||
1. Compile latest Z3 .NET API (from any branch consisting of opt features) and copy 'libz3.dll' and 'Microsoft.Z3.dll' to the folder of 'Z3MSFPlugin.sln'.
|
||||
2. Retrieve 'Microsoft.Solver.Foundation.dll' from http://archive.msdn.microsoft.com/solverfoundation/Release/ProjectReleases.aspx?ReleaseId=1799,
|
||||
preferably using DLL only version. Copy 'Microsoft.Solver.Foundation.dll' to the folder of 'Z3MSFPlugin.sln'
|
||||
3. Build 'Z3MSFPlugin.sln'. Note that you have to compile using x86 target for Microsoft.Z3.dll 32-bit and x64 target for Microsoft.Z3.dll 64-bit.
|
||||
|
||||
The solution consists of a plugin project, a test project with a few simple test cases and a command line projects for external OML, MPS and SMPS models.
|
||||
To retrieve SMT2 models which are native to Z3, set the logging file in corresponding directives or solver params e.g.
|
||||
|
||||
var p = new Z3MILPParams();
|
||||
p.SMT2LogFile = "model.smt2";
|
||||
|
||||
For more details, check out the commands in 'Validator\Program.cs'.
|
||||
|
||||
Enjoy!
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="MsfConfig"
|
||||
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
|
||||
allowLocation="true"
|
||||
allowDefinition="Everywhere"
|
||||
allowExeDefinition="MachineToApplication"
|
||||
restartOnExternalChanges="true"
|
||||
requirePermission="true"/>
|
||||
</configSections>
|
||||
<MsfConfig>
|
||||
<MsfPluginSolvers>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MINLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="NLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
</MsfPluginSolvers>
|
||||
</MsfConfig>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||
</startup>
|
||||
</configuration>
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2013")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("27657eee-ca7b-4996-a905-86a3f4584988")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,92 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Solvers;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using Microsoft.SolverFoundation.Plugin.Z3;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class ServiceTests
|
||||
{
|
||||
[TestInitialize]
|
||||
public void SetUp()
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
context.ClearModel();
|
||||
}
|
||||
|
||||
private void TestService1(Directive directive)
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
Model model = context.CreateModel();
|
||||
|
||||
Decision x1 = new Decision(Domain.RealRange(0, 2), "x1");
|
||||
Decision x2 = new Decision(Domain.RealRange(0, 2), "x2");
|
||||
|
||||
Decision z = new Decision(Domain.IntegerRange(0, 1), "z");
|
||||
|
||||
model.AddDecisions(x1, x2, z);
|
||||
|
||||
model.AddConstraint("Row0", x1 - z <= 1);
|
||||
model.AddConstraint("Row1", x2 + z <= 2);
|
||||
|
||||
Goal goal = model.AddGoal("Goal0", GoalKind.Maximize, x1 + x2);
|
||||
|
||||
Solution solution = context.Solve(directive);
|
||||
Assert.IsTrue(goal.ToInt32() == 3);
|
||||
context.ClearModel();
|
||||
}
|
||||
|
||||
private void TestService2(Directive directive)
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
Model model = context.CreateModel();
|
||||
|
||||
Decision x1 = new Decision(Domain.RealNonnegative, "x1");
|
||||
Decision x2 = new Decision(Domain.RealNonnegative, "x2");
|
||||
|
||||
Decision z = new Decision(Domain.IntegerRange(0, 1), "z");
|
||||
|
||||
Rational M = 100;
|
||||
|
||||
model.AddDecisions(x1, x2, z);
|
||||
|
||||
model.AddConstraint("Row0", x1 + x2 >= 1);
|
||||
model.AddConstraint("Row1", x1 - z * 100 <= 0);
|
||||
model.AddConstraint("Row2", x2 + z * 100 <= 100);
|
||||
|
||||
Goal goal = model.AddGoal("Goal0", GoalKind.Maximize, x1 + x2);
|
||||
|
||||
Solution solution = context.Solve(directive);
|
||||
Assert.IsTrue(goal.ToInt32() == 100);
|
||||
context.ClearModel();
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestService1()
|
||||
{
|
||||
TestService1(new Z3MILPDirective());
|
||||
TestService1(new Z3TermDirective());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestService2()
|
||||
{
|
||||
TestService2(new Z3MILPDirective());
|
||||
TestService2(new Z3TermDirective());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{280AEE2F-1FDB-4A27-BE37-14DC154C873B}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.SolverFoundation.Plugin.Z3.Tests</RootNamespace>
|
||||
<AssemblyName>SolverFoundation.Plugin.Z3.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Solver.Foundation">
|
||||
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="ServiceTests.cs" />
|
||||
<Compile Include="SolverTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj">
|
||||
<Project>{7340e664-f648-4ff7-89b2-f4da424996d3}</Project>
|
||||
<Name>SolverFoundation.Plugin.Z3</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,138 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Solvers;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using Microsoft.SolverFoundation.Plugin.Z3;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class SolverTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void TestMILPSolver1()
|
||||
{
|
||||
var solver = new Z3MILPSolver();
|
||||
int goal;
|
||||
|
||||
solver.AddRow("goal", out goal);
|
||||
int x1, x2, z;
|
||||
|
||||
// 0 <= x1 <= 2
|
||||
solver.AddVariable("x1", out x1);
|
||||
solver.SetBounds(x1, 0, 2);
|
||||
|
||||
// 0 <= x2 <= 2
|
||||
solver.AddVariable("x2", out x2);
|
||||
solver.SetBounds(x2, 0, 2);
|
||||
|
||||
// z is an integer in [0,1]
|
||||
solver.AddVariable("z", out z);
|
||||
solver.SetIntegrality(z, true);
|
||||
solver.SetBounds(z, 0, 1);
|
||||
|
||||
//max x1 + x2
|
||||
solver.SetCoefficient(goal, x1, 1);
|
||||
solver.SetCoefficient(goal, x2, 1);
|
||||
solver.AddGoal(goal, 1, false);
|
||||
|
||||
// 0 <= x1 -z <= 1
|
||||
int row1;
|
||||
solver.AddRow("rowI1", out row1);
|
||||
solver.SetBounds(row1, 0, 1);
|
||||
solver.SetCoefficient(row1, x1, 1);
|
||||
solver.SetCoefficient(row1, z, -1);
|
||||
|
||||
// 0 <= x2 + z <= 2
|
||||
int row2;
|
||||
solver.AddRow("rowI2", out row2);
|
||||
solver.SetBounds(row2, 0, 2);
|
||||
solver.SetCoefficient(row2, x2, 1);
|
||||
solver.SetCoefficient(row2, z, 1);
|
||||
|
||||
var p = new Z3MILPParams();
|
||||
solver.Solve(p);
|
||||
|
||||
Assert.IsTrue(solver.Result == LinearResult.Optimal);
|
||||
Assert.AreEqual(solver.GetValue(x1), 2 * Rational.One);
|
||||
Assert.AreEqual(solver.GetValue(x2), Rational.One);
|
||||
Assert.AreEqual(solver.GetValue(z), Rational.One);
|
||||
Assert.AreEqual(solver.GetValue(goal), 3 * Rational.One);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void TestMILPSolver2()
|
||||
{
|
||||
var solver = new Z3MILPSolver();
|
||||
int goal, extraGoal;
|
||||
|
||||
Rational M = 100;
|
||||
solver.AddRow("goal", out goal);
|
||||
int x1, x2, z;
|
||||
|
||||
// 0 <= x1 <= 100
|
||||
solver.AddVariable("x1", out x1);
|
||||
solver.SetBounds(x1, 0, M);
|
||||
|
||||
// 0 <= x2 <= 100
|
||||
solver.AddVariable("x2", out x2);
|
||||
solver.SetBounds(x2, 0, M);
|
||||
|
||||
// z is an integer in [0,1]
|
||||
solver.AddVariable("z", out z);
|
||||
solver.SetIntegrality(z, true);
|
||||
solver.SetBounds(z, 0, 1);
|
||||
|
||||
solver.SetCoefficient(goal, x1, 1);
|
||||
solver.SetCoefficient(goal, x2, 2);
|
||||
solver.AddGoal(goal, 1, false);
|
||||
|
||||
solver.AddRow("extraGoal", out extraGoal);
|
||||
|
||||
solver.SetCoefficient(extraGoal, x1, 2);
|
||||
solver.SetCoefficient(extraGoal, x2, 1);
|
||||
solver.AddGoal(extraGoal, 2, false);
|
||||
|
||||
// x1 + x2 >= 1
|
||||
int row;
|
||||
solver.AddRow("row", out row);
|
||||
solver.SetBounds(row, 1, Rational.PositiveInfinity);
|
||||
solver.SetCoefficient(row, x1, 1);
|
||||
solver.SetCoefficient(row, x2, 1);
|
||||
|
||||
|
||||
// x1 - M*z <= 0
|
||||
int row1;
|
||||
solver.AddRow("rowI1", out row1);
|
||||
solver.SetBounds(row1, Rational.NegativeInfinity, 0);
|
||||
solver.SetCoefficient(row1, x1, 1);
|
||||
solver.SetCoefficient(row1, z, -M);
|
||||
|
||||
// x2 - M* (1-z) <= 0
|
||||
int row2;
|
||||
solver.AddRow("rowI2", out row2);
|
||||
solver.SetBounds(row2, Rational.NegativeInfinity, M);
|
||||
solver.SetCoefficient(row2, x2, 1);
|
||||
solver.SetCoefficient(row2, z, M);
|
||||
|
||||
var p = new Z3MILPParams();
|
||||
p.OptKind = OptimizationKind.BoundingBox;
|
||||
|
||||
solver.Solve(p);
|
||||
Assert.IsTrue(solver.Result == LinearResult.Optimal);
|
||||
Assert.AreEqual(solver.GetValue(goal), 200 * Rational.One);
|
||||
Assert.AreEqual(solver.GetValue(extraGoal), 200 * Rational.One);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using Microsoft.Z3;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// Thread that will wait until the query abort function returns true or
|
||||
/// the stop method is called. If the abort function returns true at some
|
||||
/// point it will issue a softCancel() call to Z3.
|
||||
/// </summary>
|
||||
internal class AbortWorker
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
/// <summary>The Z3 solver</summary>
|
||||
private Microsoft.Z3.Context _context;
|
||||
/// <summary>The abort function to use to check if we are aborted</summary>
|
||||
private Func<bool> _QueryAbortFunction;
|
||||
/// <summary>Flag indicating that worker should stop</summary>
|
||||
private bool _stop = false;
|
||||
/// <summary>Flag indicating that we have been sent an abort signal</summary>
|
||||
private bool _aborted = false;
|
||||
|
||||
#endregion Private Members
|
||||
|
||||
#region Construction
|
||||
|
||||
/// <summary>
|
||||
/// Worker constructor taking a Z3 instance and a function to periodically
|
||||
/// check for aborts.
|
||||
/// </summary>
|
||||
/// <param name="z3">Z3 instance</param>
|
||||
/// <param name="queryAbortFunction">method to call to check for aborts</param>
|
||||
public AbortWorker(Context context, Func<bool> queryAbortFunction)
|
||||
{
|
||||
_context = context;
|
||||
_QueryAbortFunction = queryAbortFunction;
|
||||
}
|
||||
|
||||
#endregion Construction
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Stop the abort worker.
|
||||
/// </summary>
|
||||
public void Stop()
|
||||
{
|
||||
_stop = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Is true if we have been aborted.
|
||||
/// </summary>
|
||||
public bool Aborted
|
||||
{
|
||||
get
|
||||
{
|
||||
return _aborted;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts the abort worker. The worker checks the abort method
|
||||
/// periodically until either it is stopped by a call to the Stop()
|
||||
/// method or it gets an abort signal. In the latter case it will
|
||||
/// issue a soft abort signal to Z3.
|
||||
/// </summary>
|
||||
public void Start()
|
||||
{
|
||||
// We go until someone stops us
|
||||
_stop = false;
|
||||
while (!_stop && !_QueryAbortFunction())
|
||||
{
|
||||
// Wait for a while
|
||||
Thread.Sleep(10);
|
||||
}
|
||||
// If we were stopped on abort, cancel z3
|
||||
if (!_stop)
|
||||
{
|
||||
_context.Interrupt();
|
||||
_aborted = true;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Public Methods
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="MsfConfig"
|
||||
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
|
||||
allowLocation="true"
|
||||
allowDefinition="Everywhere"
|
||||
allowExeDefinition="MachineToApplication"
|
||||
restartOnExternalChanges="true"
|
||||
requirePermission="true"/>
|
||||
</configSections>
|
||||
<MsfConfig>
|
||||
<MsfPluginSolvers>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MINLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="NLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
</MsfPluginSolvers>
|
||||
</MsfConfig>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||
</startup>
|
||||
</configuration>
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("SolverFoundation.Plugin.Z3")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("SolverFoundation.Plugin.Z3")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("ed1476c0-96de-4d2c-983d-3888b140c3ad")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,149 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7340E664-F648-4FF7-89B2-F4DA424996D3}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Microsoft.SolverFoundation.Plugin.Z3</RootNamespace>
|
||||
<AssemblyName>SolverFoundation.Plugin.Z3</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>
|
||||
</AssemblyOriginatorKeyFile>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial|AnyCPU'">
|
||||
<OutputPath>bin\commercial\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial_64|AnyCPU'">
|
||||
<OutputPath>bin\commercial_64\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial|x86'">
|
||||
<OutputPath>bin\x86\commercial\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'commercial_64|x86'">
|
||||
<OutputPath>bin\x86\commercial_64\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Solver.Foundation">
|
||||
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.Z3, Version=4.3.2.0, Culture=neutral, processorArchitecture=x86">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\Microsoft.Z3.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
</Reference>
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Xml.Linq">
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AbortWorker.cs" />
|
||||
<Compile Include="Utils.cs" />
|
||||
<Compile Include="Z3BaseDirective.cs" />
|
||||
<Compile Include="Z3BaseParams.cs" />
|
||||
<Compile Include="Z3BaseSolver.cs" />
|
||||
<Compile Include="Z3MILPDirective.cs" />
|
||||
<Compile Include="Z3MILPParams.cs" />
|
||||
<Compile Include="Z3MILPSolver.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Z3TermDirective.cs" />
|
||||
<Compile Include="Z3TermParams.cs" />
|
||||
<Compile Include="Z3TermSolver.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,130 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Z3;
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns the Z3 term corresponding to the MSF rational number.
|
||||
/// </summary>
|
||||
/// <param name="rational">The MSF rational</param>
|
||||
/// <returns>The Z3 term</returns>
|
||||
public static ArithExpr GetNumeral(Context context, Rational rational, Sort sort = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
sort = rational.IsInteger() ? ((Sort)context.IntSort) : (sort == null ? (Sort)context.RealSort : sort);
|
||||
return (ArithExpr)context.MkNumeral(rational.ToString(), sort);
|
||||
}
|
||||
catch (Z3Exception e)
|
||||
{
|
||||
Console.Error.WriteLine("Conversion of {0} failed:\n {1}", rational, e);
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
|
||||
private static long BASE = 10 ^ 18;
|
||||
|
||||
private static Rational ToRational(System.Numerics.BigInteger bi)
|
||||
{
|
||||
if (System.Numerics.BigInteger.Abs(bi) <= BASE)
|
||||
{
|
||||
return (Rational)((long)bi);
|
||||
}
|
||||
return BASE * ToRational(bi / BASE) + ToRational(bi % BASE);
|
||||
}
|
||||
|
||||
public static Rational ToRational(IntNum i)
|
||||
{
|
||||
return ToRational(i.BigInteger);
|
||||
}
|
||||
|
||||
public static Rational ToRational(RatNum r)
|
||||
{
|
||||
return ToRational(r.BigIntNumerator) / ToRational(r.BigIntDenominator);
|
||||
}
|
||||
|
||||
public static Rational ToRational(Expr expr)
|
||||
{
|
||||
Debug.Assert(expr is ArithExpr, "Only accept ArithExpr for now.");
|
||||
var e = expr as ArithExpr;
|
||||
|
||||
if (e is IntNum)
|
||||
{
|
||||
Debug.Assert(expr.IsIntNum, "Number should be an integer.");
|
||||
return ToRational(expr as IntNum);
|
||||
}
|
||||
|
||||
if (e is RatNum)
|
||||
{
|
||||
Debug.Assert(expr.IsRatNum, "Number should be a rational.");
|
||||
return ToRational(expr as RatNum);
|
||||
}
|
||||
|
||||
if (e.IsAdd)
|
||||
{
|
||||
Rational r = Rational.Zero;
|
||||
foreach (var arg in e.Args)
|
||||
{
|
||||
r += ToRational(arg);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (e.IsMul)
|
||||
{
|
||||
Rational r = Rational.One;
|
||||
foreach (var arg in e.Args)
|
||||
{
|
||||
r *= ToRational(arg);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (e.IsUMinus)
|
||||
{
|
||||
return -ToRational(e.Args[0]);
|
||||
}
|
||||
|
||||
if (e.IsDiv)
|
||||
{
|
||||
return ToRational(e.Args[0]) / ToRational(e.Args[1]);
|
||||
}
|
||||
|
||||
if (e.IsSub)
|
||||
{
|
||||
Rational r = ToRational(e.Args[0]);
|
||||
for (int i = 1; i < e.Args.Length; ++i)
|
||||
{
|
||||
r -= ToRational(e.Args[i]);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
if (e.IsConst && e.FuncDecl.Name.ToString() == "oo")
|
||||
{
|
||||
return Rational.PositiveInfinity;
|
||||
}
|
||||
|
||||
if (e.IsConst && e.FuncDecl.Name.ToString() == "epsilon")
|
||||
{
|
||||
return Rational.One/Rational.PositiveInfinity;
|
||||
}
|
||||
|
||||
Debug.Assert(false, "Should not happen");
|
||||
return Rational.One;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Text;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// Combining objective functions
|
||||
/// </summary>
|
||||
public enum OptimizationKind
|
||||
{
|
||||
Lexicographic,
|
||||
BoundingBox,
|
||||
ParetoOptimal
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Algorithm for solving cardinality constraints
|
||||
/// </summary>
|
||||
public enum CardinalityAlgorithm
|
||||
{
|
||||
FuMalik,
|
||||
CoreMaxSAT
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Algorithm for solving pseudo-boolean constraints
|
||||
/// </summary>
|
||||
public enum PseudoBooleanAlgorithm
|
||||
{
|
||||
WeightedMaxSAT,
|
||||
IterativeWeightedMaxSAT,
|
||||
BisectionWeightedMaxSAT,
|
||||
WeightedPartialMaxSAT2
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Strategy for solving arithmetic optimization
|
||||
/// </summary>
|
||||
public enum ArithmeticStrategy
|
||||
{
|
||||
Basic,
|
||||
Farkas
|
||||
}
|
||||
|
||||
public abstract class Z3BaseDirective : Directive
|
||||
{
|
||||
protected OptimizationKind _optKind;
|
||||
protected CardinalityAlgorithm _cardAlgorithm;
|
||||
protected PseudoBooleanAlgorithm _pboAlgorithm;
|
||||
protected ArithmeticStrategy _arithStrategy;
|
||||
|
||||
protected string _smt2LogFile;
|
||||
|
||||
public Z3BaseDirective()
|
||||
{
|
||||
Arithmetic = Arithmetic.Exact;
|
||||
}
|
||||
|
||||
public OptimizationKind OptKind
|
||||
{
|
||||
get { return _optKind; }
|
||||
set { _optKind = value; }
|
||||
}
|
||||
|
||||
public CardinalityAlgorithm CardinalityAlgorithm
|
||||
{
|
||||
get { return _cardAlgorithm; }
|
||||
set { _cardAlgorithm = value; }
|
||||
}
|
||||
|
||||
public PseudoBooleanAlgorithm PseudoBooleanAlgorithm
|
||||
{
|
||||
get { return _pboAlgorithm; }
|
||||
set { _pboAlgorithm = value; }
|
||||
}
|
||||
|
||||
public ArithmeticStrategy ArithmeticStrategy
|
||||
{
|
||||
get { return _arithStrategy; }
|
||||
set { _arithStrategy = value; }
|
||||
}
|
||||
|
||||
public string SMT2LogFile
|
||||
{
|
||||
get { return _smt2LogFile; }
|
||||
set { _smt2LogFile = value; }
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.Append(this.GetType().Name);
|
||||
sb.Append("(");
|
||||
sb.AppendFormat("OptKind: {0}, ", _optKind);
|
||||
sb.AppendFormat("SMT2LogFile: {0}", _smt2LogFile);
|
||||
sb.Append(")");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,109 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the solver parameters for Z3
|
||||
/// </summary>
|
||||
public class Z3BaseParams : ISolverParameters
|
||||
{
|
||||
#region Private Members
|
||||
|
||||
/// <summary>The abort method we can call (defaults to always false)
|
||||
protected Func<bool> _queryAbortFunction = delegate() { return false; };
|
||||
|
||||
/// <summary>The directive to use</summary>
|
||||
protected Directive _directive = null;
|
||||
|
||||
protected OptimizationKind _optKind;
|
||||
protected CardinalityAlgorithm _cardAlgorithm;
|
||||
protected PseudoBooleanAlgorithm _pboAlgorithm;
|
||||
protected ArithmeticStrategy _arithStrategy;
|
||||
|
||||
protected string _smt2LogFile;
|
||||
|
||||
#endregion Private Members
|
||||
|
||||
#region Construction
|
||||
|
||||
public Z3BaseParams() { }
|
||||
|
||||
public Z3BaseParams(Directive directive)
|
||||
{
|
||||
_directive = directive;
|
||||
|
||||
var z3Directive = directive as Z3BaseDirective;
|
||||
if (z3Directive != null)
|
||||
{
|
||||
_optKind = z3Directive.OptKind;
|
||||
_cardAlgorithm = z3Directive.CardinalityAlgorithm;
|
||||
_pboAlgorithm = z3Directive.PseudoBooleanAlgorithm;
|
||||
_arithStrategy = z3Directive.ArithmeticStrategy;
|
||||
_smt2LogFile = z3Directive.SMT2LogFile;
|
||||
}
|
||||
}
|
||||
|
||||
public Z3BaseParams(Func<bool> queryAbortFunction)
|
||||
{
|
||||
_queryAbortFunction = queryAbortFunction;
|
||||
}
|
||||
|
||||
public Z3BaseParams(Z3BaseParams z3Parameters)
|
||||
{
|
||||
_queryAbortFunction = z3Parameters._queryAbortFunction;
|
||||
}
|
||||
|
||||
#endregion Construction
|
||||
|
||||
#region ISolverParameters Members
|
||||
|
||||
/// <summary>
|
||||
/// Getter for the abort method
|
||||
/// </summary>
|
||||
public Func<bool> QueryAbort
|
||||
{
|
||||
get { return _queryAbortFunction; }
|
||||
set { _queryAbortFunction = value; }
|
||||
}
|
||||
|
||||
public OptimizationKind OptKind
|
||||
{
|
||||
get { return _optKind; }
|
||||
set { _optKind = value; }
|
||||
}
|
||||
|
||||
public CardinalityAlgorithm CardinalityAlgorithm
|
||||
{
|
||||
get { return _cardAlgorithm; }
|
||||
set { _cardAlgorithm = value; }
|
||||
}
|
||||
|
||||
public PseudoBooleanAlgorithm PseudoBooleanAlgorithm
|
||||
{
|
||||
get { return _pboAlgorithm; }
|
||||
set { _pboAlgorithm = value; }
|
||||
}
|
||||
|
||||
public ArithmeticStrategy ArithmeticStrategy
|
||||
{
|
||||
get { return _arithStrategy; }
|
||||
set { _arithStrategy = value; }
|
||||
}
|
||||
|
||||
public string SMT2LogFile
|
||||
{
|
||||
get { return _smt2LogFile; }
|
||||
set { _smt2LogFile = value; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
|
@ -1,387 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Z3;
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
internal enum Z3Result
|
||||
{
|
||||
Optimal,
|
||||
LocalOptimal,
|
||||
Feasible,
|
||||
Interrupted,
|
||||
Infeasible
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The basic solver class to take care of transformation from an MSF instance to an Z3 instance
|
||||
/// </summary>
|
||||
internal class Z3BaseSolver
|
||||
{
|
||||
/// <summary>Representing MSF model</summary>
|
||||
private IRowVariableModel _model;
|
||||
|
||||
/// <summary>The Z3 solver we are currently using</summary>
|
||||
private Context _context = null;
|
||||
|
||||
/// <summary>Default optimization solver</summary>
|
||||
private Optimize _optSolver = null;
|
||||
|
||||
/// <summary>Marks when we are inside the Solve() method</summary>
|
||||
private bool _isSolving = false;
|
||||
|
||||
/// <summary>A map from MSF variable ids to Z3 variables</summary>
|
||||
private Dictionary<int, Expr> _variables = new Dictionary<int, Expr>();
|
||||
|
||||
/// <summary>A map from MSF variable ids to Z3 goal ids</summary>
|
||||
private Dictionary<IGoal, Optimize.Handle> _goals = new Dictionary<IGoal, Optimize.Handle>();
|
||||
|
||||
internal Z3BaseSolver(IRowVariableModel model)
|
||||
{
|
||||
_model = model;
|
||||
}
|
||||
|
||||
internal Context Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
|
||||
internal Dictionary<int, Expr> Variables
|
||||
{
|
||||
get { return _variables; }
|
||||
}
|
||||
|
||||
internal Dictionary<IGoal, Optimize.Handle> Goals
|
||||
{
|
||||
get { return _goals; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Destructs a currently active Z3 solver and the associated data.
|
||||
/// </summary>
|
||||
internal void DestructSolver(bool checkInSolve)
|
||||
{
|
||||
if (_context != null)
|
||||
{
|
||||
if (checkInSolve && !_isSolving)
|
||||
{
|
||||
_variables.Clear();
|
||||
if (!_isSolving)
|
||||
{
|
||||
_optSolver.Dispose();
|
||||
_context.Dispose();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("Z3 destruction is invoked while in Solving phase.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a Z3 solver to be used.
|
||||
/// </summary>
|
||||
internal void ConstructSolver(Z3BaseParams parameters)
|
||||
{
|
||||
// If Z3 is there already, kill it
|
||||
if (_context != null)
|
||||
{
|
||||
DestructSolver(false);
|
||||
}
|
||||
|
||||
_context = new Context();
|
||||
_optSolver = _context.MkOptimize();
|
||||
var p = _context.MkParams();
|
||||
|
||||
switch (parameters.OptKind)
|
||||
{
|
||||
case OptimizationKind.BoundingBox:
|
||||
p.Add("priority", _context.MkSymbol("box"));
|
||||
break;
|
||||
case OptimizationKind.Lexicographic:
|
||||
p.Add("priority", _context.MkSymbol("lex"));
|
||||
break;
|
||||
case OptimizationKind.ParetoOptimal:
|
||||
p.Add("priority", _context.MkSymbol("pareto"));
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, String.Format("Unknown optimization option {0}", parameters.OptKind));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (parameters.CardinalityAlgorithm)
|
||||
{
|
||||
case CardinalityAlgorithm.FuMalik:
|
||||
p.Add("maxsat_engine", _context.MkSymbol("fu_malik"));
|
||||
break;
|
||||
case CardinalityAlgorithm.CoreMaxSAT:
|
||||
p.Add("maxsat_engine", _context.MkSymbol("core_maxsat"));
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, String.Format("Unknown cardinality algorithm option {0}", parameters.CardinalityAlgorithm));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (parameters.PseudoBooleanAlgorithm)
|
||||
{
|
||||
case PseudoBooleanAlgorithm.WeightedMaxSAT:
|
||||
p.Add("wmaxsat_engine", _context.MkSymbol("wmax"));
|
||||
break;
|
||||
case PseudoBooleanAlgorithm.IterativeWeightedMaxSAT:
|
||||
p.Add("wmaxsat_engine", _context.MkSymbol("iwmax"));
|
||||
break;
|
||||
case PseudoBooleanAlgorithm.BisectionWeightedMaxSAT:
|
||||
p.Add("wmaxsat_engine", _context.MkSymbol("bwmax"));
|
||||
break;
|
||||
case PseudoBooleanAlgorithm.WeightedPartialMaxSAT2:
|
||||
p.Add("wmaxsat_engine", _context.MkSymbol("wpm2"));
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, String.Format("Unknown pseudo-boolean algorithm option {0}", parameters.PseudoBooleanAlgorithm));
|
||||
break;
|
||||
}
|
||||
|
||||
switch (parameters.ArithmeticStrategy)
|
||||
{
|
||||
case ArithmeticStrategy.Basic:
|
||||
p.Add("engine", _context.MkSymbol("basic"));
|
||||
break;
|
||||
case ArithmeticStrategy.Farkas:
|
||||
p.Add("engine", _context.MkSymbol("farkas"));
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, String.Format("Unknown arithmetic strategy option {0}", parameters.ArithmeticStrategy));
|
||||
break;
|
||||
}
|
||||
|
||||
_optSolver.Parameters = p;
|
||||
}
|
||||
|
||||
internal ArithExpr GetVariable(int vid)
|
||||
{
|
||||
Expr variable;
|
||||
if (!_variables.TryGetValue(vid, out variable))
|
||||
{
|
||||
AddVariable(vid);
|
||||
variable = _variables[vid];
|
||||
}
|
||||
return (ArithExpr)variable;
|
||||
}
|
||||
|
||||
internal void AssertBool(BoolExpr row)
|
||||
{
|
||||
_optSolver.Assert(row);
|
||||
}
|
||||
|
||||
internal void AssertArith(int vid, ArithExpr variable)
|
||||
{
|
||||
// Get the bounds on the row
|
||||
Rational lower, upper;
|
||||
_model.GetBounds(vid, out lower, out upper);
|
||||
|
||||
// Case of equality
|
||||
if (lower == upper)
|
||||
{
|
||||
// Create the equality term
|
||||
Expr eqConst = GetNumeral(lower, variable.Sort);
|
||||
BoolExpr constraint = _context.MkEq(eqConst, variable);
|
||||
// Assert the constraint
|
||||
_optSolver.Assert(constraint);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If upper bound is finite assert the upper bound constraint
|
||||
if (lower.IsFinite)
|
||||
{
|
||||
// Create the lower Bound constraint
|
||||
ArithExpr lowerTerm = GetNumeral(lower, variable.Sort);
|
||||
BoolExpr constraint = _context.MkLe(lowerTerm, variable);
|
||||
// Assert the constraint
|
||||
_optSolver.Assert(constraint);
|
||||
}
|
||||
// If lower bound is finite assert the lower bound constraint
|
||||
if (upper.IsFinite)
|
||||
{
|
||||
// Create the upper bound constraint
|
||||
ArithExpr upperTerm = GetNumeral(upper, variable.Sort);
|
||||
BoolExpr constraint = _context.MkGe(upperTerm, variable);
|
||||
// Assert the constraint
|
||||
_optSolver.Assert(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a MSF variable with the corresponding assertion to the Z3 variables.
|
||||
/// </summary>
|
||||
/// <param name="vid">The MSF id of the variable</param>
|
||||
internal void AddVariable(int vid)
|
||||
{
|
||||
// Is the variable an integer
|
||||
bool isInteger = _model.GetIntegrality(vid);
|
||||
|
||||
// Construct the sort we will be using
|
||||
Sort sort = isInteger ? (Sort)_context.IntSort : (Sort)_context.RealSort;
|
||||
|
||||
// Get the variable key
|
||||
object key = _model.GetKeyFromIndex(vid);
|
||||
|
||||
// Try to construct the name
|
||||
string name;
|
||||
if (key != null) name = String.Format("x_{0}_{1}", key, vid);
|
||||
else name = String.Format("x_{0}", vid);
|
||||
ArithExpr variable = (ArithExpr)_context.MkConst(name, sort);
|
||||
|
||||
// Create the variable and add it to the map
|
||||
Debug.Assert(!_variables.ContainsKey(vid), "Variable names should be unique.");
|
||||
_variables.Add(vid, variable);
|
||||
|
||||
AssertArith(vid, variable);
|
||||
}
|
||||
|
||||
internal ArithExpr GetNumeral(Rational rational, Sort sort = null)
|
||||
{
|
||||
return Utils.GetNumeral(_context, rational, sort);
|
||||
}
|
||||
|
||||
internal void Solve(Z3BaseParams parameters, IEnumerable<IGoal> modelGoals,
|
||||
Action<int> addRow, Func<int, ArithExpr> mkGoalRow, Action<Z3Result> setResult)
|
||||
{
|
||||
_variables.Clear();
|
||||
_goals.Clear();
|
||||
|
||||
try
|
||||
{
|
||||
// Mark that we are in solving phase
|
||||
_isSolving = true;
|
||||
|
||||
// Construct Z3
|
||||
ConstructSolver(parameters);
|
||||
|
||||
// Add all the variables
|
||||
foreach (int vid in _model.VariableIndices)
|
||||
{
|
||||
AddVariable(vid);
|
||||
}
|
||||
|
||||
// Add all the rows
|
||||
foreach (int rid in _model.RowIndices)
|
||||
{
|
||||
addRow(rid);
|
||||
}
|
||||
|
||||
// Add enabled goals to optimization problem
|
||||
foreach (IGoal g in modelGoals)
|
||||
{
|
||||
if (!g.Enabled) continue;
|
||||
|
||||
ArithExpr gr = mkGoalRow(g.Index);
|
||||
if (g.Minimize)
|
||||
_goals.Add(g, _optSolver.MkMinimize(gr));
|
||||
else
|
||||
_goals.Add(g, _optSolver.MkMaximize(gr));
|
||||
}
|
||||
|
||||
if (_goals.Any() && parameters.SMT2LogFile != null)
|
||||
{
|
||||
Debug.WriteLine("Dumping SMT2 benchmark to log file...");
|
||||
File.WriteAllText(parameters.SMT2LogFile, _optSolver.ToString());
|
||||
}
|
||||
|
||||
bool aborted = parameters.QueryAbort();
|
||||
|
||||
if (!aborted)
|
||||
{
|
||||
// Start the abort thread
|
||||
AbortWorker abortWorker = new AbortWorker(_context, parameters.QueryAbort);
|
||||
Thread abortThread = new Thread(abortWorker.Start);
|
||||
abortThread.Start();
|
||||
|
||||
// Now solve the problem
|
||||
Status status = _optSolver.Check();
|
||||
|
||||
// Stop the abort thread
|
||||
abortWorker.Stop();
|
||||
abortThread.Join();
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case Status.SATISFIABLE:
|
||||
Microsoft.Z3.Model model = _optSolver.Model;
|
||||
Debug.Assert(model != null, "Should be able to get Z3 model.");
|
||||
// Remember the solution values
|
||||
foreach (KeyValuePair<int, Expr> pair in _variables)
|
||||
{
|
||||
var value = Utils.ToRational(model.Eval(pair.Value, true));
|
||||
_model.SetValue(pair.Key, value);
|
||||
}
|
||||
// Remember all objective values
|
||||
foreach (var pair in _goals)
|
||||
{
|
||||
var optimalValue = Utils.ToRational(pair.Value.Upper);
|
||||
_model.SetValue(pair.Key.Index, optimalValue);
|
||||
}
|
||||
model.Dispose();
|
||||
setResult(_goals.Any() ? Z3Result.Optimal : Z3Result.Feasible);
|
||||
break;
|
||||
case Status.UNSATISFIABLE:
|
||||
setResult(Z3Result.Infeasible);
|
||||
break;
|
||||
case Status.UNKNOWN:
|
||||
if (abortWorker.Aborted)
|
||||
{
|
||||
Microsoft.Z3.Model subOptimalModel = _optSolver.Model;
|
||||
if (subOptimalModel != null && subOptimalModel.NumConsts != 0)
|
||||
{
|
||||
// Remember the solution values
|
||||
foreach (KeyValuePair<int, Expr> pair in _variables)
|
||||
{
|
||||
var value = Utils.ToRational(subOptimalModel.Eval(pair.Value, true));
|
||||
_model.SetValue(pair.Key, value);
|
||||
}
|
||||
// Remember all objective values
|
||||
foreach (var pair in _goals)
|
||||
{
|
||||
var optimalValue = Utils.ToRational(pair.Value.Upper);
|
||||
_model.SetValue(pair.Key.Index, optimalValue);
|
||||
}
|
||||
subOptimalModel.Dispose();
|
||||
|
||||
setResult(Z3Result.LocalOptimal);
|
||||
}
|
||||
else
|
||||
setResult(Z3Result.Infeasible);
|
||||
}
|
||||
else
|
||||
setResult(Z3Result.Interrupted);
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Unrecognized Z3 Status");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSolving = false;
|
||||
}
|
||||
|
||||
// Now kill Z3
|
||||
DestructSolver(true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3MILPDirective : Z3BaseDirective
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3MILPParams : Z3BaseParams
|
||||
{
|
||||
// Need these constructors for reflection done by plugin model
|
||||
|
||||
public Z3MILPParams() : base() { }
|
||||
|
||||
public Z3MILPParams(Directive directive) : base(directive) { }
|
||||
|
||||
public Z3MILPParams(Func<bool> queryAbortFunction) : base(queryAbortFunction) { }
|
||||
|
||||
public Z3MILPParams(Z3BaseParams z3Parameters) : base (z3Parameters) { }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,236 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
|
||||
using Microsoft.Z3;
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using Microsoft.SolverFoundation.Plugin;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// The class is implementation of the MSF mixed linear programming solver
|
||||
/// using the Microsoft Z3 solver as the backend.
|
||||
/// </summary>
|
||||
public class Z3MILPSolver : LinearModel, ILinearSolver, ILinearSolution, IReportProvider
|
||||
{
|
||||
#region Private members
|
||||
|
||||
private LinearResult _result;
|
||||
private LinearSolutionQuality _solutionQuality;
|
||||
private Z3BaseSolver _solver;
|
||||
|
||||
#endregion Private members
|
||||
|
||||
#region Solver construction and destruction
|
||||
|
||||
/// <summary>Constructor that initializes the base classes</summary>
|
||||
public Z3MILPSolver() : base(null)
|
||||
{
|
||||
_result = LinearResult.Feasible;
|
||||
_solver = new Z3BaseSolver(this);
|
||||
}
|
||||
|
||||
/// <summary>Constructor that initializes the base classes</summary>
|
||||
public Z3MILPSolver(ISolverEnvironment context) : this() { }
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown can be called when when the solver is not active, i.e.
|
||||
/// when it is done with Solve() or it has gracefully returns from Solve()
|
||||
/// after an abort.
|
||||
/// </summary>
|
||||
public void Shutdown() { _solver.DestructSolver(true); }
|
||||
|
||||
#endregion Solver construction and destruction
|
||||
|
||||
#region Obtaining information about the solution
|
||||
|
||||
public ILinearSolverReport GetReport(LinearSolverReportType reportType)
|
||||
{
|
||||
// We don't support sensitivity report
|
||||
return null;
|
||||
}
|
||||
|
||||
#endregion Obtaining information about the solution
|
||||
|
||||
#region Construction of the problem
|
||||
|
||||
/// <summary>
|
||||
/// Get corresponding Z3 formula of a MSF row.
|
||||
/// </summary>
|
||||
/// <param name="rid">The MSF row id</param>
|
||||
private ArithExpr MkGoalRow(int rid)
|
||||
{
|
||||
// Start with the 0 term
|
||||
List<ArithExpr> row = new List<ArithExpr>();
|
||||
|
||||
// Now, add all the entries of this row
|
||||
foreach (LinearEntry entry in GetRowEntries(rid))
|
||||
{
|
||||
// Get the variable and constant in the row
|
||||
ArithExpr e = _solver.GetVariable(entry.Index);
|
||||
if (!entry.Value.IsOne)
|
||||
{
|
||||
e = _solver.Context.MkMul(_solver.GetNumeral(entry.Value, e.Sort), e);
|
||||
}
|
||||
row.Add(e);
|
||||
}
|
||||
switch (row.Count)
|
||||
{
|
||||
case 0: return _solver.GetNumeral(new Rational());
|
||||
case 1: return row[0];
|
||||
default: return _solver.Context.MkAdd(row.ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a MSF row to the Z3 assertions.
|
||||
/// </summary>
|
||||
/// <param name="rid">The MSF row id</param>
|
||||
private void AddRow(int rid)
|
||||
{
|
||||
// Start with the 0 term
|
||||
ArithExpr row = MkGoalRow(rid);
|
||||
_solver.AssertArith(rid, row);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set results based on internal solver status
|
||||
/// </summary>
|
||||
private void SetResult(Z3Result status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case Z3Result.Optimal:
|
||||
_result = LinearResult.Optimal;
|
||||
_solutionQuality = LinearSolutionQuality.Exact;
|
||||
break;
|
||||
case Z3Result.LocalOptimal:
|
||||
_result = LinearResult.Feasible;
|
||||
_solutionQuality = LinearSolutionQuality.Approximate;
|
||||
break;
|
||||
case Z3Result.Feasible:
|
||||
_result = LinearResult.Feasible;
|
||||
_solutionQuality = LinearSolutionQuality.Exact;
|
||||
break;
|
||||
case Z3Result.Infeasible:
|
||||
_result = LinearResult.InfeasiblePrimal;
|
||||
_solutionQuality = LinearSolutionQuality.None;
|
||||
break;
|
||||
case Z3Result.Interrupted:
|
||||
_result = LinearResult.Interrupted;
|
||||
_solutionQuality = LinearSolutionQuality.None;
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Unrecognized Z3 Result");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion Construction of the problem
|
||||
|
||||
#region Solving the problem
|
||||
|
||||
/// <summary>
|
||||
/// Starts solving the problem using the Z3 solver.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters to the solver</param>
|
||||
/// <returns>The solution to the problem</returns>
|
||||
public ILinearSolution Solve(ISolverParameters parameters)
|
||||
{
|
||||
// Get the Z3 parameters
|
||||
var z3Params = parameters as Z3BaseParams;
|
||||
Debug.Assert(z3Params != null, "Parameters should be an instance of Z3BaseParams.");
|
||||
|
||||
_solver.Solve(z3Params, Goals, AddRow, MkGoalRow, SetResult);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion Solving the problem
|
||||
|
||||
#region ILinearSolution Members
|
||||
|
||||
public Rational GetSolutionValue(int goalIndex)
|
||||
{
|
||||
var goal = Goals.ElementAt(goalIndex);
|
||||
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
|
||||
return GetValue(goal.Index);
|
||||
}
|
||||
|
||||
public void GetSolvedGoal(int goalIndex, out object key, out int vid, out bool minimize, out bool optimal)
|
||||
{
|
||||
var goal = Goals.ElementAt(goalIndex);
|
||||
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
|
||||
key = goal.Key;
|
||||
vid = goal.Index;
|
||||
minimize = goal.Minimize;
|
||||
optimal = _result == LinearResult.Optimal;
|
||||
}
|
||||
|
||||
// LpResult is LP relaxation assignment.
|
||||
|
||||
public LinearResult LpResult
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
public Rational MipBestBound
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(GoalCount > 0, "MipBestBound is only applicable for optimization instances.");
|
||||
return GetSolutionValue(0);
|
||||
}
|
||||
}
|
||||
|
||||
public LinearResult MipResult
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
public LinearResult Result
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
public LinearSolutionQuality SolutionQuality
|
||||
{
|
||||
get { return _solutionQuality; }
|
||||
}
|
||||
|
||||
public int SolvedGoalCount
|
||||
{
|
||||
get { return GoalCount; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Report GetReport(SolverContext context, Solution solution, SolutionMapping solutionMapping)
|
||||
{
|
||||
LinearSolutionMapping lpSolutionMapping = solutionMapping as LinearSolutionMapping;
|
||||
if (lpSolutionMapping == null && solutionMapping != null)
|
||||
throw new ArgumentException("solutionMapping is not a LinearSolutionMapping", "solutionMapping");
|
||||
return new Z3LinearSolverReport(context, this, solution, lpSolutionMapping);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Class implementing the LinearReport.
|
||||
/// </summary>
|
||||
public class Z3LinearSolverReport : LinearReport
|
||||
{
|
||||
public Z3LinearSolverReport(SolverContext context, ISolver solver, Solution solution, LinearSolutionMapping solutionMapping)
|
||||
: base(context, solver, solution, solutionMapping) {
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3TermDirective : Z3BaseDirective
|
||||
{
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
public class Z3TermParams : Z3BaseParams
|
||||
{
|
||||
public Z3TermParams() : base() { }
|
||||
|
||||
public Z3TermParams(Directive directive) : base(directive) { }
|
||||
|
||||
public Z3TermParams(Func<bool> queryAbortFunction) : base(queryAbortFunction) { }
|
||||
|
||||
public Z3TermParams(Z3BaseParams z3Parameters) : base(z3Parameters) { }
|
||||
}
|
||||
|
||||
}
|
|
@ -1,388 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Globalization;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Properties;
|
||||
using Microsoft.SolverFoundation.Solvers;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using Microsoft.Z3;
|
||||
using System.Linq;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
|
||||
namespace Microsoft.SolverFoundation.Plugin.Z3
|
||||
{
|
||||
/// <summary>
|
||||
/// The class is implementation of the MSF constraint solver
|
||||
/// using the Microsoft Z3 solver as the backend.
|
||||
/// This solver supports Int, Real constraints and their arbitrary boolean combinations.
|
||||
/// </summary>
|
||||
public class Z3TermSolver : TermModel, ITermSolver, INonlinearSolution, IReportProvider
|
||||
{
|
||||
private NonlinearResult _result;
|
||||
private Z3BaseSolver _solver;
|
||||
|
||||
/// <summary>Constructor that initializes the base classes</summary>
|
||||
public Z3TermSolver() : base(null)
|
||||
{
|
||||
_solver = new Z3BaseSolver(this);
|
||||
}
|
||||
|
||||
/// <summary>Constructor that initializes the base classes</summary>
|
||||
public Z3TermSolver(ISolverEnvironment context) : this() { }
|
||||
|
||||
/// <summary>
|
||||
/// Shutdown can be called when when the solver is not active, i.e.
|
||||
/// when it is done with Solve() or it has gracefully returns from Solve()
|
||||
/// after an abort.
|
||||
/// </summary>
|
||||
public void Shutdown() { _solver.DestructSolver(true); }
|
||||
|
||||
private BoolExpr MkBool(int rid)
|
||||
{
|
||||
var context = _solver.Context;
|
||||
|
||||
if (IsConstant(rid))
|
||||
{
|
||||
Rational lower, upper;
|
||||
GetBounds(rid, out lower, out upper);
|
||||
Debug.Assert(lower == upper);
|
||||
if (lower.IsZero) return context.MkFalse();
|
||||
return context.MkTrue();
|
||||
}
|
||||
if (IsOperation(rid))
|
||||
{
|
||||
BoolExpr[] children;
|
||||
ArithExpr[] operands;
|
||||
TermModelOperation op = GetOperation(rid);
|
||||
switch(op) {
|
||||
case TermModelOperation.And:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Conjunction requires at least two operands.");
|
||||
children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray();
|
||||
return context.MkAnd(children);
|
||||
case TermModelOperation.Or:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Disjunction requires at least two operands.");
|
||||
children = (GetOperands(rid)).Select(x => MkBool(x)).ToArray();
|
||||
return context.MkOr(children);
|
||||
case TermModelOperation.Not:
|
||||
Debug.Assert(GetOperandCount(rid) == 1, "Negation is unary.");
|
||||
return context.MkNot(MkBool(GetOperand(rid, 0)));
|
||||
case TermModelOperation.If:
|
||||
Debug.Assert(GetOperandCount(rid) == 3, "If is ternary.");
|
||||
BoolExpr b = MkBool(GetOperand(rid, 0));
|
||||
Expr x1 = MkBool(GetOperand(rid, 1));
|
||||
Expr x2 = MkBool(GetOperand(rid, 2));
|
||||
return (BoolExpr)context.MkITE(b, x1, x2);
|
||||
case TermModelOperation.Unequal:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Distinct should have at least two operands.");
|
||||
return context.MkDistinct((GetOperands(rid)).Select(x => MkTerm(x)).ToArray());
|
||||
case TermModelOperation.Greater:
|
||||
case TermModelOperation.Less:
|
||||
case TermModelOperation.GreaterEqual:
|
||||
case TermModelOperation.LessEqual:
|
||||
case TermModelOperation.Equal:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Comparison should have at least two operands.");
|
||||
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
|
||||
return ReduceComparison(GetOperation(rid), operands);
|
||||
case TermModelOperation.Identity:
|
||||
Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand.");
|
||||
return MkBool(GetOperand(rid, 0));
|
||||
default:
|
||||
return context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One));
|
||||
}
|
||||
}
|
||||
return context.MkEq(MkTerm(rid), _solver.GetNumeral(Rational.One));
|
||||
}
|
||||
|
||||
private ArithExpr MkBoolToArith(BoolExpr e)
|
||||
{
|
||||
var context = _solver.Context;
|
||||
return (ArithExpr)context.MkITE(e, _solver.GetNumeral(Rational.One), _solver.GetNumeral(Rational.Zero));
|
||||
}
|
||||
|
||||
private ArithExpr MkTerm(int rid)
|
||||
{
|
||||
var context = _solver.Context;
|
||||
|
||||
if (IsConstant(rid))
|
||||
{
|
||||
Rational lower, upper;
|
||||
GetBounds(rid, out lower, out upper);
|
||||
Debug.Assert(lower == upper);
|
||||
return _solver.GetNumeral(lower);
|
||||
}
|
||||
else if (IsOperation(rid))
|
||||
{
|
||||
ArithExpr[] operands;
|
||||
TermModelOperation op = GetOperation(rid);
|
||||
switch(op)
|
||||
{
|
||||
case TermModelOperation.And:
|
||||
case TermModelOperation.Or:
|
||||
case TermModelOperation.Not:
|
||||
case TermModelOperation.Unequal:
|
||||
case TermModelOperation.Greater:
|
||||
case TermModelOperation.Less:
|
||||
case TermModelOperation.GreaterEqual:
|
||||
case TermModelOperation.LessEqual:
|
||||
case TermModelOperation.Equal:
|
||||
return MkBoolToArith(MkBool(rid));
|
||||
case TermModelOperation.If:
|
||||
Debug.Assert(GetOperandCount(rid) == 3, "If is ternary.");
|
||||
BoolExpr b = MkBool(GetOperand(rid, 0));
|
||||
Expr x1 = MkTerm(GetOperand(rid, 1));
|
||||
Expr x2 = MkTerm(GetOperand(rid, 2));
|
||||
return (ArithExpr)context.MkITE(b, x1, x2);
|
||||
case TermModelOperation.Plus:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Plus takes at least two operands.");
|
||||
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
|
||||
return context.MkAdd(operands);
|
||||
case TermModelOperation.Minus:
|
||||
Debug.Assert(GetOperandCount(rid) == 1, "Minus takes exactly one operand.");
|
||||
return context.MkUnaryMinus(MkTerm(GetOperand(rid, 0)));
|
||||
case TermModelOperation.Times:
|
||||
Debug.Assert(GetOperandCount(rid) >= 2, "Times requires at least two operands.");
|
||||
operands = (GetOperands(rid)).Select(x => MkTerm(x)).ToArray();
|
||||
return context.MkMul(operands);
|
||||
case TermModelOperation.Identity:
|
||||
Debug.Assert(GetOperandCount(rid) == 1, "Identity takes exactly one operand.");
|
||||
return MkTerm(GetOperand(rid, 0));
|
||||
case TermModelOperation.Abs:
|
||||
Debug.Assert(GetOperandCount(rid) == 1, "Abs takes exactly one operand.");
|
||||
ArithExpr e = MkTerm(GetOperand(rid, 0));
|
||||
ArithExpr minusE = context.MkUnaryMinus(e);
|
||||
ArithExpr zero = _solver.GetNumeral(Rational.Zero);
|
||||
return (ArithExpr)context.MkITE(context.MkGe(e, zero), e, minusE);
|
||||
default:
|
||||
Console.Error.WriteLine("{0} operation isn't supported.", op);
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return _solver.GetVariable(rid);
|
||||
}
|
||||
}
|
||||
|
||||
private BoolExpr ReduceComparison(TermModelOperation type, ArithExpr[] operands)
|
||||
{
|
||||
var context = _solver.Context;
|
||||
Debug.Assert(operands.Length >= 2);
|
||||
Func<ArithExpr, ArithExpr, BoolExpr> mkComparison;
|
||||
switch (type)
|
||||
{
|
||||
case TermModelOperation.Greater:
|
||||
mkComparison = (x, y) => context.MkGt(x, y);
|
||||
break;
|
||||
case TermModelOperation.Less:
|
||||
mkComparison = (x, y) => context.MkLt(x, y);
|
||||
break;
|
||||
case TermModelOperation.GreaterEqual:
|
||||
mkComparison = (x, y) => context.MkGe(x, y);
|
||||
break;
|
||||
case TermModelOperation.LessEqual:
|
||||
mkComparison = (x, y) => context.MkLe(x, y);
|
||||
break;
|
||||
case TermModelOperation.Equal:
|
||||
mkComparison = (x, y) => context.MkEq(x, y);
|
||||
break;
|
||||
default:
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
BoolExpr current = mkComparison(operands[0], operands[1]);
|
||||
for (int i = 1; i < operands.Length - 1; ++i)
|
||||
current = context.MkAnd(current, mkComparison(operands[i], operands[i + 1]));
|
||||
return current;
|
||||
}
|
||||
|
||||
private bool IsBoolRow(int rid)
|
||||
{
|
||||
Rational lower, upper;
|
||||
GetBounds(rid, out lower, out upper);
|
||||
|
||||
return lower == upper && lower.IsOne && IsBoolTerm(rid);
|
||||
}
|
||||
|
||||
private bool IsBoolTerm(int rid)
|
||||
{
|
||||
if (IsConstant(rid))
|
||||
{
|
||||
Rational lower, upper;
|
||||
GetBounds(rid, out lower, out upper);
|
||||
Debug.Assert(lower == upper);
|
||||
return lower.IsOne || lower.IsZero;
|
||||
}
|
||||
if (IsOperation(rid))
|
||||
{
|
||||
TermModelOperation op = GetOperation(rid);
|
||||
switch (op)
|
||||
{
|
||||
case TermModelOperation.And:
|
||||
case TermModelOperation.Or:
|
||||
case TermModelOperation.Not:
|
||||
case TermModelOperation.LessEqual:
|
||||
case TermModelOperation.Less:
|
||||
case TermModelOperation.Greater:
|
||||
case TermModelOperation.GreaterEqual:
|
||||
case TermModelOperation.Unequal:
|
||||
case TermModelOperation.Equal:
|
||||
return true;
|
||||
case TermModelOperation.If:
|
||||
return IsBoolTerm(GetOperand(rid, 1)) &&
|
||||
IsBoolTerm(GetOperand(rid, 2));
|
||||
case TermModelOperation.Identity:
|
||||
return IsBoolTerm(GetOperand(rid, 0));
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a MSF row to the Z3 assertions.
|
||||
/// </summary>
|
||||
/// <param name="rid">The MSF row id</param>
|
||||
private void AddRow(int rid)
|
||||
{
|
||||
if (IsConstant(rid))
|
||||
return;
|
||||
|
||||
if (IsBoolRow(rid))
|
||||
{
|
||||
_solver.AssertBool(MkBool(rid));
|
||||
return;
|
||||
}
|
||||
// Start with the 0 term
|
||||
ArithExpr row = MkTerm(rid);
|
||||
_solver.AssertArith(rid, row);
|
||||
}
|
||||
|
||||
private TermModelOperation[] _supportedOperations =
|
||||
{ TermModelOperation.And,
|
||||
TermModelOperation.Or,
|
||||
TermModelOperation.Not,
|
||||
TermModelOperation.Unequal,
|
||||
TermModelOperation.Greater,
|
||||
TermModelOperation.Less,
|
||||
TermModelOperation.GreaterEqual,
|
||||
TermModelOperation.LessEqual,
|
||||
TermModelOperation.Equal,
|
||||
TermModelOperation.If,
|
||||
TermModelOperation.Plus,
|
||||
TermModelOperation.Minus,
|
||||
TermModelOperation.Times,
|
||||
TermModelOperation.Identity,
|
||||
TermModelOperation.Abs };
|
||||
|
||||
/// <summary>
|
||||
/// Gets the operations supported by the solver.
|
||||
/// </summary>
|
||||
/// <returns>All the TermModelOperations supported by the solver.</returns>
|
||||
public IEnumerable<TermModelOperation> SupportedOperations
|
||||
{
|
||||
get { return _supportedOperations; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set results based on internal solver status
|
||||
/// </summary>
|
||||
private void SetResult(Z3Result status)
|
||||
{
|
||||
switch (status)
|
||||
{
|
||||
case Z3Result.Optimal:
|
||||
_result = NonlinearResult.Optimal;
|
||||
break;
|
||||
case Z3Result.LocalOptimal:
|
||||
_result = NonlinearResult.LocalOptimal;
|
||||
break;
|
||||
case Z3Result.Feasible:
|
||||
_result = NonlinearResult.Feasible;
|
||||
break;
|
||||
case Z3Result.Infeasible:
|
||||
_result = NonlinearResult.Infeasible;
|
||||
break;
|
||||
case Z3Result.Interrupted:
|
||||
_result = NonlinearResult.Interrupted;
|
||||
break;
|
||||
default:
|
||||
Debug.Assert(false, "Unrecognized Z3 Result");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Starts solving the problem using the Z3 solver.
|
||||
/// </summary>
|
||||
/// <param name="parameters">Parameters to the solver</param>
|
||||
/// <returns>The solution to the problem</returns>
|
||||
public INonlinearSolution Solve(ISolverParameters parameters)
|
||||
{
|
||||
// Get the Z3 parameters
|
||||
var z3Params = parameters as Z3BaseParams;
|
||||
Debug.Assert(z3Params != null, "Parameters should be an instance of Z3BaseParams.");
|
||||
|
||||
_solver.Solve(z3Params, Goals, AddRow, MkTerm, SetResult);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
double INonlinearSolution.GetValue(int vid)
|
||||
{
|
||||
Debug.Assert(_solver.Variables.ContainsKey(vid), "This index should correspond to a variable.");
|
||||
return GetValue(vid).ToDouble();
|
||||
}
|
||||
|
||||
public int SolvedGoalCount
|
||||
{
|
||||
get { return GoalCount; }
|
||||
}
|
||||
|
||||
public double GetSolutionValue(int goalIndex)
|
||||
{
|
||||
var goal = Goals.ElementAt(goalIndex);
|
||||
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
|
||||
return GetValue(goal.Index).ToDouble();
|
||||
}
|
||||
|
||||
public void GetSolvedGoal(int goalIndex, out object key, out int vid, out bool minimize, out bool optimal)
|
||||
{
|
||||
var goal = Goals.ElementAt(goalIndex);
|
||||
Debug.Assert(goal != null, "Goal should be an element of the goal list.");
|
||||
key = goal.Key;
|
||||
vid = goal.Index;
|
||||
minimize = goal.Minimize;
|
||||
optimal = _result == NonlinearResult.Optimal;
|
||||
}
|
||||
|
||||
public NonlinearResult Result
|
||||
{
|
||||
get { return _result; }
|
||||
}
|
||||
|
||||
public Report GetReport(SolverContext context, Solution solution, SolutionMapping solutionMapping)
|
||||
{
|
||||
PluginSolutionMapping pluginSolutionMapping = solutionMapping as PluginSolutionMapping;
|
||||
if (pluginSolutionMapping == null && solutionMapping != null)
|
||||
throw new ArgumentException("solutionMapping is not a LinearSolutionMapping", "solutionMapping");
|
||||
return new Z3TermSolverReport(context, this, solution, pluginSolutionMapping);
|
||||
}
|
||||
}
|
||||
|
||||
public class Z3TermSolverReport : Report
|
||||
{
|
||||
public Z3TermSolverReport(SolverContext context, ISolver solver, Solution solution, PluginSolutionMapping pluginSolutionMapping)
|
||||
: base(context, solver, solution, pluginSolutionMapping)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="MsfConfig"
|
||||
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
|
||||
allowLocation="true"
|
||||
allowDefinition="Everywhere"
|
||||
allowExeDefinition="MachineToApplication"
|
||||
restartOnExternalChanges="true"
|
||||
requirePermission="true"/>
|
||||
</configSections>
|
||||
<MsfConfig>
|
||||
<MsfPluginSolvers>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MINLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="NLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
</MsfPluginSolvers>
|
||||
</MsfConfig>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
|
||||
</startup>
|
||||
</configuration>
|
|
@ -1,58 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section
|
||||
name="MsfConfig"
|
||||
type="Microsoft.SolverFoundation.Services.MsfConfigSection, Microsoft.Solver.Foundation"
|
||||
allowLocation="true"
|
||||
allowDefinition="Everywhere"
|
||||
allowExeDefinition="MachineToApplication"
|
||||
restartOnExternalChanges="true"
|
||||
requirePermission="true" />
|
||||
</configSections>
|
||||
<MsfConfig>
|
||||
<MsfPluginSolvers>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 MILP Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3MILPParams"/>
|
||||
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MILP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="LP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="MINLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
<MsfPluginSolver name="Microsoft Z3 Term Solver"
|
||||
capability="NLP"
|
||||
assembly="SolverFoundation.Plugin.Z3.dll"
|
||||
interface="Microsoft.SolverFoundation.Services.ITermSolver"
|
||||
solverclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermSolver"
|
||||
directiveclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermDirective"
|
||||
parameterclass="Microsoft.SolverFoundation.Plugin.Z3.Z3TermParams"/>
|
||||
</MsfPluginSolvers>
|
||||
</MsfConfig>
|
||||
</configuration>
|
|
@ -1,200 +0,0 @@
|
|||
|
||||
/*++
|
||||
Copyright (c) 2015 Microsoft Corporation
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.SolverFoundation.Common;
|
||||
using Microsoft.SolverFoundation.Solvers;
|
||||
using Microsoft.SolverFoundation.Plugin.Z3;
|
||||
using Microsoft.SolverFoundation.Services;
|
||||
using System.Text;
|
||||
|
||||
namespace Validator
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void LoadModel(SolverContext context, string fileName)
|
||||
{
|
||||
string ext = Path.GetExtension(fileName).ToLower();
|
||||
|
||||
if (ext == ".mps")
|
||||
{
|
||||
context.LoadModel(FileFormat.MPS, Path.GetFullPath(fileName));
|
||||
}
|
||||
else if (ext == ".smps")
|
||||
{
|
||||
context.LoadModel(FileFormat.SMPS, Path.GetFullPath(fileName));
|
||||
}
|
||||
else if (ext == ".oml")
|
||||
{
|
||||
context.LoadModel(FileFormat.OML, Path.GetFullPath(fileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException("This file format hasn't been supported.");
|
||||
}
|
||||
}
|
||||
|
||||
static void ExecuteZ3(string fileName, Z3BaseDirective directive)
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
try
|
||||
{
|
||||
LoadModel(context, fileName);
|
||||
|
||||
Solution solution = context.Solve(directive);
|
||||
Report report = solution.GetReport();
|
||||
Console.Write("{0}", report);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Skipping unsolvable instance in {0} with error message '{1}'.", fileName, e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.ClearModel();
|
||||
}
|
||||
}
|
||||
|
||||
static void ConvertToSMT2(string fileName, Z3BaseDirective directive)
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
try
|
||||
{
|
||||
LoadModel(context, fileName);
|
||||
|
||||
if (context.CurrentModel.Goals.Any())
|
||||
{
|
||||
directive.SMT2LogFile = Path.ChangeExtension(fileName, ".smt2");
|
||||
context.Solve(() => true, directive);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Skipping unconvertable instance in {0} with error message '{1}'.", fileName, e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.ClearModel();
|
||||
}
|
||||
}
|
||||
|
||||
static void ValidateZ3(string fileName, Z3BaseDirective directive)
|
||||
{
|
||||
SolverContext context = SolverContext.GetContext();
|
||||
try
|
||||
{
|
||||
LoadModel(context, fileName);
|
||||
|
||||
if (context.CurrentModel.Goals.Any())
|
||||
{
|
||||
var msfDirective = (directive is Z3MILPDirective) ? (Directive)new MixedIntegerProgrammingDirective() { TimeLimit = 10000 }
|
||||
: (Directive)new Directive() { TimeLimit = 10000 };
|
||||
var sol1 = context.Solve(msfDirective);
|
||||
|
||||
Console.WriteLine("Solved the model using MSF.");
|
||||
Console.Write("{0}", sol1.GetReport());
|
||||
var expectedGoals = sol1.Goals.Select(x => x.ToDouble());
|
||||
context.ClearModel();
|
||||
|
||||
context.LoadModel(FileFormat.OML, Path.GetFullPath(fileName));
|
||||
directive.SMT2LogFile = Path.ChangeExtension(fileName, ".smt2");
|
||||
var sol2 = context.Solve(directive);
|
||||
//Console.Write("{0}", sol2.GetReport());
|
||||
var actualGoals = sol2.Goals.Select(x => x.ToDouble());
|
||||
|
||||
Console.WriteLine("Solved the model using Z3.");
|
||||
var goalPairs = expectedGoals.Zip(actualGoals, (expected, actual) => new { expected, actual }).ToArray();
|
||||
bool validated = goalPairs.All(p => Math.Abs(p.expected - p.actual) <= 0.0001);
|
||||
if (validated)
|
||||
{
|
||||
Console.WriteLine("INFO: Two solvers give approximately the same results.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.Error.WriteLine("ERROR: Discrepancy found between results.");
|
||||
if (!validated && File.Exists(directive.SMT2LogFile))
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
for(int i = 0; i < goalPairs.Length; i++)
|
||||
{
|
||||
sb.AppendFormat("\n(echo \"Goal {0}: actual |-> {1:0.0000}, expected |-> {2:0.0000}\")",
|
||||
i + 1, goalPairs[i].actual, goalPairs[i].expected);
|
||||
}
|
||||
Console.Error.WriteLine(sb.ToString());
|
||||
File.AppendAllText(directive.SMT2LogFile, sb.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Ignoring this instance without having any goal.");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine("Skipping unsolvable instance in {0} with error message '{1}'.",
|
||||
fileName, e.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
context.ClearModel();
|
||||
}
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
Z3BaseDirective directive = new Z3MILPDirective();
|
||||
|
||||
for (int i = 0; i < args.Length; ++i) {
|
||||
if (args[i] == "-s" || args[i] == "-solve")
|
||||
{
|
||||
ExecuteZ3(args[i + 1], directive);
|
||||
return;
|
||||
}
|
||||
if (args[i] == "-c" || args[i] == "-convert")
|
||||
{
|
||||
ConvertToSMT2(args[i + 1], directive);
|
||||
return;
|
||||
}
|
||||
if (args[i] == "-v" || args[i] == "-validate")
|
||||
{
|
||||
ValidateZ3(args[i + 1], directive);
|
||||
return;
|
||||
}
|
||||
if (args[i] == "-t" || args[i] == "-term")
|
||||
{
|
||||
directive = new Z3TermDirective();
|
||||
}
|
||||
}
|
||||
|
||||
if (args.Length > 0)
|
||||
{
|
||||
ExecuteZ3(args[0], directive);
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine(@"
|
||||
Validator is a simple command line to migrate benchmarks from OML, MPS and SMPS to SMT2 formats.
|
||||
|
||||
Commands:
|
||||
-solve <file_name> : solving the model using Z3
|
||||
-convert <file_name> : converting the model into SMT2 format
|
||||
-validate <file_name> : validating by comparing results between Z3 and MSF solvers
|
||||
-term : change the default Z3 MILP solver to Z3 Term solver
|
||||
|
||||
where <file_name> is any file with OML, MPS or SMPS extension.
|
||||
|
||||
Examples:
|
||||
Validator.exe -convert model.mps
|
||||
Validator.exe -term -solve model.oml
|
||||
|
||||
");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("testSolver")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("testSolver")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2009")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("c03c1084-d119-483f-80fe-c639eae75959")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
|
@ -1,123 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.21022</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{54835857-129F-44C9-B529-A42158647B36}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Validator</RootNamespace>
|
||||
<AssemblyName>Validator</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x64\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<OutputPath>bin\x64\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
|
||||
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<OutputPath>bin\x86\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\x86\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.Solver.Foundation">
|
||||
<HintPath>..\Microsoft.Solver.Foundation.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core">
|
||||
</Reference>
|
||||
<Reference Include="System.Xml.Linq">
|
||||
</Reference>
|
||||
<Reference Include="System.Data.DataSetExtensions">
|
||||
</Reference>
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
<None Include="MicrosoftSolverFoundationForExcel.dll.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj">
|
||||
<Project>{7340e664-f648-4ff7-89b2-f4da424996d3}</Project>
|
||||
<Name>SolverFoundation.Plugin.Z3</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
|
@ -1,125 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2012
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SolverFoundation.Plugin.Z3", "SolverFoundation.Plugin.Z3\SolverFoundation.Plugin.Z3.csproj", "{7340E664-F648-4FF7-89B2-F4DA424996D3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SolverFoundation.Plugin.Z3.Tests", "SolverFoundation.Plugin.Z3.Tests\SolverFoundation.Plugin.Z3.Tests.csproj", "{280AEE2F-1FDB-4A27-BE37-14DC154C873B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Validator", "Validator\Validator.csproj", "{54835857-129F-44C9-B529-A42158647B36}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{F1E99540-BA5E-46DF-9E29-6146A309CD18}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
README = README
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
commercial_64|Any CPU = commercial_64|Any CPU
|
||||
commercial_64|Mixed Platforms = commercial_64|Mixed Platforms
|
||||
commercial_64|x64 = commercial_64|x64
|
||||
commercial_64|x86 = commercial_64|x86
|
||||
commercial|Any CPU = commercial|Any CPU
|
||||
commercial|Mixed Platforms = commercial|Mixed Platforms
|
||||
commercial|x64 = commercial|x64
|
||||
commercial|x86 = commercial|x86
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Debug|Mixed Platforms = Debug|Mixed Platforms
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|Any CPU = Release|Any CPU
|
||||
Release|Mixed Platforms = Release|Mixed Platforms
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Any CPU.ActiveCfg = commercial_64|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Any CPU.Build.0 = commercial_64|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Mixed Platforms.ActiveCfg = commercial_64|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|Mixed Platforms.Build.0 = commercial_64|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x64.ActiveCfg = commercial_64|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x86.ActiveCfg = commercial_64|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial_64|x86.Build.0 = commercial_64|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Any CPU.ActiveCfg = commercial|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Any CPU.Build.0 = commercial|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Mixed Platforms.ActiveCfg = commercial|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|Mixed Platforms.Build.0 = commercial|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x64.ActiveCfg = commercial|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x86.ActiveCfg = commercial|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.commercial|x86.Build.0 = commercial|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Debug|x86.Build.0 = Debug|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x86.ActiveCfg = Release|x86
|
||||
{7340E664-F648-4FF7-89B2-F4DA424996D3}.Release|x86.Build.0 = Release|x86
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Any CPU.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|x64.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial_64|x86.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Any CPU.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|x64.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.commercial|x86.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{280AEE2F-1FDB-4A27-BE37-14DC154C873B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Any CPU.Build.0 = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|Mixed Platforms.Build.0 = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x64.ActiveCfg = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x64.Build.0 = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x86.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial_64|x86.Build.0 = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|Any CPU.Build.0 = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|Mixed Platforms.Build.0 = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|x64.ActiveCfg = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|x64.Build.0 = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|x86.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.commercial|x86.Build.0 = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|x64.Build.0 = Debug|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|x86.ActiveCfg = Debug|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Debug|x86.Build.0 = Debug|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|x64.ActiveCfg = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|x64.Build.0 = Release|x64
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|x86.ActiveCfg = Release|x86
|
||||
{54835857-129F-44C9-B529-A42158647B36}.Release|x86.Build.0 = Release|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
93
examples/python/prooflogs.py
Normal file
93
examples/python/prooflogs.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
# This script illustrates uses of proof logs over the Python interface.
|
||||
|
||||
from z3 import *
|
||||
|
||||
example1 = """
|
||||
(declare-sort T)
|
||||
|
||||
(declare-fun subtype (T T) Bool)
|
||||
|
||||
;; subtype is reflexive
|
||||
(assert (forall ((x T)) (subtype x x)))
|
||||
|
||||
;; subtype is antisymmetric
|
||||
(assert (forall ((x T) (y T)) (=> (and (subtype x y)
|
||||
(subtype y x))
|
||||
(= x y))))
|
||||
;; subtype is transitive
|
||||
(assert (forall ((x T) (y T) (z T)) (=> (and (subtype x y)
|
||||
(subtype y z))
|
||||
(subtype x z))))
|
||||
;; subtype has the tree-property
|
||||
(assert (forall ((x T) (y T) (z T)) (=> (and (subtype x z)
|
||||
(subtype y z))
|
||||
(or (subtype x y)
|
||||
(subtype y x)))))
|
||||
|
||||
;; now we define a simple example using the axiomatization above.
|
||||
(declare-const obj-type T)
|
||||
(declare-const int-type T)
|
||||
(declare-const real-type T)
|
||||
(declare-const complex-type T)
|
||||
(declare-const string-type T)
|
||||
|
||||
;; we have an additional axiom: every type is a subtype of obj-type
|
||||
(assert (forall ((x T)) (subtype x obj-type)))
|
||||
|
||||
(assert (subtype int-type real-type))
|
||||
(assert (subtype real-type complex-type))
|
||||
(assert (not (subtype string-type real-type)))
|
||||
(declare-const root-type T)
|
||||
(assert (subtype obj-type root-type))
|
||||
"""
|
||||
|
||||
def monitor_plain():
|
||||
print("Monitor all inferred clauses")
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
onc = OnClause(s, lambda pr, clause : print(pr, clause))
|
||||
print(s.check())
|
||||
|
||||
def log_instance(pr, clause):
|
||||
if pr.decl().name() == "inst":
|
||||
q = pr.arg(0).arg(0) # first argument is Not(q)
|
||||
for ch in pr.children():
|
||||
if ch.decl().name() == "bind":
|
||||
print("Binding")
|
||||
print(q)
|
||||
print(ch.children())
|
||||
break
|
||||
|
||||
def monitor_instances():
|
||||
print("Monitor just quantifier bindings")
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
onc = OnClause(s, log_instance)
|
||||
print(s.check())
|
||||
|
||||
def monitor_with_proofs():
|
||||
print("Monitor clauses annotated with detailed justifications")
|
||||
set_param(proof=True)
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
onc = OnClause(s, lambda pr, clause : print(pr, clause))
|
||||
print(s.check())
|
||||
|
||||
def monitor_new_core():
|
||||
print("Monitor proof objects from the new core")
|
||||
set_param("sat.euf", True)
|
||||
set_param("tactic.default_tactic", "sat")
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
onc = OnClause(s, lambda pr, clause : print(pr, clause))
|
||||
print(s.check())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
monitor_plain()
|
||||
monitor_instances()
|
||||
monitor_new_core()
|
||||
|
||||
|
||||
# Monitoring with proofs cannot be done in the same session
|
||||
# monitor_with_proofs()
|
113
examples/python/proofreplay.py
Normal file
113
examples/python/proofreplay.py
Normal file
|
@ -0,0 +1,113 @@
|
|||
# This script illustrates uses of proof replay and proof logs over the Python interface.
|
||||
|
||||
from z3 import *
|
||||
|
||||
example1 = """
|
||||
(declare-sort T)
|
||||
|
||||
(declare-fun subtype (T T) Bool)
|
||||
|
||||
;; subtype is reflexive
|
||||
(assert (forall ((x T)) (subtype x x)))
|
||||
|
||||
;; subtype is antisymmetric
|
||||
(assert (forall ((x T) (y T)) (=> (and (subtype x y)
|
||||
(subtype y x))
|
||||
(= x y))))
|
||||
;; subtype is transitive
|
||||
(assert (forall ((x T) (y T) (z T)) (=> (and (subtype x y)
|
||||
(subtype y z))
|
||||
(subtype x z))))
|
||||
;; subtype has the tree-property
|
||||
(assert (forall ((x T) (y T) (z T)) (=> (and (subtype x z)
|
||||
(subtype y z))
|
||||
(or (subtype x y)
|
||||
(subtype y x)))))
|
||||
|
||||
;; now we define a simple example using the axiomatization above.
|
||||
(declare-const obj-type T)
|
||||
(declare-const int-type T)
|
||||
(declare-const real-type T)
|
||||
(declare-const complex-type T)
|
||||
(declare-const string-type T)
|
||||
|
||||
;; we have an additional axiom: every type is a subtype of obj-type
|
||||
(assert (forall ((x T)) (subtype x obj-type)))
|
||||
|
||||
(assert (subtype int-type real-type))
|
||||
(assert (subtype real-type complex-type))
|
||||
(assert (not (subtype string-type real-type)))
|
||||
(declare-const root-type T)
|
||||
(assert (subtype obj-type root-type))
|
||||
"""
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("Solve and log inferences")
|
||||
print("--------------------------------------------------------")
|
||||
|
||||
# inference logging, replay, and checking is supported for
|
||||
# the core enabled by setting sat.euf = true.
|
||||
# setting the default tactic to 'sat' bypasses other tactics that could
|
||||
# end up using different solvers.
|
||||
set_param("sat.euf", True)
|
||||
set_param("tactic.default_tactic", "sat")
|
||||
|
||||
# Set a log file to trace inferences
|
||||
set_param("sat.smt.proof", "proof_log.smt2")
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
print(s.check())
|
||||
print(s.statistics())
|
||||
print("Parse the logged inferences and replay them")
|
||||
print("--------------------------------------------------------")
|
||||
|
||||
# Reset the log file to an invalid (empty) file name.
|
||||
set_param("sat.smt.proof", "")
|
||||
|
||||
# Turn off proof checking. It is on by default when parsing proof logs.
|
||||
set_param("solver.proof.check", False)
|
||||
s = Solver()
|
||||
onc = OnClause(s, lambda pr, clause : print(pr, clause))
|
||||
s.from_file("proof_log.smt2")
|
||||
|
||||
|
||||
print("Parse the logged inferences and check them")
|
||||
print("--------------------------------------------------------")
|
||||
s = Solver()
|
||||
|
||||
# Now turn on proof checking. It invokes the self-validator.
|
||||
# The self-validator produces log lines of the form:
|
||||
# (proofs +tseitin 60 +alldiff 8 +euf 3 +rup 5 +inst 6 -quant 3 -inst 2)
|
||||
# (verified-smt
|
||||
# (inst (forall (vars (x T) (y T) (z T)) (or (subtype (:var 2) (:var 1)) ...
|
||||
# The 'proofs' line summarizes inferences that were self-validated.
|
||||
# The pair +tseitin 60 indicates that 60 inferences were validated as Tseitin
|
||||
# encodings.
|
||||
# The pair -inst 2 indicates that two quantifier instantiations were not self-validated
|
||||
# They were instead validated using a call to SMT solving. A log for an smt invocation
|
||||
# is exemplified in the next line.
|
||||
# Note that the pair +inst 6 indicates that 6 quantifier instantations were validated
|
||||
# using a syntactic (cheap) check. Some quantifier instantiations based on quantifier elimination
|
||||
# are not simple substitutions and therefore a simple syntactic check does not suffice.
|
||||
set_param("solver.proof.check", True)
|
||||
s.from_file("proof_log.smt2")
|
||||
|
||||
print("Verify and self-validate on the fly")
|
||||
print("--------------------------------------------------------")
|
||||
set_param("sat.smt.proof.check", True)
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
print(s.check())
|
||||
print(s.statistics())
|
||||
|
||||
print("Verify and self-validate on the fly, but don't check rup")
|
||||
print("--------------------------------------------------------")
|
||||
set_param("sat.smt.proof.check", True)
|
||||
set_param("sat.smt.proof.check_rup", False)
|
||||
s = Solver()
|
||||
s.from_string(example1)
|
||||
print(s.check())
|
||||
print(s.statistics())
|
||||
|
||||
|
||||
|
|
@ -2305,12 +2305,26 @@ static void display_smt2(std::ostream& out) {
|
|||
return;
|
||||
}
|
||||
|
||||
z3::expr_vector asms(ctx);
|
||||
size_t num_assumptions = fmls.m_formulas.size();
|
||||
for (size_t i = 0; i < num_assumptions; ++i)
|
||||
asms.push_back(fmls.m_formulas[i]);
|
||||
|
||||
Z3_ast* assumptions = new Z3_ast[num_assumptions];
|
||||
for (size_t i = 0; i < num_assumptions; ++i) {
|
||||
assumptions[i] = fmls.m_formulas[i];
|
||||
for (size_t i = 0; i < asms.size(); ++i) {
|
||||
z3::expr fml = asms[i];
|
||||
if (fml.is_and()) {
|
||||
z3::expr arg0 = fml.arg(0);
|
||||
asms.set(i, arg0);
|
||||
for (unsigned j = 1; j < fml.num_args(); ++j)
|
||||
asms.push_back(fml.arg(j));
|
||||
--i;
|
||||
}
|
||||
}
|
||||
|
||||
Z3_ast* assumptions = new Z3_ast[asms.size()];
|
||||
for (size_t i = 0; i < asms.size(); ++i)
|
||||
assumptions[i] = asms[i];
|
||||
Z3_set_ast_print_mode(ctx, Z3_PRINT_SMTLIB_FULL);
|
||||
Z3_string s =
|
||||
Z3_benchmark_to_smtlib_string(
|
||||
ctx,
|
||||
|
@ -2318,7 +2332,7 @@ static void display_smt2(std::ostream& out) {
|
|||
0, // no logic is set
|
||||
"unknown", // no status annotation
|
||||
"", // attributes
|
||||
static_cast<unsigned>(num_assumptions),
|
||||
static_cast<unsigned>(asms.size()),
|
||||
assumptions,
|
||||
ctx.bool_val(true));
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ jobs:
|
|||
publishSymbols: true
|
||||
symbolServerType: TeamServices
|
||||
detailedLog: true
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: Sign
|
||||
inputs:
|
||||
ConnectedServiceName: 'z3-esrp-signing-2'
|
||||
|
|
|
@ -672,6 +672,7 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
|
|||
components.
|
||||
"""
|
||||
ADD_TACTIC_DATA = []
|
||||
ADD_SIMPLIFIER_DATA = []
|
||||
ADD_PROBE_DATA = []
|
||||
def ADD_TACTIC(name, descr, cmd):
|
||||
ADD_TACTIC_DATA.append((name, descr, cmd))
|
||||
|
@ -679,9 +680,13 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
|
|||
def ADD_PROBE(name, descr, cmd):
|
||||
ADD_PROBE_DATA.append((name, descr, cmd))
|
||||
|
||||
def ADD_SIMPLIFIER(name, descr, cmd):
|
||||
ADD_SIMPLIFIER_DATA.append((name, descr, cmd))
|
||||
|
||||
eval_globals = {
|
||||
'ADD_TACTIC': ADD_TACTIC,
|
||||
'ADD_PROBE': ADD_PROBE,
|
||||
'ADD_SIMPLIFIER': ADD_SIMPLIFIER
|
||||
}
|
||||
|
||||
assert isinstance(h_files_full_path, list)
|
||||
|
@ -691,9 +696,11 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
|
|||
fout.write('// Automatically generated file.\n')
|
||||
fout.write('#include "tactic/tactic.h"\n')
|
||||
fout.write('#include "cmd_context/tactic_cmds.h"\n')
|
||||
fout.write('#include "cmd_context/simplifier_cmds.h"\n')
|
||||
fout.write('#include "cmd_context/cmd_context.h"\n')
|
||||
tactic_pat = re.compile('[ \t]*ADD_TACTIC\(.*\)')
|
||||
probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)')
|
||||
probe_pat = re.compile('[ \t]*ADD_PROBE\(.*\)')
|
||||
simplifier_pat = re.compile('[ \t]*ADD_SIMPLIFIER\(.*\)')
|
||||
for h_file in sorted_headers_by_component(h_files_full_path):
|
||||
added_include = False
|
||||
try:
|
||||
|
@ -719,17 +726,31 @@ def mk_install_tactic_cpp_internal(h_files_full_path, path):
|
|||
_logger.error("Failed processing ADD_PROBE command at '{}'\n{}".format(
|
||||
fullname, line))
|
||||
raise e
|
||||
if simplifier_pat.match(line):
|
||||
if not added_include:
|
||||
added_include = True
|
||||
fout.write('#include "%s"\n' % path_after_src(h_file))
|
||||
try:
|
||||
eval(line.strip('\n '), eval_globals, None)
|
||||
except Exception as e:
|
||||
_logger.error("Failed processing ADD_SIMPLIFIER command at '{}'\n{}".format(
|
||||
fullname, line))
|
||||
raise e
|
||||
|
||||
except Exception as e:
|
||||
_logger.error("Failed to read file {}\n".format(h_file))
|
||||
raise e
|
||||
# First pass will just generate the tactic factories
|
||||
fout.write('#define ADD_TACTIC_CMD(NAME, DESCR, CODE) ctx.insert(alloc(tactic_cmd, symbol(NAME), DESCR, [](ast_manager &m, const params_ref &p) { return CODE; }))\n')
|
||||
fout.write('#define ADD_PROBE(NAME, DESCR, PROBE) ctx.insert(alloc(probe_info, symbol(NAME), DESCR, PROBE))\n')
|
||||
fout.write('#define ADD_SIMPLIFIER_CMD(NAME, DESCR, CODE) ctx.insert(alloc(simplifier_cmd, symbol(NAME), DESCR, [](auto& m, auto& p, auto &s) -> dependent_expr_simplifier* { return CODE; }))\n')
|
||||
fout.write('void install_tactics(tactic_manager & ctx) {\n')
|
||||
for data in ADD_TACTIC_DATA:
|
||||
fout.write(' ADD_TACTIC_CMD("%s", "%s", %s);\n' % data)
|
||||
for data in ADD_PROBE_DATA:
|
||||
fout.write(' ADD_PROBE("%s", "%s", %s);\n' % data)
|
||||
for data in ADD_SIMPLIFIER_DATA:
|
||||
fout.write(' ADD_SIMPLIFIER_CMD("%s", "%s", %s);\n' % data)
|
||||
fout.write('}\n')
|
||||
fout.close()
|
||||
return fullname
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
from mk_util import *
|
||||
|
||||
def init_version():
|
||||
set_version(4, 11, 3, 0) # express a default build version or pick up ci build version
|
||||
set_version(4, 12, 2, 0) # express a default build version or pick up ci build version
|
||||
|
||||
# Z3 Project definition
|
||||
def init_project_def():
|
||||
|
@ -20,48 +20,50 @@ def init_project_def():
|
|||
add_lib('simplex', ['util'], 'math/simplex')
|
||||
add_lib('hilbert', ['util'], 'math/hilbert')
|
||||
add_lib('automata', ['util'], 'math/automata')
|
||||
add_lib('params', ['util'])
|
||||
add_lib('realclosure', ['interval'], 'math/realclosure')
|
||||
add_lib('subpaving', ['interval'], 'math/subpaving')
|
||||
add_lib('ast', ['util', 'polynomial'])
|
||||
add_lib('euf', ['ast', 'util'], 'ast/euf')
|
||||
add_lib('params', ['util'])
|
||||
add_lib('smt_params', ['params'], 'smt/params')
|
||||
add_lib('smt_params', ['ast', 'params'], 'smt/params')
|
||||
add_lib('parser_util', ['ast'], 'parsers/util')
|
||||
add_lib('euf', ['ast'], 'ast/euf')
|
||||
add_lib('grobner', ['ast', 'dd', 'simplex'], 'math/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')
|
||||
add_lib('macros', ['rewriter'], 'ast/macros')
|
||||
add_lib('rewriter', ['ast', 'polynomial', 'interval', 'automata', 'params'], 'ast/rewriter')
|
||||
add_lib('bit_blaster', ['rewriter'], 'ast/rewriter/bit_blaster')
|
||||
add_lib('normal_forms', ['rewriter'], 'ast/normal_forms')
|
||||
add_lib('model', ['rewriter', 'macros'])
|
||||
add_lib('tactic', ['ast', 'model'])
|
||||
add_lib('substitution', ['ast', 'rewriter'], 'ast/substitution')
|
||||
add_lib('parser_util', ['ast'], 'parsers/util')
|
||||
add_lib('proofs', ['rewriter', 'util'], 'ast/proofs')
|
||||
add_lib('solver', ['params', 'model', 'tactic', 'proofs'])
|
||||
add_lib('substitution', ['rewriter'], 'ast/substitution')
|
||||
add_lib('proofs', ['rewriter'], 'ast/proofs')
|
||||
add_lib('macros', ['rewriter'], 'ast/macros')
|
||||
add_lib('model', ['macros'])
|
||||
add_lib('converters', ['model'], 'ast/converters')
|
||||
add_lib('simplifiers', ['euf', 'normal_forms', 'bit_blaster', 'converters', 'substitution'], 'ast/simplifiers')
|
||||
add_lib('tactic', ['simplifiers'])
|
||||
add_lib('mbp', ['model', 'simplex'], 'qe/mbp')
|
||||
add_lib('qe_lite', ['tactic', 'mbp'], 'qe/lite')
|
||||
add_lib('solver', ['params', 'smt_params', 'model', 'tactic', 'qe_lite', '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')
|
||||
add_lib('aig_tactic', ['tactic'], 'tactic/aig')
|
||||
add_lib('ackermannization', ['model', 'rewriter', 'ast', 'solver', 'tactic'], 'ackermannization')
|
||||
add_lib('fpa', ['ast', 'util', 'rewriter', 'model'], 'ast/fpa')
|
||||
add_lib('bit_blaster', ['rewriter', 'params'], 'ast/rewriter/bit_blaster')
|
||||
add_lib('core_tactics', ['tactic', 'macros', 'normal_forms', 'rewriter', 'pattern'], 'tactic/core')
|
||||
add_lib('arith_tactics', ['core_tactics', 'sat'], 'tactic/arith')
|
||||
add_lib('mbp', ['model', 'simplex'], 'qe/mbp')
|
||||
add_lib('qe_lite', ['tactic', 'mbp'], 'qe/lite')
|
||||
add_lib('solver_assertions', ['pattern','smt_params','cmd_context','qe_lite'], 'solver/assertions')
|
||||
add_lib('bigfix',['util'], 'math/bigfix')
|
||||
add_lib('polysat_univariate_solver', ['util', 'solver'], 'math/polysat/univariate')
|
||||
add_lib('polysat', ['bigfix','util','dd','simplex','interval','polysat_univariate_solver'], 'math/polysat')
|
||||
add_lib('solver_assertions', ['pattern','smt_params','cmd_context','qe_lite'], 'solver/assertions')
|
||||
add_lib('sat_smt', ['sat', 'euf', 'tactic', 'solver', 'smt_params', 'bit_blaster', 'fpa', 'mbp', 'normal_forms', 'lp', 'pattern', 'qe_lite', 'polysat'], 'sat/smt')
|
||||
add_lib('sat_tactic', ['tactic', 'sat', 'solver', 'sat_smt'], 'sat/tactic')
|
||||
add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic')
|
||||
add_lib('subpaving_tactic', ['core_tactics', 'subpaving'], 'math/subpaving/tactic')
|
||||
|
||||
add_lib('proto_model', ['model', 'rewriter', 'smt_params'], 'smt/proto_model')
|
||||
add_lib('smt', ['bit_blaster', 'macros', 'normal_forms', 'cmd_context', 'proto_model', 'solver_assertions',
|
||||
'substitution', 'grobner', 'simplex', 'proofs', 'pattern', 'parser_util', 'fpa', 'lp'])
|
||||
add_lib('sat_smt', ['sat', 'euf', 'smt', 'tactic', 'solver', 'smt_params', 'bit_blaster', 'fpa', 'mbp', 'normal_forms', 'lp', 'pattern', 'qe_lite', 'polysat'], 'sat/smt')
|
||||
add_lib('sat_tactic', ['tactic', 'sat', 'solver', 'sat_smt'], 'sat/tactic')
|
||||
add_lib('nlsat_tactic', ['nlsat', 'sat_tactic', 'arith_tactics'], 'nlsat/tactic')
|
||||
add_lib('bv_tactics', ['tactic', 'bit_blaster', 'core_tactics'], 'tactic/bv')
|
||||
add_lib('fuzzing', ['ast'], 'test/fuzzing')
|
||||
add_lib('smt_tactic', ['smt'], 'smt/tactic')
|
||||
|
@ -85,9 +87,9 @@ def init_project_def():
|
|||
add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'fd_solver', 'qe', 'sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
|
||||
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt')
|
||||
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', 'euf', 'arith_tactics'], 'cmd_context/extra_cmds')
|
||||
add_lib('api', ['portfolio', 'realclosure', 'opt', 'extra_cmds'],
|
||||
includes2install=['z3.h', 'z3_v1.h', 'z3_macros.h'] + API_files)
|
||||
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',
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
variables:
|
||||
Major: '4'
|
||||
Minor: '11'
|
||||
Patch: '3'
|
||||
Minor: '12'
|
||||
Patch: '2'
|
||||
AssemblyVersion: $(Major).$(Minor).$(Patch).$(Build.BuildId)
|
||||
NightlyVersion: $(AssemblyVersion)-$(Build.DefinitionName)
|
||||
|
||||
|
@ -11,7 +11,7 @@ stages:
|
|||
- job: Mac
|
||||
displayName: "Mac Build"
|
||||
pool:
|
||||
vmImage: "macOS-latest"
|
||||
vmImage: "macOS-11"
|
||||
steps:
|
||||
- script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk
|
||||
- script: git clone https://github.com/z3prover/z3test z3test
|
||||
|
@ -25,7 +25,7 @@ stages:
|
|||
- job: MacArm64
|
||||
displayName: "Mac ARM64 Build"
|
||||
pool:
|
||||
vmImage: "macOS-latest"
|
||||
vmImage: "macOS-11"
|
||||
steps:
|
||||
- script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk --arch=arm64 --os=osx-11.0
|
||||
- script: git clone https://github.com/z3prover/z3test z3test
|
||||
|
@ -91,7 +91,7 @@ stages:
|
|||
displayName: "ManyLinux build"
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
container: "quay.io/pypa/manylinux2010_x86_64:latest"
|
||||
container: "quay.io/pypa/manylinux2014_x86_64:latest"
|
||||
steps:
|
||||
- script: $(python) scripts/mk_unix_dist.py --nodotnet --nojava
|
||||
- script: git clone https://github.com/z3prover/z3test z3test
|
||||
|
@ -261,7 +261,7 @@ stages:
|
|||
minorVersion: $(Minor)
|
||||
patchVersion: $(Patch)
|
||||
arguments: 'pack $(Agent.TempDirectory)\package\out\Microsoft.Z3.sym.nuspec -Version $(NightlyVersion) -OutputDirectory $(Build.ArtifactStagingDirectory) -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath $(Agent.TempDirectory)\package\out'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
continueOnError: true
|
||||
displayName: 'Sign Package'
|
||||
inputs:
|
||||
|
@ -289,7 +289,7 @@ stages:
|
|||
SessionTimeout: '60'
|
||||
MaxConcurrency: '50'
|
||||
MaxRetryAttempts: '5'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
continueOnError: true
|
||||
displayName: 'Sign Symbol Package'
|
||||
inputs:
|
||||
|
@ -366,7 +366,7 @@ stages:
|
|||
minorVersion: $(Minor)
|
||||
patchVersion: $(Patch)
|
||||
arguments: 'pack $(Agent.TempDirectory)\package\out\Microsoft.Z3.x86.sym.nuspec -Version $(NightlyVersion) -OutputDirectory $(Build.ArtifactStagingDirectory) -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath $(Agent.TempDirectory)\package\out'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
continueOnError: true
|
||||
displayName: 'Sign Package'
|
||||
inputs:
|
||||
|
@ -394,7 +394,7 @@ stages:
|
|||
SessionTimeout: '60'
|
||||
MaxConcurrency: '50'
|
||||
MaxRetryAttempts: '5'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
continueOnError: true
|
||||
displayName: 'Sign Symbol Package'
|
||||
inputs:
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
trigger: none
|
||||
|
||||
variables:
|
||||
ReleaseVersion: '4.11.3'
|
||||
ReleaseVersion: '4.12.2'
|
||||
|
||||
stages:
|
||||
|
||||
|
@ -17,7 +17,7 @@ stages:
|
|||
- job: MacBuild
|
||||
displayName: "macOS Build"
|
||||
pool:
|
||||
vmImage: "macOS-latest"
|
||||
vmImage: "macOS-11"
|
||||
steps:
|
||||
- task: PythonScript@0
|
||||
displayName: Build
|
||||
|
@ -46,7 +46,7 @@ stages:
|
|||
- job: MacBuildArm64
|
||||
displayName: "macOS ARM64 Build"
|
||||
pool:
|
||||
vmImage: "macOS-latest"
|
||||
vmImage: "macOS-11"
|
||||
steps:
|
||||
- script: python scripts/mk_unix_dist.py --dotnet-key=$(Build.SourcesDirectory)/resources/z3.snk --arch=arm64 --os=osx-11.0
|
||||
- script: git clone https://github.com/z3prover/z3test z3test
|
||||
|
@ -124,11 +124,10 @@ stages:
|
|||
displayName: "ManyLinux build"
|
||||
variables:
|
||||
name: ManyLinux
|
||||
image: "quay.io/pypa/manylinux2010_x86_64:latest"
|
||||
python: "/opt/python/cp37-cp37m/bin/python"
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
container: "quay.io/pypa/manylinux2010_x86_64:latest"
|
||||
container: "quay.io/pypa/manylinux2014_x86_64:latest"
|
||||
steps:
|
||||
- task: PythonScript@0
|
||||
displayName: Build
|
||||
|
@ -220,7 +219,7 @@ stages:
|
|||
inputs:
|
||||
command: custom
|
||||
arguments: 'pack $(Agent.TempDirectory)\package\out\Microsoft.Z3.sym.nuspec -OutputDirectory $(Build.ArtifactStagingDirectory) -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath $(Agent.TempDirectory)\package\out'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: 'Sign Package'
|
||||
inputs:
|
||||
ConnectedServiceName: 'z3-esrp-signing-2'
|
||||
|
@ -234,20 +233,20 @@ stages:
|
|||
"OperationCode" : "NuGetSign",
|
||||
"Parameters" : {},
|
||||
"ToolName" : "sign",
|
||||
"ToolVersion" : "1.0"
|
||||
"ToolVersion" : "2.0"
|
||||
},
|
||||
{
|
||||
"KeyCode" : "CP-401405",
|
||||
"OperationCode" : "NuGetVerify",
|
||||
"Parameters" : {},
|
||||
"ToolName" : "sign",
|
||||
"ToolVersion" : "1.0"
|
||||
"ToolVersion" : "2.0"
|
||||
}
|
||||
]
|
||||
SessionTimeout: '60'
|
||||
MaxConcurrency: '50'
|
||||
MaxRetryAttempts: '5'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: 'Sign Symbol Package'
|
||||
inputs:
|
||||
ConnectedServiceName: 'z3-esrp-signing-2'
|
||||
|
@ -261,14 +260,14 @@ stages:
|
|||
"OperationCode" : "NuGetSign",
|
||||
"Parameters" : {},
|
||||
"ToolName" : "sign",
|
||||
"ToolVersion" : "1.0"
|
||||
"ToolVersion" : "2.0"
|
||||
},
|
||||
{
|
||||
"KeyCode" : "CP-401405",
|
||||
"OperationCode" : "NuGetVerify",
|
||||
"Parameters" : {},
|
||||
"ToolName" : "sign",
|
||||
"ToolVersion" : "1.0"
|
||||
"ToolVersion" : "2.0"
|
||||
}
|
||||
]
|
||||
SessionTimeout: '60'
|
||||
|
@ -319,7 +318,7 @@ stages:
|
|||
inputs:
|
||||
command: custom
|
||||
arguments: 'pack $(Agent.TempDirectory)\package\out\Microsoft.Z3.x86.sym.nuspec -OutputDirectory $(Build.ArtifactStagingDirectory) -Verbosity detailed -Symbols -SymbolPackageFormat snupkg -BasePath $(Agent.TempDirectory)\package\out'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: 'Sign Package'
|
||||
inputs:
|
||||
ConnectedServiceName: 'z3-esrp-signing-2'
|
||||
|
@ -346,7 +345,7 @@ stages:
|
|||
SessionTimeout: '60'
|
||||
MaxConcurrency: '50'
|
||||
MaxRetryAttempts: '5'
|
||||
- task: EsrpCodeSigning@1
|
||||
- task: EsrpCodeSigning@2
|
||||
displayName: 'Sign Symbol Package'
|
||||
inputs:
|
||||
ConnectedServiceName: 'z3-esrp-signing-2'
|
||||
|
|
|
@ -312,7 +312,7 @@ NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ]
|
|||
Unwrapped = [ 'Z3_del_context', 'Z3_get_error_code' ]
|
||||
Unchecked = frozenset([ 'Z3_dec_ref', 'Z3_params_dec_ref', 'Z3_model_dec_ref',
|
||||
'Z3_func_interp_dec_ref', 'Z3_func_entry_dec_ref',
|
||||
'Z3_goal_dec_ref', 'Z3_tactic_dec_ref', 'Z3_probe_dec_ref',
|
||||
'Z3_goal_dec_ref', 'Z3_tactic_dec_ref', 'Z3_simplifier_dec_ref', 'Z3_probe_dec_ref',
|
||||
'Z3_fixedpoint_dec_ref', 'Z3_param_descrs_dec_ref',
|
||||
'Z3_ast_vector_dec_ref', 'Z3_ast_map_dec_ref',
|
||||
'Z3_apply_result_dec_ref', 'Z3_solver_dec_ref',
|
||||
|
@ -339,6 +339,10 @@ def Z3_set_error_handler(ctx, hndlr, _elems=Elementaries(_lib.Z3_set_error_handl
|
|||
_elems.Check(ctx)
|
||||
return ceh
|
||||
|
||||
def Z3_solver_register_on_clause(ctx, s, user_ctx, on_clause_eh, _elems = Elementaries(_lib.Z3_solver_register_on_clause)):
|
||||
_elems.f(ctx, s, user_ctx, on_clause_eh)
|
||||
_elems.Check(ctx)
|
||||
|
||||
def Z3_solver_propagate_init(ctx, s, user_ctx, push_eh, pop_eh, fresh_eh, _elems = Elementaries(_lib.Z3_solver_propagate_init)):
|
||||
_elems.f(ctx, s, user_ctx, push_eh, pop_eh, fresh_eh)
|
||||
_elems.Check(ctx)
|
||||
|
@ -1172,6 +1176,8 @@ def ml_plus_type(ts):
|
|||
return 'Z3_goal_plus'
|
||||
elif ts == 'Z3_tactic':
|
||||
return 'Z3_tactic_plus'
|
||||
elif ts == 'Z3_simplifier':
|
||||
return 'Z3_simplifier_plus'
|
||||
elif ts == 'Z3_probe':
|
||||
return 'Z3_probe_plus'
|
||||
elif ts == 'Z3_apply_result':
|
||||
|
@ -1216,6 +1222,8 @@ def ml_minus_type(ts):
|
|||
return 'Z3_goal'
|
||||
elif ts == 'Z3_tactic_plus':
|
||||
return 'Z3_tactic'
|
||||
elif ts == 'Z3_simplifier_plus':
|
||||
return 'Z3_simplifier'
|
||||
elif ts == 'Z3_probe_plus':
|
||||
return 'Z3_probe'
|
||||
elif ts == 'Z3_apply_result_plus':
|
||||
|
@ -1315,7 +1323,8 @@ z3_ml_callbacks = frozenset([
|
|||
'Z3_solver_propagate_eq',
|
||||
'Z3_solver_propagate_diseq',
|
||||
'Z3_solver_propagate_created',
|
||||
'Z3_solver_propagate_decide'
|
||||
'Z3_solver_propagate_decide',
|
||||
'Z3_solver_register_on_clause'
|
||||
])
|
||||
|
||||
def mk_ml(ml_src_dir, ml_output_dir):
|
||||
|
@ -1844,6 +1853,7 @@ _error_handler_type = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_uint)
|
|||
_lib.Z3_set_error_handler.restype = None
|
||||
_lib.Z3_set_error_handler.argtypes = [ContextObj, _error_handler_type]
|
||||
|
||||
Z3_on_clause_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
|
||||
Z3_push_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p)
|
||||
Z3_pop_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_uint)
|
||||
Z3_fresh_eh = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
|
||||
|
@ -1855,6 +1865,7 @@ Z3_eq_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_
|
|||
Z3_created_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
|
||||
Z3_decide_eh = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p)
|
||||
|
||||
_lib.Z3_solver_register_on_clause.restype = None
|
||||
_lib.Z3_solver_propagate_init.restype = None
|
||||
_lib.Z3_solver_propagate_final.restype = None
|
||||
_lib.Z3_solver_propagate_fixed.restype = None
|
||||
|
|
|
@ -47,12 +47,17 @@ add_subdirectory(math/subpaving)
|
|||
add_subdirectory(ast)
|
||||
add_subdirectory(params)
|
||||
add_subdirectory(ast/rewriter)
|
||||
add_subdirectory(ast/rewriter/bit_blaster)
|
||||
add_subdirectory(ast/normal_forms)
|
||||
add_subdirectory(ast/macros)
|
||||
add_subdirectory(model)
|
||||
add_subdirectory(tactic)
|
||||
add_subdirectory(ast/substitution)
|
||||
add_subdirectory(ast/euf)
|
||||
add_subdirectory(ast/converters)
|
||||
add_subdirectory(ast/substitution)
|
||||
add_subdirectory(ast/simplifiers)
|
||||
add_subdirectory(tactic)
|
||||
add_subdirectory(qe/mbp)
|
||||
add_subdirectory(qe/lite)
|
||||
add_subdirectory(smt/params)
|
||||
add_subdirectory(parsers/util)
|
||||
add_subdirectory(math/grobner)
|
||||
|
@ -68,11 +73,8 @@ add_subdirectory(math/polysat)
|
|||
add_subdirectory(cmd_context)
|
||||
add_subdirectory(cmd_context/extra_cmds)
|
||||
add_subdirectory(parsers/smt2)
|
||||
add_subdirectory(qe/mbp)
|
||||
add_subdirectory(qe/lite)
|
||||
add_subdirectory(solver/assertions)
|
||||
add_subdirectory(ast/pattern)
|
||||
add_subdirectory(ast/rewriter/bit_blaster)
|
||||
add_subdirectory(math/lp)
|
||||
add_subdirectory(sat/smt)
|
||||
add_subdirectory(sat/tactic)
|
||||
|
@ -138,7 +140,7 @@ if (MSVC AND Z3_BUILD_LIBZ3_MSVC_STATIC)
|
|||
set(${CompilerFlag} "${${CompilerFlag}}" CACHE STRING "msvc compiler flags" FORCE)
|
||||
message("MSVC flags: ${CompilerFlag}:${${CompilerFlag}}")
|
||||
endforeach()
|
||||
endif(MSVC)
|
||||
endif()
|
||||
add_library(libz3 ${lib_type} ${object_files})
|
||||
target_include_directories(libz3 INTERFACE
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/api>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "tactic/model_converter.h"
|
||||
#include "ast/converters/model_converter.h"
|
||||
#include "ackermannization/ackr_info.h"
|
||||
|
||||
model_converter * mk_ackermannize_bv_model_converter(ast_manager & m, const ackr_info_ref& info);
|
||||
|
|
|
@ -11,7 +11,37 @@ Author:
|
|||
|
||||
Mikolas Janota
|
||||
|
||||
Revision History:
|
||||
Tactic Documentation:
|
||||
|
||||
## Tactic ackernannize_bv
|
||||
|
||||
### Short Description
|
||||
|
||||
A tactic for performing Ackermann reduction for bit-vector formulas
|
||||
|
||||
### Long Description
|
||||
|
||||
The Ackermann reduction replaces uninterpreted functions $f(t_1), f(t_2)$
|
||||
by fresh variables $f_1, f_2$ and addes axioms $t_1 \simeq t_2 \implies f_1 \simeq f_2$.
|
||||
The reduction has the effect of eliminating uninterpreted functions. When the reduction
|
||||
produces a pure bit-vector benchmark, it allows Z3 to use a specialized SAT solver.
|
||||
|
||||
### Example
|
||||
|
||||
```z3
|
||||
(declare-const x (_ BitVec 32))
|
||||
(declare-const y (_ BitVec 32))
|
||||
(declare-fun f ((_ BitVec 32)) (_ BitVec 8))
|
||||
|
||||
(assert (not (= (f x) (f y))))
|
||||
(apply ackermannize_bv)
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
* does not support proofs, does not support unsatisfiable cores
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
#pragma once
|
||||
|
|
|
@ -15,7 +15,7 @@ Revision History:
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "tactic/model_converter.h"
|
||||
#include "ast/converters/model_converter.h"
|
||||
#include "ackermannization/ackr_info.h"
|
||||
|
||||
model_converter * mk_ackr_model_converter(ast_manager & m, const ackr_info_ref & info, model_ref & abstr_model);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
--*/
|
||||
#pragma once
|
||||
|
||||
#include "tactic/model_converter.h"
|
||||
#include "ast/converters/model_converter.h"
|
||||
#include "ackermannization/ackr_info.h"
|
||||
|
||||
model_converter * mk_lackr_model_converter_lazy(ast_manager & m, const ackr_info_ref& info, model_ref& abstr_model);
|
||||
|
|
|
@ -68,4 +68,5 @@ z3_add_component(api
|
|||
opt
|
||||
portfolio
|
||||
realclosure
|
||||
extra_cmds
|
||||
)
|
||||
|
|
|
@ -48,6 +48,20 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_real_int64(Z3_context c, int64_t num, int64_t den) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real_int64(c, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
if (den == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
RETURN_Z3(nullptr);
|
||||
}
|
||||
sort* s = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
|
||||
ast* a = mk_c(c)->mk_numeral_core(rational(num, rational::i64())/rational(den, rational::i64()), s);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_real(Z3_context c, int num, int den) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real(c, num, den);
|
||||
|
|
|
@ -137,7 +137,7 @@ extern "C" {
|
|||
ast_manager& m = mk_c(c)->m();
|
||||
recfun::decl::plugin& p = mk_c(c)->recfun().get_plugin();
|
||||
if (!p.has_def(d)) {
|
||||
std::string msg = "function " + mk_pp(d, m) + " needs to be defined using rec_func_decl";
|
||||
std::string msg = "function " + mk_pp(d, m) + " needs to be declared using rec_func_decl";
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, msg.c_str());
|
||||
return;
|
||||
}
|
||||
|
@ -158,6 +158,12 @@ extern "C" {
|
|||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
return;
|
||||
}
|
||||
if (!pd.get_def()->get_cases().empty()) {
|
||||
std::string msg = "function " + mk_pp(d, m) + " has already been given a definition";
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, msg.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (abs_body->get_sort() != d->get_range()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
return;
|
||||
|
@ -654,11 +660,14 @@ extern "C" {
|
|||
LOG_Z3_get_domain(c, d, i);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(d, nullptr);
|
||||
if (i >= to_func_decl(d)->get_arity()) {
|
||||
func_decl* _d = to_func_decl(d);
|
||||
if (_d->is_associative())
|
||||
i = 0;
|
||||
if (i >= _d->get_arity()) {
|
||||
SET_ERROR_CODE(Z3_IOB, nullptr);
|
||||
RETURN_Z3(nullptr);
|
||||
}
|
||||
Z3_sort r = of_sort(to_func_decl(d)->get_domain(i));
|
||||
Z3_sort r = of_sort(_d->get_domain(i));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ namespace api {
|
|||
}
|
||||
|
||||
void context::del_object(api::object* o) {
|
||||
if (!o)
|
||||
return;
|
||||
#ifndef SINGLE_THREAD
|
||||
if (m_concurrent_dec_ref) {
|
||||
lock_guard lock(m_mux);
|
||||
|
@ -149,6 +151,8 @@ namespace api {
|
|||
|
||||
|
||||
context::~context() {
|
||||
if (m_parser)
|
||||
smt2::free_parser(m_parser);
|
||||
m_last_obj = nullptr;
|
||||
flush_objects();
|
||||
for (auto& kv : m_allocated_objects) {
|
||||
|
|
|
@ -50,6 +50,11 @@ namespace realclosure {
|
|||
class manager;
|
||||
};
|
||||
|
||||
namespace smt2 {
|
||||
class parser;
|
||||
void free_parser(parser*);
|
||||
};
|
||||
|
||||
namespace api {
|
||||
|
||||
class seq_expr_solver : public expr_solver {
|
||||
|
@ -233,6 +238,19 @@ namespace api {
|
|||
|
||||
void check_sorts(ast * n);
|
||||
|
||||
|
||||
// ------------------------------------------------
|
||||
//
|
||||
// State reused by calls to Z3_eval_smtlib2_string
|
||||
//
|
||||
// ------------------------------------------------
|
||||
//
|
||||
// The m_parser field is reused by all calls of Z3_eval_smtlib2_string using this context.
|
||||
// It is an optimization to save the cost of recreating these objects on each invocation.
|
||||
//
|
||||
// See https://github.com/Z3Prover/z3/pull/6422 for the motivation
|
||||
smt2::parser* m_parser = nullptr;
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Polynomial manager & caches
|
||||
|
|
|
@ -395,8 +395,7 @@ extern "C" {
|
|||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_from_string(c, d, s);
|
||||
std::string str(s);
|
||||
std::istringstream is(str);
|
||||
std::istringstream is(s);
|
||||
RETURN_Z3(Z3_fixedpoint_from_stream(c, d, is));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
|
|
@ -102,6 +102,13 @@ extern "C" {
|
|||
sort* e;
|
||||
|
||||
ptr_vector<constructor_decl> constrs;
|
||||
symbol sname = to_symbol(name);
|
||||
|
||||
if (mk_c(c)->get_dt_plugin()->is_declared(sname)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, "enumeration sort name is already declared");
|
||||
RETURN_Z3(nullptr);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
symbol e_name(to_symbol(enum_names[i]));
|
||||
std::string recognizer_s("is_");
|
||||
|
@ -112,8 +119,9 @@ extern "C" {
|
|||
}
|
||||
|
||||
|
||||
|
||||
{
|
||||
datatype_decl * dt = mk_datatype_decl(dt_util, to_symbol(name), 0, nullptr, n, constrs.data());
|
||||
datatype_decl * dt = mk_datatype_decl(dt_util, sname, 0, nullptr, n, constrs.data());
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, 0, nullptr, sorts);
|
||||
del_datatype_decl(dt);
|
||||
|
||||
|
|
|
@ -383,8 +383,7 @@ extern "C" {
|
|||
Z3_string s) {
|
||||
Z3_TRY;
|
||||
//LOG_Z3_optimize_from_string(c, d, s);
|
||||
std::string str(s);
|
||||
std::istringstream is(str);
|
||||
std::istringstream is(s);
|
||||
Z3_optimize_from_stream(c, d, is, nullptr);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ extern "C" {
|
|||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_params(p)->m_params.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
return mk_c(c)->mk_external_string(std::move(buffer).str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ extern "C" {
|
|||
buffer << to_param_descrs_ptr(p)->get_param_name(i);
|
||||
}
|
||||
buffer << ")";
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
return mk_c(c)->mk_external_string(std::move(buffer).str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ Revision History:
|
|||
#include "solver/solver_na2as.h"
|
||||
#include "muz/fp/dl_cmds.h"
|
||||
#include "opt/opt_cmds.h"
|
||||
#include "cmd_context/extra_cmds/proof_cmds.h"
|
||||
|
||||
|
||||
|
||||
|
@ -42,6 +43,7 @@ extern "C" {
|
|||
ast_manager& m = c.m();
|
||||
ctx = alloc(cmd_context, false, &(m));
|
||||
install_dl_cmds(*ctx.get());
|
||||
install_proof_cmds(*ctx.get());
|
||||
install_opt_cmds(*ctx.get());
|
||||
install_smt2_extra_cmds(*ctx.get());
|
||||
ctx->register_plist();
|
||||
|
@ -155,8 +157,7 @@ extern "C" {
|
|||
Z3_ast_vector Z3_API Z3_parser_context_from_string(Z3_context c, Z3_parser_context pc, Z3_string str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parser_context_from_string(c, pc, str);
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
std::istringstream is(str);
|
||||
auto& ctx = to_parser_context(pc)->ctx;
|
||||
Z3_ast_vector r = Z3_parser_context_parse_stream(c, ctx, false, is);
|
||||
RETURN_Z3(r);
|
||||
|
@ -175,6 +176,7 @@ extern "C" {
|
|||
ast_manager& m = mk_c(c)->m();
|
||||
scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(m));
|
||||
install_dl_cmds(*ctx.get());
|
||||
install_proof_cmds(*ctx.get());
|
||||
install_opt_cmds(*ctx.get());
|
||||
install_smt2_extra_cmds(*ctx.get());
|
||||
ctx->register_plist();
|
||||
|
@ -199,8 +201,7 @@ extern "C" {
|
|||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_smtlib2_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
std::istringstream is(str);
|
||||
Z3_ast_vector r = parse_smtlib2_stream(false, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
|
@ -233,19 +234,20 @@ extern "C" {
|
|||
auto* ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
|
||||
mk_c(c)->cmd() = ctx;
|
||||
install_dl_cmds(*ctx);
|
||||
install_proof_cmds(*ctx);
|
||||
install_opt_cmds(*ctx);
|
||||
install_smt2_extra_cmds(*ctx);
|
||||
ctx->register_plist();
|
||||
ctx->set_solver_factory(mk_smt_strategic_solver_factory());
|
||||
}
|
||||
scoped_ptr<cmd_context>& ctx = mk_c(c)->cmd();
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
std::istringstream is(str);
|
||||
ctx->set_regular_stream(ous);
|
||||
ctx->set_diagnostic_stream(ous);
|
||||
cmd_context::scoped_redirect _redirect(*ctx);
|
||||
try {
|
||||
if (!parse_smt2_commands(*ctx.get(), is)) {
|
||||
// See api::context::m_parser for a motivation about the reuse of the parser
|
||||
if (!parse_smt2_commands_with_parser(mk_c(c)->m_parser, *ctx.get(), is)) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str());
|
||||
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ Notes:
|
|||
#include "api/api_model.h"
|
||||
#include "api/api_ast_map.h"
|
||||
#include "api/api_ast_vector.h"
|
||||
#include "qe/lite/qe_lite.h"
|
||||
#include "qe/lite/qe_lite_tactic.h"
|
||||
#include "muz/spacer/spacer_util.h"
|
||||
|
||||
extern "C"
|
||||
|
|
|
@ -212,6 +212,8 @@ extern "C" {
|
|||
buffer.push_back('\\');
|
||||
buffer.push_back('u');
|
||||
buffer.push_back('{');
|
||||
if (ch == 0)
|
||||
buff.push_back('0');
|
||||
while (ch > 0) {
|
||||
unsigned d = ch & 0xF;
|
||||
if (d < 10)
|
||||
|
|
|
@ -43,6 +43,8 @@ Revision History:
|
|||
#include "sat/sat_solver.h"
|
||||
#include "sat/tactic/goal2sat.h"
|
||||
#include "sat/tactic/sat2goal.h"
|
||||
#include "cmd_context/extra_cmds/proof_cmds.h"
|
||||
#include "solver/simplifier_solver.h"
|
||||
|
||||
|
||||
extern "C" {
|
||||
|
@ -231,12 +233,26 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_solver Z3_API Z3_solver_add_simplifier(Z3_context c, Z3_solver solver, Z3_simplifier simplifier) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_add_simplifier(c, solver, simplifier);
|
||||
init_solver(c, solver);
|
||||
auto simp = to_simplifier_ref(simplifier);
|
||||
auto* slv = mk_simplifier_solver(to_solver_ref(solver), simp);
|
||||
Z3_solver_ref* sr = alloc(Z3_solver_ref, *mk_c(c), slv);
|
||||
mk_c(c)->save_object(sr);
|
||||
// ?? init_solver_log(c, sr)
|
||||
RETURN_Z3(of_solver(sr));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
|
||||
Z3_solver Z3_API Z3_solver_translate(Z3_context c, Z3_solver s, Z3_context target) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_translate(c, s, target);
|
||||
RESET_ERROR_CODE();
|
||||
params_ref const& p = to_solver(s)->m_params;
|
||||
Z3_solver_ref * sr = alloc(Z3_solver_ref, *mk_c(target), nullptr);
|
||||
Z3_solver_ref * sr = alloc(Z3_solver_ref, *mk_c(target), (solver_factory *)nullptr);
|
||||
init_solver(c, s);
|
||||
sr->m_solver = to_solver(s)->m_solver->translate(mk_c(target)->m(), p);
|
||||
mk_c(target)->save_object(sr);
|
||||
|
@ -257,8 +273,10 @@ extern "C" {
|
|||
|
||||
void solver_from_stream(Z3_context c, Z3_solver s, std::istream& is) {
|
||||
auto& solver = *to_solver(s);
|
||||
if (!solver.m_cmd_context)
|
||||
if (!solver.m_cmd_context) {
|
||||
solver.m_cmd_context = alloc(cmd_context, false, &(mk_c(c)->m()));
|
||||
install_proof_cmds(*solver.m_cmd_context);
|
||||
}
|
||||
auto& ctx = solver.m_cmd_context;
|
||||
ctx->set_ignore_check(true);
|
||||
std::stringstream errstrm;
|
||||
|
@ -270,6 +288,7 @@ extern "C" {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
bool initialized = to_solver(s)->m_solver.get() != nullptr;
|
||||
if (!initialized)
|
||||
init_solver(c, s);
|
||||
|
@ -277,6 +296,10 @@ extern "C" {
|
|||
to_solver(s)->assert_expr(e);
|
||||
ctx->reset_tracked_assertions();
|
||||
to_solver_ref(s)->set_model_converter(ctx->get_model_converter());
|
||||
auto* ctx_s = ctx->get_solver();
|
||||
if (ctx_s && ctx_s->get_proof())
|
||||
to_solver_ref(s)->set_proof(ctx_s->get_proof());
|
||||
|
||||
}
|
||||
|
||||
static void solver_from_dimacs_stream(Z3_context c, Z3_solver s, std::istream& is) {
|
||||
|
@ -310,8 +333,7 @@ extern "C" {
|
|||
void Z3_API Z3_solver_from_string(Z3_context c, Z3_solver s, Z3_string c_str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_from_string(c, s, c_str);
|
||||
std::string str(c_str);
|
||||
std::istringstream is(str);
|
||||
std::istringstream is(c_str);
|
||||
if (is_dimacs_string(c_str)) {
|
||||
solver_from_dimacs_stream(c, s, is);
|
||||
}
|
||||
|
@ -399,7 +421,11 @@ extern "C" {
|
|||
params.validate(r);
|
||||
to_solver_ref(s)->updt_params(params);
|
||||
}
|
||||
to_solver(s)->m_params.append(params);
|
||||
auto& solver = *to_solver(s);
|
||||
solver.m_params.append(params);
|
||||
|
||||
if (solver.m_cmd_context && solver.m_cmd_context->get_proof_cmds())
|
||||
solver.m_cmd_context->get_proof_cmds()->updt_params(solver.m_params);
|
||||
|
||||
init_solver_log(c, s);
|
||||
|
||||
|
@ -684,7 +710,29 @@ extern "C" {
|
|||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
expr_ref_vector core(mk_c(c)->m());
|
||||
to_solver_ref(s)->get_unsat_core(core);
|
||||
solver_params sp(to_solver(s)->m_params);
|
||||
unsigned timeout = mk_c(c)->get_timeout();
|
||||
timeout = to_solver(s)->m_params.get_uint("timeout", timeout);
|
||||
timeout = sp.timeout() != UINT_MAX ? sp.timeout() : timeout;
|
||||
unsigned rlimit = to_solver(s)->m_params.get_uint("rlimit", mk_c(c)->get_rlimit());
|
||||
bool use_ctrl_c = to_solver(s)->m_params.get_bool("ctrl_c", true);
|
||||
cancel_eh<reslimit> eh(mk_c(c)->m().limit());
|
||||
to_solver(s)->set_eh(&eh);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
scoped_rlimit _rlimit(mk_c(c)->m().limit(), rlimit);
|
||||
try {
|
||||
to_solver_ref(s)->get_unsat_core(core);
|
||||
}
|
||||
catch (...) {
|
||||
to_solver_ref(s)->set_reason_unknown(eh);
|
||||
to_solver(s)->set_eh(nullptr);
|
||||
if (core.empty())
|
||||
throw;
|
||||
}
|
||||
}
|
||||
to_solver(s)->set_eh(nullptr);
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (expr* e : core) {
|
||||
|
@ -870,6 +918,26 @@ extern "C" {
|
|||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_solver_congruence_root(Z3_context c, Z3_solver s, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_congruence_root(c, s, a);
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
expr* r = to_solver_ref(s)->congruence_root(to_expr(a));
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_solver_congruence_next(Z3_context c, Z3_solver s, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_congruence_next(c, s, a);
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
expr* sib = to_solver_ref(s)->congruence_next(to_expr(a));
|
||||
RETURN_Z3(of_expr(sib));
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
class api_context_obj : public user_propagator::context_obj {
|
||||
api::context* c;
|
||||
public:
|
||||
|
@ -877,6 +945,45 @@ extern "C" {
|
|||
~api_context_obj() override { dealloc(c); }
|
||||
};
|
||||
|
||||
struct scoped_ast_vector {
|
||||
Z3_ast_vector_ref* v;
|
||||
scoped_ast_vector(Z3_ast_vector_ref* v): v(v) { v->inc_ref(); }
|
||||
~scoped_ast_vector() { v->dec_ref(); }
|
||||
};
|
||||
|
||||
void Z3_API Z3_solver_register_on_clause(
|
||||
Z3_context c,
|
||||
Z3_solver s,
|
||||
void* user_context,
|
||||
Z3_on_clause_eh on_clause_eh) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
init_solver(c, s);
|
||||
user_propagator::on_clause_eh_t _on_clause = [=](void* user_ctx, expr* proof, unsigned n, expr* const* _literals) {
|
||||
Z3_ast_vector_ref * literals = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||
mk_c(c)->save_object(literals);
|
||||
expr_ref pr(proof, mk_c(c)->m());
|
||||
scoped_ast_vector _sc(literals);
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
literals->m_ast_vector.push_back(_literals[i]);
|
||||
on_clause_eh(user_ctx, of_expr(pr.get()), of_ast_vector(literals));
|
||||
};
|
||||
to_solver_ref(s)->register_on_clause(user_context, _on_clause);
|
||||
auto& solver = *to_solver(s);
|
||||
|
||||
if (!solver.m_cmd_context) {
|
||||
solver.m_cmd_context = alloc(cmd_context, false, &(mk_c(c)->m()));
|
||||
install_proof_cmds(*solver.m_cmd_context);
|
||||
}
|
||||
|
||||
if (!solver.m_cmd_context->get_proof_cmds()) {
|
||||
init_proof_cmds(*solver.m_cmd_context);
|
||||
solver.m_cmd_context->get_proof_cmds()->updt_params(solver.m_params);
|
||||
}
|
||||
solver.m_cmd_context->get_proof_cmds()->register_on_clause(user_context, _on_clause);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_propagate_init(
|
||||
Z3_context c,
|
||||
Z3_solver s,
|
||||
|
|
|
@ -52,6 +52,9 @@ struct Z3_solver_ref : public api::object {
|
|||
Z3_solver_ref(api::context& c, solver_factory * f):
|
||||
api::object(c), m_solver_factory(f), m_solver(nullptr), m_logic(symbol::null), m_eh(nullptr) {}
|
||||
|
||||
Z3_solver_ref(api::context& c, solver * s):
|
||||
api::object(c), m_solver_factory(nullptr), m_solver(s), m_logic(symbol::null), m_eh(nullptr) {}
|
||||
|
||||
void assert_expr(expr* e);
|
||||
void assert_expr(expr* e, expr* t);
|
||||
void set_eh(event_handler* eh);
|
||||
|
|
|
@ -20,9 +20,11 @@ Revision History:
|
|||
#include "api/api_context.h"
|
||||
#include "api/api_tactic.h"
|
||||
#include "api/api_model.h"
|
||||
#include "api/api_solver.h"
|
||||
#include "util/scoped_ctrl_c.h"
|
||||
#include "util/cancel_eh.h"
|
||||
#include "util/scoped_timer.h"
|
||||
#include "ast/simplifiers/seq_simplifier.h"
|
||||
|
||||
Z3_apply_result_ref::Z3_apply_result_ref(api::context& c, ast_manager & m): api::object(c) {
|
||||
}
|
||||
|
@ -45,6 +47,14 @@ extern "C" {
|
|||
RETURN_Z3(_result_); \
|
||||
}
|
||||
|
||||
#define RETURN_SIMPLIFIER(_t_) { \
|
||||
Z3_simplifier_ref * _ref_ = alloc(Z3_simplifier_ref, *mk_c(c)); \
|
||||
_ref_->m_simplifier = _t_; \
|
||||
mk_c(c)->save_object(_ref_); \
|
||||
Z3_simplifier _result_ = of_simplifier(_ref_); \
|
||||
RETURN_Z3(_result_); \
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_mk_tactic(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_tactic(c, name);
|
||||
|
@ -517,6 +527,146 @@ extern "C" {
|
|||
RETURN_Z3(result);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Z3_simplifier Z3_API Z3_mk_simplifier(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_simplifier(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
simplifier_cmd * t = mk_c(c)->find_simplifier_cmd(symbol(name));
|
||||
if (t == nullptr) {
|
||||
std::stringstream err;
|
||||
err << "unknown simplifier " << name;
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, err.str());
|
||||
RETURN_Z3(nullptr);
|
||||
}
|
||||
simplifier_factory new_t = t->factory();
|
||||
RETURN_SIMPLIFIER(new_t);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
void Z3_API Z3_simplifier_inc_ref(Z3_context c, Z3_simplifier t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_inc_ref(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
to_simplifier(t)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_simplifier_dec_ref(Z3_context c, Z3_simplifier t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_dec_ref(c, t);
|
||||
if (t)
|
||||
to_simplifier(t)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_num_simplifiers(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_num_simplifiers(c);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->num_simplifiers();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_simplifier_name(Z3_context c, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_simplifier_name(c, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= mk_c(c)->num_simplifiers()) {
|
||||
SET_ERROR_CODE(Z3_IOB, nullptr);
|
||||
return "";
|
||||
}
|
||||
return mk_c(c)->mk_external_string(mk_c(c)->get_simplifier(idx)->get_name().str().c_str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_simplifier Z3_API Z3_simplifier_and_then(Z3_context c, Z3_simplifier t1, Z3_simplifier t2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_and_then(c, t1, t2);
|
||||
RESET_ERROR_CODE();
|
||||
auto fac1 = *to_simplifier_ref(t1);
|
||||
auto fac2 = *to_simplifier_ref(t2);
|
||||
auto new_s = [fac1, fac2](auto& m, auto& p, auto& st) {
|
||||
auto* r = alloc(seq_simplifier, m, p, st);
|
||||
r->add_simplifier(fac1(m, p, st));
|
||||
r->add_simplifier(fac2(m, p, st));
|
||||
return r;
|
||||
};
|
||||
RETURN_SIMPLIFIER(new_s);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_simplifier Z3_API Z3_simplifier_using_params(Z3_context c, Z3_simplifier t, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_using_params(c, t, p);
|
||||
RESET_ERROR_CODE();
|
||||
param_descrs r;
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
default_dependent_expr_state st(m);
|
||||
params_ref p1;
|
||||
auto fac = (*to_simplifier_ref(t));
|
||||
scoped_ptr<dependent_expr_simplifier> simp = fac(m, p1, st);
|
||||
simp->collect_param_descrs(r);
|
||||
auto params = to_param_ref(p);
|
||||
params.validate(r);
|
||||
auto new_s = [params, fac](auto& m, auto& p, auto& st) {
|
||||
params_ref pp;
|
||||
pp.append(params);
|
||||
pp.append(p);
|
||||
return fac(m, pp, st);
|
||||
};
|
||||
RETURN_SIMPLIFIER(new_s);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
|
||||
Z3_string Z3_API Z3_simplifier_get_help(Z3_context c, Z3_simplifier t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_get_help(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
param_descrs descrs;
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
default_dependent_expr_state st(m);
|
||||
params_ref p;
|
||||
scoped_ptr<dependent_expr_simplifier> simp = (*to_simplifier_ref(t))(m, p, st);
|
||||
simp->collect_param_descrs(descrs);
|
||||
descrs.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_param_descrs Z3_API Z3_simplifier_get_param_descrs(Z3_context c, Z3_simplifier t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_get_param_descrs(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref, *mk_c(c));
|
||||
mk_c(c)->save_object(d);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
default_dependent_expr_state st(m);
|
||||
params_ref p;
|
||||
scoped_ptr<dependent_expr_simplifier> simp = (*to_simplifier_ref(t))(m, p, st);
|
||||
simp->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(nullptr);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_simplifier_get_descr(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_simplifier_get_descr(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
simplifier_cmd * t = mk_c(c)->find_simplifier_cmd(symbol(name));
|
||||
if (t == nullptr) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
|
||||
return "";
|
||||
}
|
||||
return t->get_descr();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@ Revision History:
|
|||
|
||||
#include "api/api_goal.h"
|
||||
#include "tactic/tactical.h"
|
||||
#include "ast/simplifiers/dependent_expr_state.h"
|
||||
|
||||
namespace api {
|
||||
class context;
|
||||
|
@ -35,10 +36,19 @@ struct Z3_probe_ref : public api::object {
|
|||
Z3_probe_ref(api::context& c):api::object(c) {}
|
||||
};
|
||||
|
||||
struct Z3_simplifier_ref : public api::object {
|
||||
simplifier_factory m_simplifier;
|
||||
Z3_simplifier_ref(api::context& c):api::object(c) {}
|
||||
};
|
||||
|
||||
inline Z3_tactic_ref * to_tactic(Z3_tactic g) { return reinterpret_cast<Z3_tactic_ref *>(g); }
|
||||
inline Z3_tactic of_tactic(Z3_tactic_ref * g) { return reinterpret_cast<Z3_tactic>(g); }
|
||||
inline tactic * to_tactic_ref(Z3_tactic g) { return g == nullptr ? nullptr : to_tactic(g)->m_tactic.get(); }
|
||||
|
||||
inline Z3_simplifier_ref * to_simplifier(Z3_simplifier g) { return reinterpret_cast<Z3_simplifier_ref *>(g); }
|
||||
inline Z3_simplifier of_simplifier(Z3_simplifier_ref * g) { return reinterpret_cast<Z3_simplifier>(g); }
|
||||
inline simplifier_factory * to_simplifier_ref(Z3_simplifier g) { return g == nullptr ? nullptr : &to_simplifier(g)->m_simplifier; }
|
||||
|
||||
inline Z3_probe_ref * to_probe(Z3_probe g) { return reinterpret_cast<Z3_probe_ref *>(g); }
|
||||
inline Z3_probe of_probe(Z3_probe_ref * g) { return reinterpret_cast<Z3_probe>(g); }
|
||||
inline probe * to_probe_ref(Z3_probe g) { return g == nullptr ? nullptr : to_probe(g)->m_probe.get(); }
|
||||
|
|
|
@ -63,6 +63,7 @@ namespace z3 {
|
|||
class solver;
|
||||
class goal;
|
||||
class tactic;
|
||||
class simplifier;
|
||||
class probe;
|
||||
class model;
|
||||
class func_interp;
|
||||
|
@ -158,7 +159,7 @@ namespace z3 {
|
|||
class context {
|
||||
private:
|
||||
friend class user_propagator_base;
|
||||
bool m_enable_exceptions;
|
||||
bool m_enable_exceptions = true;
|
||||
rounding_mode m_rounding_mode;
|
||||
Z3_context m_ctx = nullptr;
|
||||
void init(config & c) {
|
||||
|
@ -366,8 +367,14 @@ namespace z3 {
|
|||
void recdef(func_decl, expr_vector const& args, expr const& body);
|
||||
func_decl user_propagate_function(symbol const& name, sort_vector const& domain, sort const& range);
|
||||
|
||||
/**
|
||||
\brief create an uninterpreted constant.
|
||||
*/
|
||||
expr constant(symbol const & name, sort const & s);
|
||||
expr constant(char const * name, sort const & s);
|
||||
/**
|
||||
\brief create uninterpreted constants of a given sort.
|
||||
*/
|
||||
expr bool_const(char const * name);
|
||||
expr int_const(char const * name);
|
||||
expr real_const(char const * name);
|
||||
|
@ -378,6 +385,12 @@ namespace z3 {
|
|||
template<size_t precision>
|
||||
expr fpa_const(char const * name);
|
||||
|
||||
/**
|
||||
\brief create a de-Bruijn variable.
|
||||
*/
|
||||
expr variable(unsigned index, sort const& s);
|
||||
|
||||
|
||||
expr fpa_rounding_mode();
|
||||
|
||||
expr bool_val(bool b);
|
||||
|
@ -388,11 +401,11 @@ namespace z3 {
|
|||
expr int_val(uint64_t n);
|
||||
expr int_val(char const * n);
|
||||
|
||||
expr real_val(int n, int d);
|
||||
expr real_val(int n);
|
||||
expr real_val(unsigned n);
|
||||
expr real_val(int64_t n);
|
||||
expr real_val(uint64_t n);
|
||||
expr real_val(int64_t n, int64_t d);
|
||||
expr real_val(char const * n);
|
||||
|
||||
expr bv_val(int n, unsigned sz);
|
||||
|
@ -1566,6 +1579,11 @@ namespace z3 {
|
|||
*/
|
||||
expr substitute(expr_vector const& dst);
|
||||
|
||||
/**
|
||||
\brief Apply function substitution by macro definitions.
|
||||
*/
|
||||
expr substitute(func_decl_vector const& funs, expr_vector const& bodies);
|
||||
|
||||
|
||||
class iterator {
|
||||
expr& e;
|
||||
|
@ -1902,21 +1920,21 @@ namespace z3 {
|
|||
inline expr operator>(expr const & a, int b) { return a > a.ctx().num_val(b, a.get_sort()); }
|
||||
inline expr operator>(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) > b; }
|
||||
|
||||
inline expr operator&(expr const & a, expr const & b) { if (a.is_bool()) return a && b; check_context(a, b); Z3_ast r = Z3_mk_bvand(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr operator&(expr const & a, expr const & b) { if (a.is_bool()) return a && b; check_context(a, b); Z3_ast r = Z3_mk_bvand(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr operator&(expr const & a, int b) { return a & a.ctx().num_val(b, a.get_sort()); }
|
||||
inline expr operator&(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) & b; }
|
||||
|
||||
inline expr operator^(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = a.is_bool() ? Z3_mk_xor(a.ctx(), a, b) : Z3_mk_bvxor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr operator^(expr const & a, expr const & b) { check_context(a, b); Z3_ast r = a.is_bool() ? Z3_mk_xor(a.ctx(), a, b) : Z3_mk_bvxor(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr operator^(expr const & a, int b) { return a ^ a.ctx().num_val(b, a.get_sort()); }
|
||||
inline expr operator^(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) ^ b; }
|
||||
|
||||
inline expr operator|(expr const & a, expr const & b) { if (a.is_bool()) return a || b; check_context(a, b); Z3_ast r = Z3_mk_bvor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr operator|(expr const & a, expr const & b) { if (a.is_bool()) return a || b; check_context(a, b); Z3_ast r = Z3_mk_bvor(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr operator|(expr const & a, int b) { return a | a.ctx().num_val(b, a.get_sort()); }
|
||||
inline expr operator|(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) | b; }
|
||||
|
||||
inline expr nand(expr const& a, expr const& b) { if (a.is_bool()) return !(a && b); check_context(a, b); Z3_ast r = Z3_mk_bvnand(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr nor(expr const& a, expr const& b) { if (a.is_bool()) return !(a || b); check_context(a, b); Z3_ast r = Z3_mk_bvnor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr xnor(expr const& a, expr const& b) { if (a.is_bool()) return !(a ^ b); check_context(a, b); Z3_ast r = Z3_mk_bvxnor(a.ctx(), a, b); return expr(a.ctx(), r); }
|
||||
inline expr nand(expr const& a, expr const& b) { if (a.is_bool()) return !(a && b); check_context(a, b); Z3_ast r = Z3_mk_bvnand(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr nor(expr const& a, expr const& b) { if (a.is_bool()) return !(a || b); check_context(a, b); Z3_ast r = Z3_mk_bvnor(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr xnor(expr const& a, expr const& b) { if (a.is_bool()) return !(a ^ b); check_context(a, b); Z3_ast r = Z3_mk_bvxnor(a.ctx(), a, b); a.check_error(); return expr(a.ctx(), r); }
|
||||
inline expr min(expr const& a, expr const& b) {
|
||||
check_context(a, b);
|
||||
Z3_ast r;
|
||||
|
@ -1930,6 +1948,7 @@ namespace z3 {
|
|||
assert(a.is_fpa());
|
||||
r = Z3_mk_fpa_min(a.ctx(), a, b);
|
||||
}
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
inline expr max(expr const& a, expr const& b) {
|
||||
|
@ -1945,6 +1964,7 @@ namespace z3 {
|
|||
assert(a.is_fpa());
|
||||
r = Z3_mk_fpa_max(a.ctx(), a, b);
|
||||
}
|
||||
a.check_error();
|
||||
return expr(a.ctx(), r);
|
||||
}
|
||||
inline expr bvredor(expr const & a) {
|
||||
|
@ -2670,12 +2690,13 @@ namespace z3 {
|
|||
public:
|
||||
struct simple {};
|
||||
struct translate {};
|
||||
solver(context & c):object(c) { init(Z3_mk_solver(c)); }
|
||||
solver(context & c, simple):object(c) { init(Z3_mk_simple_solver(c)); }
|
||||
solver(context & c):object(c) { init(Z3_mk_solver(c)); check_error(); }
|
||||
solver(context & c, simple):object(c) { init(Z3_mk_simple_solver(c)); check_error(); }
|
||||
solver(context & c, Z3_solver s):object(c) { init(s); }
|
||||
solver(context & c, char const * logic):object(c) { init(Z3_mk_solver_for_logic(c, c.str_symbol(logic))); }
|
||||
solver(context & c, char const * logic):object(c) { init(Z3_mk_solver_for_logic(c, c.str_symbol(logic))); check_error(); }
|
||||
solver(context & c, solver const& src, translate): object(c) { Z3_solver s = Z3_solver_translate(src.ctx(), src, c); check_error(); init(s); }
|
||||
solver(solver const & s):object(s) { init(s.m_solver); }
|
||||
solver(solver const& s, simplifier const& simp);
|
||||
~solver() { Z3_solver_dec_ref(ctx(), m_solver); }
|
||||
operator Z3_solver() const { return m_solver; }
|
||||
solver & operator=(solver const & s) {
|
||||
|
@ -3046,6 +3067,47 @@ namespace z3 {
|
|||
return tactic(t1.ctx(), r);
|
||||
}
|
||||
|
||||
class simplifier : public object {
|
||||
Z3_simplifier m_simplifier;
|
||||
void init(Z3_simplifier s) {
|
||||
m_simplifier = s;
|
||||
Z3_simplifier_inc_ref(ctx(), s);
|
||||
}
|
||||
public:
|
||||
simplifier(context & c, char const * name):object(c) { Z3_simplifier r = Z3_mk_simplifier(c, name); check_error(); init(r); }
|
||||
simplifier(context & c, Z3_simplifier s):object(c) { init(s); }
|
||||
simplifier(simplifier const & s):object(s) { init(s.m_simplifier); }
|
||||
~simplifier() { Z3_simplifier_dec_ref(ctx(), m_simplifier); }
|
||||
operator Z3_simplifier() const { return m_simplifier; }
|
||||
simplifier & operator=(simplifier const & s) {
|
||||
Z3_simplifier_inc_ref(s.ctx(), s.m_simplifier);
|
||||
Z3_simplifier_dec_ref(ctx(), m_simplifier);
|
||||
object::operator=(s);
|
||||
m_simplifier = s.m_simplifier;
|
||||
return *this;
|
||||
}
|
||||
std::string help() const { char const * r = Z3_simplifier_get_help(ctx(), m_simplifier); check_error(); return r; }
|
||||
friend simplifier operator&(simplifier const & t1, simplifier const & t2);
|
||||
friend simplifier with(simplifier const & t, params const & p);
|
||||
param_descrs get_param_descrs() { return param_descrs(ctx(), Z3_simplifier_get_param_descrs(ctx(), m_simplifier)); }
|
||||
};
|
||||
|
||||
inline solver::solver(solver const& s, simplifier const& simp):object(s) { init(Z3_solver_add_simplifier(s.ctx(), s, simp)); }
|
||||
|
||||
|
||||
inline simplifier operator&(simplifier const & t1, simplifier const & t2) {
|
||||
check_context(t1, t2);
|
||||
Z3_simplifier r = Z3_simplifier_and_then(t1.ctx(), t1, t2);
|
||||
t1.check_error();
|
||||
return simplifier(t1.ctx(), r);
|
||||
}
|
||||
|
||||
inline simplifier with(simplifier const & t, params const & p) {
|
||||
Z3_simplifier r = Z3_simplifier_using_params(t.ctx(), t, p);
|
||||
t.check_error();
|
||||
return simplifier(t.ctx(), r);
|
||||
}
|
||||
|
||||
class probe : public object {
|
||||
Z3_probe m_probe;
|
||||
void init(Z3_probe s) {
|
||||
|
@ -3575,6 +3637,11 @@ namespace z3 {
|
|||
return expr(*this, r);
|
||||
}
|
||||
inline expr context::constant(char const * name, sort const & s) { return constant(str_symbol(name), s); }
|
||||
inline expr context::variable(unsigned idx, sort const& s) {
|
||||
Z3_ast r = Z3_mk_bound(m_ctx, idx, s);
|
||||
check_error();
|
||||
return expr(*this, r);
|
||||
}
|
||||
inline expr context::bool_const(char const * name) { return constant(name, bool_sort()); }
|
||||
inline expr context::int_const(char const * name) { return constant(name, int_sort()); }
|
||||
inline expr context::real_const(char const * name) { return constant(name, real_sort()); }
|
||||
|
@ -3606,7 +3673,7 @@ namespace z3 {
|
|||
inline expr context::int_val(uint64_t n) { Z3_ast r = Z3_mk_unsigned_int64(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
|
||||
inline expr context::int_val(char const * n) { Z3_ast r = Z3_mk_numeral(m_ctx, n, int_sort()); check_error(); return expr(*this, r); }
|
||||
|
||||
inline expr context::real_val(int n, int d) { Z3_ast r = Z3_mk_real(m_ctx, n, d); check_error(); return expr(*this, r); }
|
||||
inline expr context::real_val(int64_t n, int64_t d) { Z3_ast r = Z3_mk_real_int64(m_ctx, n, d); check_error(); return expr(*this, r); }
|
||||
inline expr context::real_val(int n) { Z3_ast r = Z3_mk_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
|
||||
inline expr context::real_val(unsigned n) { Z3_ast r = Z3_mk_unsigned_int(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
|
||||
inline expr context::real_val(int64_t n) { Z3_ast r = Z3_mk_int64(m_ctx, n, real_sort()); check_error(); return expr(*this, r); }
|
||||
|
@ -4059,6 +4126,41 @@ namespace z3 {
|
|||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
inline expr expr::substitute(func_decl_vector const& funs, expr_vector const& dst) {
|
||||
array<Z3_ast> _dst(dst.size());
|
||||
array<Z3_func_decl> _funs(funs.size());
|
||||
if (dst.size() != funs.size()) {
|
||||
Z3_THROW(exception("length of argument lists don't align"));
|
||||
return expr(ctx(), nullptr);
|
||||
}
|
||||
for (unsigned i = 0; i < dst.size(); ++i) {
|
||||
_dst[i] = dst[i];
|
||||
_funs[i] = funs[i];
|
||||
}
|
||||
Z3_ast r = Z3_substitute_funs(ctx(), m_ast, dst.size(), _funs.ptr(), _dst.ptr());
|
||||
check_error();
|
||||
return expr(ctx(), r);
|
||||
}
|
||||
|
||||
typedef std::function<void(expr const& proof, expr_vector const& clause)> on_clause_eh_t;
|
||||
|
||||
class on_clause {
|
||||
context& c;
|
||||
on_clause_eh_t m_on_clause;
|
||||
|
||||
static void _on_clause_eh(void* _ctx, Z3_ast _proof, Z3_ast_vector _literals) {
|
||||
on_clause* ctx = static_cast<on_clause*>(_ctx);
|
||||
expr_vector lits(ctx->c, _literals);
|
||||
expr proof(ctx->c, _proof);
|
||||
ctx->m_on_clause(proof, lits);
|
||||
}
|
||||
public:
|
||||
on_clause(solver& s, on_clause_eh_t& on_clause_eh): c(s.ctx()) {
|
||||
m_on_clause = on_clause_eh;
|
||||
Z3_solver_register_on_clause(c, s, this, _on_clause_eh);
|
||||
c.check_error();
|
||||
}
|
||||
};
|
||||
|
||||
class user_propagator_base {
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ set(Z3_DOTNET_ASSEMBLY_SOURCES_IN_SRC_TREE
|
|||
NativeFuncInterp.cs
|
||||
NativeModel.cs
|
||||
NativeSolver.cs
|
||||
OnClause.cs
|
||||
Optimize.cs
|
||||
ParamDescrs.cs
|
||||
Params.cs
|
||||
|
|
102
src/api/dotnet/OnClause.cs
Normal file
102
src/api/dotnet/OnClause.cs
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
OnClause.cs
|
||||
|
||||
Abstract:
|
||||
|
||||
Callback on clause inferences
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2022-10-19
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
--*/
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Microsoft.Z3
|
||||
{
|
||||
|
||||
using Z3_context = System.IntPtr;
|
||||
using Z3_solver = System.IntPtr;
|
||||
using voidp = System.IntPtr;
|
||||
using Z3_ast = System.IntPtr;
|
||||
using Z3_ast_vector = System.IntPtr;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// OnClause - clause inference callback
|
||||
/// </summary>
|
||||
public class OnClause : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Delegate type for when clauses are inferred.
|
||||
/// An inference is a pair comprising of
|
||||
/// - a proof (hint). A partial (or comprehensive) derivation justifying the inference.
|
||||
/// - a clause (vector of literals)
|
||||
/// The life-time of the proof hint and clause vector is limited to the scope of the callback.
|
||||
/// should the callback want to store hints or clauses it will need to call Dup on the hints
|
||||
/// and/or extract literals from the clause, respectively.
|
||||
/// </summary>
|
||||
public delegate void OnClauseEh(Expr proof_hint, ASTVector clause);
|
||||
|
||||
|
||||
// access managed objects through a static array.
|
||||
// thread safety is ignored for now.
|
||||
GCHandle gch;
|
||||
Solver solver;
|
||||
Context ctx;
|
||||
OnClauseEh on_clause;
|
||||
|
||||
Native.Z3_on_clause_eh on_clause_eh;
|
||||
|
||||
static void _on_clause(voidp ctx, Z3_ast _proof_hint, Z3_ast_vector _clause)
|
||||
{
|
||||
var onc = (OnClause)GCHandle.FromIntPtr(ctx).Target;
|
||||
using var proof_hint = Expr.Create(onc.ctx, _proof_hint);
|
||||
using var clause = new ASTVector(onc.ctx, _clause);
|
||||
onc.on_clause(proof_hint, clause);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// OnClause constructor
|
||||
/// </summary>
|
||||
public OnClause(Solver s, OnClauseEh onc)
|
||||
{
|
||||
gch = GCHandle.Alloc(this);
|
||||
solver = s;
|
||||
ctx = solver.Context;
|
||||
on_clause = onc;
|
||||
on_clause_eh = _on_clause;
|
||||
Native.Z3_solver_register_on_clause(ctx.nCtx, solver.NativeObject, GCHandle.ToIntPtr(gch), on_clause_eh);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Release private memory.
|
||||
/// </summary>
|
||||
~OnClause()
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2110,7 +2110,7 @@ public class Context implements AutoCloseable {
|
|||
* Check if the string s1 is lexicographically strictly less than s2.
|
||||
*/
|
||||
|
||||
public BoolExpr MkStringLt(SeqSort<CharSort> s1, SeqSort<CharSort> s2)
|
||||
public BoolExpr MkStringLt(Expr<SeqSort<CharSort>> s1, Expr<SeqSort<CharSort>> s2)
|
||||
{
|
||||
checkContextMatch(s1, s2);
|
||||
return new BoolExpr(this, Native.mkStrLt(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
|
@ -2119,7 +2119,7 @@ public class Context implements AutoCloseable {
|
|||
/**
|
||||
* Check if the string s1 is lexicographically less or equal to s2.
|
||||
*/
|
||||
public BoolExpr MkStringLe(SeqSort<CharSort> s1, SeqSort<CharSort> s2)
|
||||
public BoolExpr MkStringLe(Expr<SeqSort<CharSort>> s1, Expr<SeqSort<CharSort>> s2)
|
||||
{
|
||||
checkContextMatch(s1, s2);
|
||||
return new BoolExpr(this, Native.mkStrLe(nCtx(), s1.getNativeObject(), s2.getNativeObject()));
|
||||
|
|
|
@ -11,6 +11,9 @@ You'll need to have emscripten set up, along with all of its dependencies. The e
|
|||
|
||||
Then run `npm i` to install dependencies, `npm run build:ts` to build the TypeScript wrapper, and `npm run build:wasm` to build the wasm artifact.
|
||||
|
||||
### Build on your own
|
||||
|
||||
Consult the file [build-wasm.ts](https://github.com/Z3Prover/z3/blob/master/src/api/js/scripts/build-wasm.ts) for configurations used for building wasm.
|
||||
|
||||
## Tests
|
||||
|
||||
|
|
8318
src/api/js/package-lock.json
generated
8318
src/api/js/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -35,7 +35,8 @@
|
|||
"contributors": [
|
||||
"Kevin Gibbons <bakkot@gmail.com>",
|
||||
"Nikolaj Bjorner",
|
||||
"Olaf Tomalka <olaf@tomalka.me>"
|
||||
"Olaf Tomalka <olaf@tomalka.me>",
|
||||
"Walden Yan <waldenyan20@gmail.com>"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/jest": "^27.5.1",
|
||||
|
@ -49,6 +50,7 @@
|
|||
"prettier": "^2.5.1",
|
||||
"rimraf": "^3.0.2",
|
||||
"sprintf-js": "^1.1.2",
|
||||
"ts-expect": "^1.3.0",
|
||||
"ts-jest": "^28.0.3",
|
||||
"ts-node": "^10.8.0",
|
||||
"typedoc": "^0.22.17",
|
||||
|
|
|
@ -45,6 +45,8 @@ const types = {
|
|||
__proto__: null,
|
||||
|
||||
// these are function types I can't be bothered to parse
|
||||
// NSB: They can be extracted automatically from z3_api.h thanks to the use
|
||||
// of a macro.
|
||||
Z3_error_handler: 'Z3_error_handler',
|
||||
Z3_push_eh: 'Z3_push_eh',
|
||||
Z3_pop_eh: 'Z3_pop_eh',
|
||||
|
@ -54,6 +56,7 @@ const types = {
|
|||
Z3_final_eh: 'Z3_final_eh',
|
||||
Z3_created_eh: 'Z3_created_eh',
|
||||
Z3_decide_eh: 'Z3_decide_eh',
|
||||
Z3_on_clause_eh: 'Z3_on_clause_eh',
|
||||
} as unknown as Record<string, string>;
|
||||
|
||||
export type ApiParam = { kind: string; sizeIndex?: number; type: string };
|
||||
|
|
|
@ -2,6 +2,7 @@ import assert from 'assert';
|
|||
import asyncToArray from 'iter-tools/methods/async-to-array';
|
||||
import { init, killThreads } from '../jest';
|
||||
import { Arith, Bool, Model, Z3AssertionError, Z3HighLevel } from './types';
|
||||
import { expectType } from "ts-expect";
|
||||
|
||||
/**
|
||||
* Generate all possible solutions from given assumptions.
|
||||
|
@ -113,7 +114,7 @@ describe('high-level', () => {
|
|||
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')
|
||||
expect(await solver.check()).toStrictEqual('sat')
|
||||
const x = Int.const('x')
|
||||
solver.add(Not(x.eq(1)))
|
||||
expect(await solver.check()).toStrictEqual('unsat')
|
||||
|
@ -211,6 +212,7 @@ describe('high-level', () => {
|
|||
}
|
||||
return cells;
|
||||
}
|
||||
|
||||
const INSTANCE = toSudoku(`
|
||||
....94.3.
|
||||
...51...7
|
||||
|
@ -390,6 +392,106 @@ describe('high-level', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('arrays', () => {
|
||||
|
||||
it('Example 1', async () => {
|
||||
const Z3 = api.Context('main');
|
||||
|
||||
const arr = Z3.Array.const('arr', Z3.Int.sort(), Z3.Int.sort());
|
||||
const [idx, val] = Z3.Int.consts('idx val');
|
||||
|
||||
const conjecture = (arr.store(idx, val).select(idx).eq(val));
|
||||
await prove(conjecture);
|
||||
});
|
||||
|
||||
it('domain and range type inference', async () => {
|
||||
const { BitVec, Array, isArray, isArraySort } = api.Context('main');
|
||||
|
||||
const arr = Array.const('arr', BitVec.sort(160), BitVec.sort(256));
|
||||
|
||||
const domain = arr.domain();
|
||||
expect(domain.size()).toStrictEqual(160);
|
||||
expect(arr.domain_n(0).size()).toStrictEqual(160);
|
||||
const range = arr.range();
|
||||
expect(range.size()).toStrictEqual(256);
|
||||
|
||||
assert(isArray(arr) && isArraySort(arr.sort));
|
||||
|
||||
const arr2 = Array.const('arr2', BitVec.sort(1), BitVec.sort(2), BitVec.sort(3));
|
||||
const dom2 = arr2.domain_n(1);
|
||||
|
||||
// We can call size() on dom2 and see that it is two bits
|
||||
// purely from type inference
|
||||
expectType<2>(dom2.size());
|
||||
|
||||
// Won't let us create an array constant with only one of domain/range
|
||||
// and is detected at compile time
|
||||
// @ts-expect-error
|
||||
const arr3 = Array.const('arr3', BitVec.sort(1));
|
||||
})
|
||||
|
||||
it('can do simple proofs', async () => {
|
||||
const { BitVec, Array, isArray, isArraySort, isConstArray, Eq, Not } = api.Context('main');
|
||||
|
||||
const idx = BitVec.const('idx', 160);
|
||||
const val = BitVec.const('val', 256);
|
||||
|
||||
const FIVE_VAL = BitVec.val(5, 256);
|
||||
|
||||
const arr = Array.const('arr', BitVec.sort(160), BitVec.sort(256));
|
||||
|
||||
const constArr = Array.K(BitVec.sort(160), FIVE_VAL);
|
||||
assert(isArray(arr) && isArraySort(arr.sort) && isConstArray(constArr));
|
||||
|
||||
const arr2 = arr.store(0, 5);
|
||||
await prove(Eq(arr2.select(0), FIVE_VAL));
|
||||
await prove(Not(Eq(arr2.select(0), BitVec.val(6, 256))));
|
||||
await prove(Eq(arr2.store(idx, val).select(idx), constArr.store(idx, val).select(idx)));
|
||||
|
||||
// TODO: add in Quantifiers and better typing of arrays
|
||||
// await prove(
|
||||
// ForAll([idx], idx.add(1).ugt(idx).and(arr.select(idx.add(1)).ugt(arr.select(idx)))).implies(
|
||||
// arr.select(0).ult(arr.select(1000))
|
||||
// )
|
||||
// );
|
||||
});
|
||||
|
||||
it('Finds arrays that differ but that sum to the same', async () => {
|
||||
const Z3 = api.Context('main');
|
||||
const { Array, BitVec } = Z3;
|
||||
|
||||
const mod = 1n << 32n;
|
||||
|
||||
const arr1 = Array.const('arr', BitVec.sort(2), BitVec.sort(32));
|
||||
const arr2 = Array.const('arr2', BitVec.sort(2), BitVec.sort(32));
|
||||
|
||||
const same_sum = arr1.select(0)
|
||||
.add(arr1.select(1))
|
||||
.add(arr1.select(2))
|
||||
.add(arr1.select(3))
|
||||
.eq(
|
||||
arr2.select(0)
|
||||
.add(arr2.select(1))
|
||||
.add(arr2.select(2))
|
||||
.add(arr2.select(3))
|
||||
);
|
||||
|
||||
const different = arr1.select(0).neq(arr2.select(0))
|
||||
.or(arr1.select(1).neq(arr2.select(1)))
|
||||
.or(arr1.select(2).neq(arr2.select(2)))
|
||||
.or(arr1.select(3).neq(arr2.select(3)));
|
||||
|
||||
const model = await solve(same_sum.and(different));
|
||||
|
||||
const arr1Vals = [0, 1, 2, 3].map(i => model.eval(arr1.select(i)).value());
|
||||
const arr2Vals = [0, 1, 2, 3].map(i => model.eval(arr2.select(i)).value());
|
||||
expect((arr1Vals.reduce((a, b) => a + b, 0n) % mod) === arr2Vals.reduce((a, b) => a + b, 0n) % mod);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
expect(arr1Vals[i] !== arr2Vals[i]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('Solver', () => {
|
||||
it('can use push and pop', async () => {
|
||||
const { Solver, Int } = api.Context('main');
|
||||
|
|
|
@ -37,7 +37,7 @@ import {
|
|||
AnyExpr,
|
||||
AnySort,
|
||||
Arith,
|
||||
ArithSort,
|
||||
ArithSort, ArrayIndexType,
|
||||
Ast,
|
||||
AstMap,
|
||||
AstMapCtor,
|
||||
|
@ -48,7 +48,7 @@ import {
|
|||
BitVecSort,
|
||||
Bool,
|
||||
BoolSort,
|
||||
CheckSatResult,
|
||||
CheckSatResult, CoercibleFromMap,
|
||||
CoercibleRational,
|
||||
CoercibleToBitVec,
|
||||
CoercibleToExpr,
|
||||
|
@ -63,6 +63,8 @@ import {
|
|||
Model,
|
||||
Probe,
|
||||
RatNum,
|
||||
SMTArray,
|
||||
SMTArraySort,
|
||||
Solver,
|
||||
Sort,
|
||||
SortToExprMap,
|
||||
|
@ -86,12 +88,11 @@ function isCoercibleRational(obj: any): obj is CoercibleRational {
|
|||
(obj.denominator !== null &&
|
||||
(typeof obj.denominator === 'number' || typeof obj.denominator === 'bigint'))
|
||||
);
|
||||
r &&
|
||||
assert(
|
||||
(typeof obj.numerator !== 'number' || Number.isSafeInteger(obj.numerator)) &&
|
||||
(typeof obj.denominator !== 'number' || Number.isSafeInteger(obj.denominator)),
|
||||
'Fraction numerator and denominator must be integers',
|
||||
);
|
||||
r && assert(
|
||||
(typeof obj!.numerator !== 'number' || Number.isSafeInteger(obj!.numerator)) &&
|
||||
(typeof obj!.denominator !== 'number' || Number.isSafeInteger(obj!.denominator)),
|
||||
'Fraction numerator and denominator must be integers',
|
||||
);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -151,7 +152,9 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
function createContext<Name extends string>(name: Name, options?: Record<string, any>): Context<Name> {
|
||||
const cfg = Z3.mk_config();
|
||||
if (options != null) {
|
||||
Object.entries(options).forEach(([key, value]) => check(Z3.set_param_value(cfg, key, value.toString())));
|
||||
Object.entries(options).forEach(
|
||||
([key, value]) => check(Z3.set_param_value(cfg, key, value.toString()))
|
||||
);
|
||||
}
|
||||
const contextPtr = Z3.mk_context_rc(cfg);
|
||||
Z3.set_ast_print_mode(contextPtr, Z3_ast_print_mode.Z3_PRINT_SMTLIB2_COMPLIANT);
|
||||
|
@ -216,20 +219,22 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return new ArithSortImpl(ast);
|
||||
case Z3_sort_kind.Z3_BV_SORT:
|
||||
return new BitVecSortImpl(ast);
|
||||
case Z3_sort_kind.Z3_ARRAY_SORT:
|
||||
return new ArraySortImpl(ast);
|
||||
default:
|
||||
return new SortImpl(ast);
|
||||
}
|
||||
}
|
||||
|
||||
function _toExpr(ast: Z3_ast): Bool<Name> | IntNum<Name> | RatNum<Name> | Arith<Name> | Expr<Name> {
|
||||
function _toExpr(ast: Z3_ast): AnyExpr<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);
|
||||
return new BoolImpl(ast);
|
||||
if (Z3.is_quantifier_exists(contextPtr, ast))
|
||||
return new BoolImpl(ast);
|
||||
return new BoolImpl(ast);
|
||||
if (Z3.is_lambda(contextPtr, ast))
|
||||
return new ExprImpl(ast);
|
||||
return new ExprImpl(ast);
|
||||
assert(false);
|
||||
}
|
||||
const sortKind = check(Z3.get_sort_kind(contextPtr, Z3.get_sort(contextPtr, ast)));
|
||||
|
@ -251,6 +256,8 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return new BitVecNumImpl(ast);
|
||||
}
|
||||
return new BitVecImpl(ast);
|
||||
case Z3_sort_kind.Z3_ARRAY_SORT:
|
||||
return new ArrayImpl(ast);
|
||||
default:
|
||||
return new ExprImpl(ast);
|
||||
}
|
||||
|
@ -440,6 +447,22 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return r;
|
||||
}
|
||||
|
||||
function isArraySort(obj: unknown): obj is SMTArraySort<Name> {
|
||||
const r = obj instanceof ArraySortImpl;
|
||||
r && _assertContext(obj);
|
||||
return r;
|
||||
}
|
||||
|
||||
function isArray(obj: unknown): obj is SMTArray<Name> {
|
||||
const r = obj instanceof ArrayImpl;
|
||||
r && _assertContext(obj);
|
||||
return r;
|
||||
}
|
||||
|
||||
function isConstArray(obj: unknown): boolean {
|
||||
return isAppOf(obj, Z3_decl_kind.Z3_OP_CONST_ARRAY);
|
||||
}
|
||||
|
||||
function isProbe(obj: unknown): obj is Probe<Name> {
|
||||
const r = obj instanceof ProbeImpl;
|
||||
r && _assertContext(obj);
|
||||
|
@ -508,9 +531,9 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
// expression simplification //
|
||||
///////////////////////////////
|
||||
|
||||
async function simplify(e : Expr<Name>) {
|
||||
const result = await Z3.simplify(contextPtr, e.ast)
|
||||
return _toExpr(check(result));
|
||||
async function simplify(e: Expr<Name>) {
|
||||
const result = await Z3.simplify(contextPtr, e.ast)
|
||||
return _toExpr(check(result));
|
||||
}
|
||||
|
||||
/////////////
|
||||
|
@ -677,6 +700,44 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
);
|
||||
},
|
||||
};
|
||||
const Array = {
|
||||
sort<DomainSort extends [AnySort<Name>, ...AnySort<Name>[]], RangeSort extends AnySort<Name>>(
|
||||
...sig: [...DomainSort, RangeSort]
|
||||
): SMTArraySort<Name, DomainSort, RangeSort> {
|
||||
const arity = sig.length - 1;
|
||||
const r = sig[arity];
|
||||
const d = sig[0];
|
||||
if (arity === 1) {
|
||||
return new ArraySortImpl(Z3.mk_array_sort(contextPtr, d.ptr, r.ptr));
|
||||
}
|
||||
const dom = sig.slice(0, arity);
|
||||
return new ArraySortImpl(Z3.mk_array_sort_n(contextPtr, dom.map(s => s.ptr), r.ptr));
|
||||
},
|
||||
const<DomainSort extends [AnySort<Name>, ...AnySort<Name>[]], RangeSort extends AnySort<Name>>(
|
||||
name: string, ...sig: [...DomainSort, RangeSort]
|
||||
): SMTArray<Name, DomainSort, RangeSort> {
|
||||
return new ArrayImpl<DomainSort, RangeSort>(
|
||||
check(Z3.mk_const(contextPtr, _toSymbol(name), Array.sort(...sig).ptr))
|
||||
);
|
||||
},
|
||||
consts<DomainSort extends [AnySort<Name>, ...AnySort<Name>[]], RangeSort extends AnySort<Name>>(
|
||||
names: string | string[],
|
||||
...sig: [...DomainSort, RangeSort]
|
||||
): SMTArray<Name, DomainSort, RangeSort>[] {
|
||||
if (typeof names === 'string') {
|
||||
names = names.split(' ');
|
||||
}
|
||||
return names.map(name => Array.const(name, ...sig));
|
||||
},
|
||||
K<DomainSort extends AnySort<Name>, RangeSort extends AnySort<Name>>(
|
||||
domain: DomainSort,
|
||||
value: SortToExprMap<RangeSort, Name>
|
||||
): SMTArray<Name, [DomainSort], RangeSort> {
|
||||
return new ArrayImpl<[DomainSort], RangeSort>(
|
||||
check(Z3.mk_const_array(contextPtr, domain.ptr, value.ptr))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////
|
||||
// Operations //
|
||||
|
@ -948,6 +1009,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
|
||||
readonly ptr: Z3_solver;
|
||||
readonly ctx: Context<Name>;
|
||||
|
||||
constructor(ptr: Z3_solver | string = Z3.mk_solver(contextPtr)) {
|
||||
this.ctx = ctx;
|
||||
let myPtr: Z3_solver;
|
||||
|
@ -964,21 +1026,26 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
push() {
|
||||
Z3.solver_push(contextPtr, this.ptr);
|
||||
}
|
||||
|
||||
pop(num: number = 1) {
|
||||
Z3.solver_pop(contextPtr, this.ptr, num);
|
||||
}
|
||||
|
||||
numScopes() {
|
||||
return Z3.solver_get_num_scopes(contextPtr, this.ptr);
|
||||
}
|
||||
|
||||
reset() {
|
||||
Z3.solver_reset(contextPtr, this.ptr);
|
||||
}
|
||||
|
||||
add(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]) {
|
||||
_flattenArgs(exprs).forEach(expr => {
|
||||
_assertContext(expr);
|
||||
check(Z3.solver_assert(contextPtr, this.ptr, expr.ast));
|
||||
});
|
||||
}
|
||||
|
||||
addAndTrack(expr: Bool<Name>, constant: Bool<Name> | string) {
|
||||
if (typeof constant === 'string') {
|
||||
constant = Bool.const(constant);
|
||||
|
@ -1019,7 +1086,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return check(Z3.solver_to_string(contextPtr, this.ptr));
|
||||
}
|
||||
|
||||
fromString(s : string) {
|
||||
fromString(s: string) {
|
||||
Z3.solver_from_string(contextPtr, this.ptr, s);
|
||||
throwIfError();
|
||||
}
|
||||
|
@ -1043,20 +1110,20 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return this.values();
|
||||
}
|
||||
|
||||
*entries(): IterableIterator<[number, FuncDecl<Name>]> {
|
||||
* entries(): IterableIterator<[number, FuncDecl<Name>]> {
|
||||
const length = this.length();
|
||||
for (let i = 0; i < length; i++) {
|
||||
yield [i, this.get(i)];
|
||||
}
|
||||
}
|
||||
|
||||
*keys(): IterableIterator<number> {
|
||||
* keys(): IterableIterator<number> {
|
||||
for (const [key] of this.entries()) {
|
||||
yield key;
|
||||
}
|
||||
}
|
||||
|
||||
*values(): IterableIterator<FuncDecl<Name>> {
|
||||
* values(): IterableIterator<FuncDecl<Name>> {
|
||||
for (const [, value] of this.entries()) {
|
||||
yield value;
|
||||
}
|
||||
|
@ -1076,11 +1143,12 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
|
||||
eval(expr: Bool<Name>, modelCompletion?: boolean): Bool<Name>;
|
||||
eval(expr: Arith<Name>, modelCompletion?: boolean): Arith<Name>;
|
||||
eval<Bits extends number = number>(expr: BitVec<Bits, Name>, modelCompletion?: boolean): BitVecNum<Bits, Name>;
|
||||
eval(expr: Expr<Name>, modelCompletion: boolean = false) {
|
||||
_assertContext(expr);
|
||||
const r = check(Z3.model_eval(contextPtr, this.ptr, expr.ast, modelCompletion));
|
||||
if (r === null) {
|
||||
throw new Z3Error('Failed to evaluatio expression in the model');
|
||||
throw new Z3Error('Failed to evaluate expression in the model');
|
||||
}
|
||||
return _toExpr(r);
|
||||
}
|
||||
|
@ -1092,7 +1160,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
get(sort: Sort<Name>): AstVector<Name, AnyExpr<Name>>;
|
||||
get(
|
||||
i: number | FuncDecl<Name> | Expr<Name> | Sort<Name>,
|
||||
to?: number,
|
||||
to?: number
|
||||
): FuncDecl<Name> | FuncInterp<Name> | Expr<Name> | AstVector<Name, AnyAst<Name>> | FuncDecl<Name>[] {
|
||||
assert(to === undefined || typeof i === 'number');
|
||||
if (typeof i === 'number') {
|
||||
|
@ -1362,15 +1430,22 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
not(): Bool<Name> {
|
||||
return Not(this);
|
||||
}
|
||||
|
||||
and(other: Bool<Name> | boolean): Bool<Name> {
|
||||
return And(this, other);
|
||||
}
|
||||
|
||||
or(other: Bool<Name> | boolean): Bool<Name> {
|
||||
return Or(this, other);
|
||||
}
|
||||
|
||||
xor(other: Bool<Name> | boolean): Bool<Name> {
|
||||
return Xor(this, other);
|
||||
}
|
||||
|
||||
implies(other: Bool<Name> | boolean): Bool<Name> {
|
||||
return Implies(this, other);
|
||||
}
|
||||
}
|
||||
|
||||
class ProbeImpl implements Probe<Name> {
|
||||
|
@ -1571,27 +1646,35 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
add(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvadd(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
mul(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvmul(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
sub(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvsub(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
sdiv(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvsdiv(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
udiv(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvudiv(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
smod(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvsmod(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
urem(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvurem(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
srem(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvsrem(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
neg(): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvneg(contextPtr, this.ast)));
|
||||
}
|
||||
|
@ -1599,33 +1682,43 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
or(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvor(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
and(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvand(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
nand(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvnand(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
xor(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvxor(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
xnor(other: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvxnor(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
shr(count: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvashr(contextPtr, this.ast, this.sort.cast(count).ast)));
|
||||
}
|
||||
|
||||
lshr(count: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvlshr(contextPtr, this.ast, this.sort.cast(count).ast)));
|
||||
}
|
||||
|
||||
shl(count: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvshl(contextPtr, this.ast, this.sort.cast(count).ast)));
|
||||
}
|
||||
|
||||
rotateRight(count: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_ext_rotate_right(contextPtr, this.ast, this.sort.cast(count).ast)));
|
||||
}
|
||||
|
||||
rotateLeft(count: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_ext_rotate_left(contextPtr, this.ast, this.sort.cast(count).ast)));
|
||||
}
|
||||
|
||||
not(): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvnot(contextPtr, this.ast)));
|
||||
}
|
||||
|
@ -1633,12 +1726,15 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
extract(high: number, low: number): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_extract(contextPtr, high, low, this.ast)));
|
||||
}
|
||||
|
||||
signExt(count: number): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_sign_ext(contextPtr, count, this.ast)));
|
||||
}
|
||||
|
||||
zeroExt(count: number): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_zero_ext(contextPtr, count, this.ast)));
|
||||
}
|
||||
|
||||
repeat(count: number): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_repeat(contextPtr, count, this.ast)));
|
||||
}
|
||||
|
@ -1646,24 +1742,31 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
sle(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsle(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
ule(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvule(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
slt(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvslt(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
ult(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvult(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
sge(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsge(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
uge(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvuge(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
sgt(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsgt(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
ugt(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvugt(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
@ -1671,6 +1774,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
redAnd(): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvredand(contextPtr, this.ast)));
|
||||
}
|
||||
|
||||
redOr(): BitVec<Bits, Name> {
|
||||
return new BitVecImpl<Bits>(check(Z3.mk_bvredor(contextPtr, this.ast)));
|
||||
}
|
||||
|
@ -1678,24 +1782,31 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
addNoOverflow(other: CoercibleToBitVec<Bits, Name>, isSigned: boolean): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvadd_no_overflow(contextPtr, this.ast, this.sort.cast(other).ast, isSigned)));
|
||||
}
|
||||
|
||||
addNoUnderflow(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvadd_no_underflow(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
subNoOverflow(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsub_no_overflow(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
subNoUndeflow(other: CoercibleToBitVec<Bits, Name>, isSigned: boolean): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsub_no_underflow(contextPtr, this.ast, this.sort.cast(other).ast, isSigned)));
|
||||
}
|
||||
|
||||
sdivNoOverflow(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvsdiv_no_overflow(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
mulNoOverflow(other: CoercibleToBitVec<Bits, Name>, isSigned: boolean): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvmul_no_overflow(contextPtr, this.ast, this.sort.cast(other).ast, isSigned)));
|
||||
}
|
||||
|
||||
mulNoUndeflow(other: CoercibleToBitVec<Bits, Name>): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvmul_no_underflow(contextPtr, this.ast, this.sort.cast(other).ast)));
|
||||
}
|
||||
|
||||
negNoOverflow(): Bool<Name> {
|
||||
return new BoolImpl(check(Z3.mk_bvneg_no_overflow(contextPtr, this.ast)));
|
||||
}
|
||||
|
@ -1703,6 +1814,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
|
||||
class BitVecNumImpl<Bits extends number> extends BitVecImpl<Bits> implements BitVecNum<Bits, Name> {
|
||||
declare readonly __typename: BitVecNum['__typename'];
|
||||
|
||||
value() {
|
||||
return BigInt(this.asString());
|
||||
}
|
||||
|
@ -1718,14 +1830,87 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
asString() {
|
||||
return Z3.get_numeral_string(contextPtr, this.ast);
|
||||
}
|
||||
|
||||
asBinaryString() {
|
||||
return Z3.get_numeral_binary_string(contextPtr, this.ast);
|
||||
}
|
||||
}
|
||||
|
||||
class ArraySortImpl<DomainSort extends [AnySort<Name>, ...AnySort<Name>[]] = [Sort<Name>, ...Sort<Name>[]],
|
||||
RangeSort extends AnySort<Name> = Sort<Name>>
|
||||
extends SortImpl
|
||||
implements SMTArraySort<Name, DomainSort, RangeSort> {
|
||||
declare readonly __typename: SMTArraySort['__typename'];
|
||||
|
||||
domain(): DomainSort[0] {
|
||||
return _toSort(check(Z3.get_array_sort_domain(contextPtr, this.ptr)));
|
||||
}
|
||||
|
||||
domain_n<T extends number>(i: T): DomainSort[T] {
|
||||
return _toSort(check(Z3.get_array_sort_domain_n(contextPtr, this.ptr, i)));
|
||||
}
|
||||
|
||||
range(): RangeSort {
|
||||
return _toSort(check(Z3.get_array_sort_range(contextPtr, this.ptr))) as RangeSort;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class ArrayImpl<
|
||||
DomainSort extends [AnySort<Name>, ...AnySort<Name>[]] = [Sort<Name>, ...Sort<Name>[]],
|
||||
RangeSort extends AnySort<Name> = Sort<Name>
|
||||
> extends ExprImpl<Z3_ast, ArraySortImpl<DomainSort, RangeSort>>
|
||||
implements SMTArray<Name, DomainSort, RangeSort> {
|
||||
declare readonly __typename: SMTArray['__typename'];
|
||||
|
||||
domain(): DomainSort[0] {
|
||||
return this.sort.domain();
|
||||
}
|
||||
|
||||
domain_n<T extends number>(i: T): DomainSort[T] {
|
||||
return this.sort.domain_n(i);
|
||||
}
|
||||
|
||||
range(): RangeSort {
|
||||
return this.sort.range();
|
||||
}
|
||||
|
||||
select(...indices: ArrayIndexType<Name, DomainSort>): SortToExprMap<RangeSort, Name> {
|
||||
const args = indices.map((arg, i) => this.domain_n(i).cast(arg as any));
|
||||
if (args.length === 1) {
|
||||
return _toExpr(check(Z3.mk_select(contextPtr, this.ast, args[0].ast))) as SortToExprMap<RangeSort, Name>;
|
||||
}
|
||||
const _args = args.map(arg => arg.ast);
|
||||
return _toExpr(check(Z3.mk_select_n(contextPtr, this.ast, _args))) as SortToExprMap<RangeSort, Name>;
|
||||
}
|
||||
|
||||
store(
|
||||
...indicesAndValue: [
|
||||
...ArrayIndexType<Name, DomainSort>,
|
||||
CoercibleFromMap<SortToExprMap<RangeSort, Name>, Name>
|
||||
]
|
||||
): SMTArray<Name, DomainSort, RangeSort> {
|
||||
const args = indicesAndValue.map((arg, i) => {
|
||||
if (i === indicesAndValue.length - 1) {
|
||||
return this.range().cast(arg as CoercibleFromMap<SortToExprMap<RangeSort, Name>, Name>);
|
||||
}
|
||||
return this.domain_n(i).cast(arg as any);
|
||||
});
|
||||
if (args.length <= 1) {
|
||||
throw new Z3Error("Array store requires both index and value arguments");
|
||||
}
|
||||
if (args.length === 2) {
|
||||
return _toExpr(check(Z3.mk_store(contextPtr, this.ast, args[0].ast, args[1].ast))) as SMTArray<Name, DomainSort, RangeSort>;
|
||||
}
|
||||
const _idxs = args.slice(0, args.length - 1).map(arg => arg.ast);
|
||||
return _toExpr(check(Z3.mk_store_n(contextPtr, this.ast, _idxs, args[args.length - 1].ast))) as SMTArray<Name, DomainSort, RangeSort>;
|
||||
}
|
||||
}
|
||||
|
||||
class AstVectorImpl<Item extends AnyAst<Name>> {
|
||||
declare readonly __typename: AstVector['__typename'];
|
||||
readonly ctx: Context<Name>;
|
||||
|
@ -1744,20 +1929,20 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return this.values();
|
||||
}
|
||||
|
||||
*entries(): IterableIterator<[number, Item]> {
|
||||
* entries(): IterableIterator<[number, Item]> {
|
||||
const length = this.length();
|
||||
for (let i = 0; i < length; i++) {
|
||||
yield [i, this.get(i)];
|
||||
}
|
||||
}
|
||||
|
||||
*keys(): IterableIterator<number> {
|
||||
* keys(): IterableIterator<number> {
|
||||
for (let [key] of this.entries()) {
|
||||
yield key;
|
||||
}
|
||||
}
|
||||
|
||||
*values(): IterableIterator<Item> {
|
||||
* values(): IterableIterator<Item> {
|
||||
for (let [, value] of this.entries()) {
|
||||
yield value;
|
||||
}
|
||||
|
@ -1842,7 +2027,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return Z3.ast_map_size(contextPtr, this.ptr);
|
||||
}
|
||||
|
||||
*entries(): IterableIterator<[Key, Value]> {
|
||||
* entries(): IterableIterator<[Key, Value]> {
|
||||
for (const key of this.keys()) {
|
||||
yield [key, this.get(key)];
|
||||
}
|
||||
|
@ -1852,11 +2037,12 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
return new AstVectorImpl(Z3.ast_map_keys(contextPtr, this.ptr));
|
||||
}
|
||||
|
||||
*values(): IterableIterator<Value> {
|
||||
* values(): IterableIterator<Value> {
|
||||
for (const [_, value] of this.entries()) {
|
||||
yield value;
|
||||
}
|
||||
}
|
||||
|
||||
get(key: Key): Value {
|
||||
return _toAst(check(Z3.ast_map_find(contextPtr, this.ptr, key.ast))) as Value;
|
||||
}
|
||||
|
@ -1928,6 +2114,9 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
isBitVecSort,
|
||||
isBitVec,
|
||||
isBitVecVal, // TODO fix ordering
|
||||
isArraySort,
|
||||
isArray,
|
||||
isConstArray,
|
||||
isProbe,
|
||||
isTactic,
|
||||
isAstVector,
|
||||
|
@ -1946,6 +2135,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
|||
Int,
|
||||
Real,
|
||||
BitVec,
|
||||
Array,
|
||||
|
||||
////////////////
|
||||
// Operations //
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -528,7 +528,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module &m)
|
|||
m.BINARY_OP(tactic, &, &);
|
||||
m.BINARY_OP(tactic, |, |);
|
||||
m.method("repeat", &repeat);
|
||||
m.method("with", &with);
|
||||
m.method("with", static_cast<tactic (*)(const tactic & , const params &)>(&with));
|
||||
m.method("try_for", &try_for);
|
||||
m.method("par_or", &par_or);
|
||||
m.method("par_and_then", &par_and_then);
|
||||
|
@ -692,7 +692,7 @@ JLCXX_MODULE define_julia_module(jlcxx::Module &m)
|
|||
.method("real_val", [](context &a, const jlcxx::StrictlyTypedNumber<unsigned> b) { return a.real_val(b.value); })
|
||||
.method("real_val", [](context &a, const jlcxx::StrictlyTypedNumber<int64_t> b) { return a.real_val(b.value); })
|
||||
.method("real_val", [](context &a, const jlcxx::StrictlyTypedNumber<uint64_t> b) { return a.real_val(b.value); })
|
||||
.method("real_val", static_cast<expr (context::*)(int, int)>(&context::real_val))
|
||||
.method("real_val", static_cast<expr (context::*)(int64_t, int64_t)>(&context::real_val))
|
||||
.method("real_val", static_cast<expr (context::*)(char const *)>(&context::real_val))
|
||||
//
|
||||
.method("bv_val", [](context &a, const jlcxx::StrictlyTypedNumber<int> b, unsigned c) { return a.bv_val(b.value, c); })
|
||||
|
|
|
@ -1734,6 +1734,39 @@ struct
|
|||
let interrupt = Z3native.interrupt
|
||||
end
|
||||
|
||||
module Simplifier =
|
||||
struct
|
||||
type simplifier = Z3native.simplifier
|
||||
let gc = Z3native.context_of_simplifier
|
||||
|
||||
let get_help (x:simplifier) = Z3native.simplifier_get_help (gc x) x
|
||||
|
||||
let get_param_descrs (x:simplifier) = Z3native.simplifier_get_param_descrs (gc x) x
|
||||
|
||||
let get_num_simplifiers = Z3native.get_num_simplifiers
|
||||
|
||||
let get_simplifier_names (ctx:context) =
|
||||
let n = get_num_simplifiers ctx in
|
||||
let f i = Z3native.get_simplifier_name ctx i in
|
||||
mk_list f n
|
||||
|
||||
let get_simplifier_description = Z3native.simplifier_get_descr
|
||||
|
||||
let mk_simplifier = Z3native.mk_simplifier
|
||||
|
||||
let and_then (ctx:context) (t1:simplifier) (t2:simplifier) (ts:simplifier list) =
|
||||
let f p c = (match p with
|
||||
| None -> Some c
|
||||
| Some(x) -> Some (Z3native.simplifier_and_then ctx c x)) in
|
||||
match (List.fold_left f None ts) with
|
||||
| None -> Z3native.simplifier_and_then ctx t1 t2
|
||||
| Some(x) -> let o = Z3native.simplifier_and_then ctx t2 x in
|
||||
Z3native.simplifier_and_then ctx t1 o
|
||||
|
||||
let using_params = Z3native.simplifier_using_params
|
||||
let with_ = using_params
|
||||
|
||||
end
|
||||
|
||||
module Statistics =
|
||||
struct
|
||||
|
@ -1868,6 +1901,7 @@ struct
|
|||
let mk_solver_s ctx logic = mk_solver ctx (Some (Symbol.mk_string ctx logic))
|
||||
let mk_simple_solver = Z3native.mk_simple_solver
|
||||
let mk_solver_t = Z3native.mk_solver_from_tactic
|
||||
let add_simplifier = Z3native.solver_add_simplifier
|
||||
let translate x = Z3native.solver_translate (gc x) x
|
||||
let to_string x = Z3native.solver_to_string (gc x) x
|
||||
end
|
||||
|
|
|
@ -3102,6 +3102,38 @@ sig
|
|||
val interrupt : context -> unit
|
||||
end
|
||||
|
||||
module Simplifier :
|
||||
sig
|
||||
type simplifier
|
||||
|
||||
(** A string containing a description of parameters accepted by the simplifier. *)
|
||||
val get_help : simplifier -> string
|
||||
|
||||
(** Retrieves parameter descriptions for Simplifiers. *)
|
||||
val get_param_descrs : simplifier -> Params.ParamDescrs.param_descrs
|
||||
|
||||
(** The number of supported simplifiers. *)
|
||||
val get_num_simplifiers : context -> int
|
||||
|
||||
(** The names of all supported simplifiers. *)
|
||||
val get_simplifier_names : context -> string list
|
||||
|
||||
(** Returns a string containing a description of the simplifier with the given name. *)
|
||||
val get_simplifier_description : context -> string -> string
|
||||
|
||||
(** Creates a new Simplifier. *)
|
||||
val mk_simplifier : context -> string -> simplifier
|
||||
|
||||
(** Create a simplifier that applies one simplifier to a Goal and
|
||||
then another one to every subgoal produced by the first one. *)
|
||||
val and_then : context -> simplifier -> simplifier -> simplifier list -> simplifier
|
||||
|
||||
(** Create a simplifier that applies a simplifier using the given set of parameters. *)
|
||||
val using_params : context -> simplifier -> Params.params -> simplifier
|
||||
val with_ : context -> simplifier -> Params.params -> simplifier
|
||||
|
||||
end
|
||||
|
||||
(** Objects that track statistical information. *)
|
||||
module Statistics :
|
||||
sig
|
||||
|
@ -3265,6 +3297,9 @@ sig
|
|||
will always solve each check from scratch. *)
|
||||
val mk_solver_t : context -> Tactic.tactic -> solver
|
||||
|
||||
(** Create a solver with simplifying pre-processing **)
|
||||
val add_simplifier : context -> solver -> Simplifier.simplifier -> solver
|
||||
|
||||
(** Create a clone of the current solver with respect to a context. *)
|
||||
val translate : solver -> context -> solver
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ and solver = ptr
|
|||
and solver_callback = ptr
|
||||
and goal = ptr
|
||||
and tactic = ptr
|
||||
and simplifier = ptr
|
||||
and params = ptr
|
||||
and parser_context = ptr
|
||||
and probe = ptr
|
||||
|
|
|
@ -424,6 +424,7 @@ MK_PLUS_OBJ(func_interp, 32)
|
|||
MK_PLUS_OBJ(func_entry, 32)
|
||||
MK_PLUS_OBJ(goal, 64)
|
||||
MK_PLUS_OBJ(tactic, 64)
|
||||
MK_PLUS_OBJ(simplifier, 64)
|
||||
MK_PLUS_OBJ(probe, 64)
|
||||
MK_PLUS_OBJ(apply_result, 32)
|
||||
MK_PLUS_OBJ(solver, 20 * 1000)
|
||||
|
|
|
@ -277,7 +277,7 @@ if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
|||
# linux builds should be built in the centos 5 vm for maximum compatibility
|
||||
# see https://github.com/pypa/manylinux
|
||||
# see also https://github.com/angr/angr-dev/blob/master/admin/bdist.py
|
||||
plat_name = 'manylinux1_' + platform.machine()
|
||||
plat_name = 'manylinux2014_' + platform.machine()
|
||||
elif 'mingw' in name:
|
||||
if platform.architecture()[0] == '64bit':
|
||||
plat_name = 'win_amd64'
|
||||
|
@ -296,9 +296,9 @@ if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
|
|||
)
|
||||
elif distos == 'glibc':
|
||||
if arch == 'x64':
|
||||
plat_name = 'manylinux1_x86_64'
|
||||
plat_name = 'manylinux2014_x86_64'
|
||||
else:
|
||||
plat_name = 'manylinux1_i686'
|
||||
plat_name = 'manylinux2014_i686'
|
||||
elif distos == 'linux' and os_id == 'alpine':
|
||||
if arch == 'x64':
|
||||
plat_name = 'musllinux_1_1_x86_64'
|
||||
|
|
|
@ -763,8 +763,6 @@ class FuncDeclRef(AstRef):
|
|||
>>> f.domain(1)
|
||||
Real
|
||||
"""
|
||||
if z3_debug():
|
||||
_z3_assert(i < self.arity(), "Index out of bounds")
|
||||
return _to_sort_ref(Z3_get_domain(self.ctx_ref(), self.ast, i), self.ctx)
|
||||
|
||||
def range(self):
|
||||
|
@ -834,8 +832,6 @@ class FuncDeclRef(AstRef):
|
|||
"""
|
||||
args = _get_args(args)
|
||||
num = len(args)
|
||||
if z3_debug():
|
||||
_z3_assert(num == self.arity(), "Incorrect number of arguments to %s" % self)
|
||||
_args = (Ast * num)()
|
||||
saved = []
|
||||
for i in range(num):
|
||||
|
@ -1194,7 +1190,7 @@ def _coerce_expr_merge(s, a):
|
|||
else:
|
||||
if z3_debug():
|
||||
_z3_assert(s1.ctx == s.ctx, "context mismatch")
|
||||
_z3_assert(False, "sort mismatch")
|
||||
_z3_assert(False, "sort mismatch")
|
||||
else:
|
||||
return s
|
||||
|
||||
|
@ -1207,6 +1203,11 @@ def _coerce_exprs(a, b, ctx=None):
|
|||
a = StringVal(a, b.ctx)
|
||||
if isinstance(b, str) and isinstance(a, SeqRef):
|
||||
b = StringVal(b, a.ctx)
|
||||
if isinstance(a, float) and isinstance(b, ArithRef):
|
||||
a = RealVal(a, b.ctx)
|
||||
if isinstance(b, float) and isinstance(a, ArithRef):
|
||||
b = RealVal(b, a.ctx)
|
||||
|
||||
s = None
|
||||
s = _coerce_expr_merge(s, a)
|
||||
s = _coerce_expr_merge(s, b)
|
||||
|
@ -1464,7 +1465,9 @@ def FreshConst(sort, prefix="c"):
|
|||
|
||||
def Var(idx, s):
|
||||
"""Create a Z3 free variable. Free variables are used to create quantified formulas.
|
||||
|
||||
A free variable with index n is bound when it occurs within the scope of n+1 quantified
|
||||
declarations.
|
||||
|
||||
>>> Var(0, IntSort())
|
||||
Var(0)
|
||||
>>> eq(Var(0, IntSort()), Var(0, BoolSort()))
|
||||
|
@ -1552,13 +1555,15 @@ class BoolRef(ExprRef):
|
|||
def __mul__(self, other):
|
||||
"""Create the Z3 expression `self * other`.
|
||||
"""
|
||||
if other == 1:
|
||||
return self
|
||||
if other == 0:
|
||||
return 0
|
||||
if isinstance(other, int) and other == 1:
|
||||
return If(self, 1, 0)
|
||||
if isinstance(other, int) and other == 0:
|
||||
return IntVal(0, self.ctx)
|
||||
if isinstance(other, BoolRef):
|
||||
other = If(other, 1, 0)
|
||||
return If(self, other, 0)
|
||||
|
||||
|
||||
|
||||
def is_bool(a):
|
||||
"""Return `True` if `a` is a Z3 Boolean expression.
|
||||
|
||||
|
@ -4588,10 +4593,10 @@ class ArrayRef(ExprRef):
|
|||
|
||||
def _array_select(ar, arg):
|
||||
if isinstance(arg, tuple):
|
||||
args = [ar.domain_n(i).cast(arg[i]) for i in range(len(arg))]
|
||||
args = [ar.sort().domain_n(i).cast(arg[i]) for i in range(len(arg))]
|
||||
_args, sz = _to_ast_array(args)
|
||||
return _to_expr_ref(Z3_mk_select_n(ar.ctx_ref(), ar.as_ast(), sz, _args), ar.ctx)
|
||||
arg = ar.domain().cast(arg)
|
||||
arg = ar.sort().domain().cast(arg)
|
||||
return _to_expr_ref(Z3_mk_select(ar.ctx_ref(), ar.as_ast(), arg.as_ast()), ar.ctx)
|
||||
|
||||
|
||||
|
@ -6653,7 +6658,7 @@ class ModelRef(Z3PPObject):
|
|||
n = Z3_func_entry_get_num_args(x.ctx_ref(), e.entry)
|
||||
v = AstVector()
|
||||
for j in range(n):
|
||||
v.push(entry.arg_value(j))
|
||||
v.push(e.arg_value(j))
|
||||
val = Z3_func_entry_get_value(x.ctx_ref(), e.entry)
|
||||
Z3_func_interp_add_entry(x.ctx_ref(), fi2.f, v.vector, val)
|
||||
return
|
||||
|
@ -7232,6 +7237,22 @@ class Solver(Z3PPObject):
|
|||
cube are likely more useful to cube on."""
|
||||
return self.cube_vs
|
||||
|
||||
def root(self, t):
|
||||
t = _py2expr(t, self.ctx)
|
||||
"""Retrieve congruence closure root of the term t relative to the current search state
|
||||
The function primarily works for SimpleSolver. Terms and variables that are
|
||||
eliminated during pre-processing are not visible to the congruence closure.
|
||||
"""
|
||||
return _to_expr_ref(Z3_solver_congruence_root(self.ctx.ref(), self.solver, t.ast), self.ctx)
|
||||
|
||||
def next(self, t):
|
||||
t = _py2expr(t, self.ctx)
|
||||
"""Retrieve congruence closure sibling of the term t relative to the current search state
|
||||
The function primarily works for SimpleSolver. Terms and variables that are
|
||||
eliminated during pre-processing are not visible to the congruence closure.
|
||||
"""
|
||||
return _to_expr_ref(Z3_solver_congruence_next(self.ctx.ref(), self.solver, t.ast), self.ctx)
|
||||
|
||||
def proof(self):
|
||||
"""Return a proof for the last `check()`. Proof construction must be enabled."""
|
||||
return _to_expr_ref(Z3_solver_get_proof(self.ctx.ref(), self.solver), self.ctx)
|
||||
|
@ -8148,6 +8169,64 @@ class ApplyResult(Z3PPObject):
|
|||
else:
|
||||
return Or([self[i].as_expr() for i in range(len(self))])
|
||||
|
||||
#########################################
|
||||
#
|
||||
# Simplifiers
|
||||
#
|
||||
#########################################
|
||||
|
||||
class Simplifier:
|
||||
"""Simplifiers act as pre-processing utilities for solvers.
|
||||
Build a custom simplifier and add it to a solver"""
|
||||
|
||||
def __init__(self, simplifier, ctx=None):
|
||||
self.ctx = _get_ctx(ctx)
|
||||
self.simplifier = None
|
||||
if isinstance(simplifier, SimplifierObj):
|
||||
self.simplifier = simplifier
|
||||
elif isinstance(simplifier, list):
|
||||
simps = [Simplifier(s, ctx) for s in simplifier]
|
||||
self.simplifier = simps[0].simplifier
|
||||
for i in range(1, len(simps)):
|
||||
self.simplifier = Z3_simplifier_and_then(self.ctx.ref(), self.simplifier, simps[i].simplifier)
|
||||
Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
|
||||
return
|
||||
else:
|
||||
if z3_debug():
|
||||
_z3_assert(isinstance(simplifier, str), "simplifier name expected")
|
||||
try:
|
||||
self.simplifier = Z3_mk_simplifier(self.ctx.ref(), str(simplifier))
|
||||
except Z3Exception:
|
||||
raise Z3Exception("unknown simplifier '%s'" % simplifier)
|
||||
Z3_simplifier_inc_ref(self.ctx.ref(), self.simplifier)
|
||||
|
||||
def __deepcopy__(self, memo={}):
|
||||
return Simplifier(self.simplifier, self.ctx)
|
||||
|
||||
def __del__(self):
|
||||
if self.simplifier is not None and self.ctx.ref() is not None and Z3_simplifier_dec_ref is not None:
|
||||
Z3_simplifier_dec_ref(self.ctx.ref(), self.simplifier)
|
||||
|
||||
def using_params(self, *args, **keys):
|
||||
"""Return a simplifier that uses the given configuration options"""
|
||||
p = args2params(args, keys, self.ctx)
|
||||
return Simplifier(Z3_simplifier_using_params(self.ctx.ref(), self.simplifier, p.params), self.ctx)
|
||||
|
||||
def add(self, solver):
|
||||
"""Return a solver that applies the simplification pre-processing specified by the simplifier"""
|
||||
print(solver.solver)
|
||||
print(self.simplifier)
|
||||
return Solver(Z3_solver_add_simplifier(self.ctx.ref(), solver.solver, self.simplifier), self.ctx)
|
||||
|
||||
def help(self):
|
||||
"""Display a string containing a description of the available options for the `self` simplifier."""
|
||||
print(Z3_simplifier_get_help(self.ctx.ref(), self.simplifier))
|
||||
|
||||
def param_descrs(self):
|
||||
"""Return the parameter description set."""
|
||||
return ParamDescrsRef(Z3_simplifier_get_param_descrs(self.ctx.ref(), self.simplifier), self.ctx)
|
||||
|
||||
|
||||
#########################################
|
||||
#
|
||||
# Tactics
|
||||
|
@ -8832,7 +8911,7 @@ def substitute_vars(t, *m):
|
|||
return _to_expr_ref(Z3_substitute_vars(t.ctx.ref(), t.as_ast(), num, _to), t.ctx)
|
||||
|
||||
def substitute_funs(t, *m):
|
||||
"""Apply subistitution m on t, m is a list of pairs of a function and expression (from, to)
|
||||
"""Apply substitution m on t, m is a list of pairs of a function and expression (from, to)
|
||||
Every occurrence in to of the function from is replaced with the expression to.
|
||||
The expression to can have free variables, that refer to the arguments of from.
|
||||
For examples, see
|
||||
|
@ -10079,7 +10158,7 @@ def FPs(names, fpsort, ctx=None):
|
|||
>>> x.ebits()
|
||||
8
|
||||
>>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
|
||||
fpMul(RNE(), fpAdd(RNE(), x, y), z)
|
||||
x + y * z
|
||||
"""
|
||||
ctx = _get_ctx(ctx)
|
||||
if isinstance(names, str):
|
||||
|
@ -10186,9 +10265,9 @@ def fpAdd(rm, a, b, ctx=None):
|
|||
>>> x = FP('x', s)
|
||||
>>> y = FP('y', s)
|
||||
>>> fpAdd(rm, x, y)
|
||||
fpAdd(RNE(), x, y)
|
||||
>>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
|
||||
x + y
|
||||
>>> fpAdd(RTZ(), x, y) # default rounding mode is RTZ
|
||||
fpAdd(RTZ(), x, y)
|
||||
>>> fpAdd(rm, x, y).sort()
|
||||
FPSort(8, 24)
|
||||
"""
|
||||
|
@ -10203,7 +10282,7 @@ def fpSub(rm, a, b, ctx=None):
|
|||
>>> x = FP('x', s)
|
||||
>>> y = FP('y', s)
|
||||
>>> fpSub(rm, x, y)
|
||||
fpSub(RNE(), x, y)
|
||||
x - y
|
||||
>>> fpSub(rm, x, y).sort()
|
||||
FPSort(8, 24)
|
||||
"""
|
||||
|
@ -10218,7 +10297,7 @@ def fpMul(rm, a, b, ctx=None):
|
|||
>>> x = FP('x', s)
|
||||
>>> y = FP('y', s)
|
||||
>>> fpMul(rm, x, y)
|
||||
fpMul(RNE(), x, y)
|
||||
x * y
|
||||
>>> fpMul(rm, x, y).sort()
|
||||
FPSort(8, 24)
|
||||
"""
|
||||
|
@ -10233,7 +10312,7 @@ def fpDiv(rm, a, b, ctx=None):
|
|||
>>> x = FP('x', s)
|
||||
>>> y = FP('y', s)
|
||||
>>> fpDiv(rm, x, y)
|
||||
fpDiv(RNE(), x, y)
|
||||
x / y
|
||||
>>> fpDiv(rm, x, y).sort()
|
||||
FPSort(8, 24)
|
||||
"""
|
||||
|
@ -11301,6 +11380,45 @@ def TransitiveClosure(f):
|
|||
"""
|
||||
return FuncDeclRef(Z3_mk_transitive_closure(f.ctx_ref(), f.ast), f.ctx)
|
||||
|
||||
def to_Ast(ptr,):
|
||||
ast = Ast(ptr)
|
||||
super(ctypes.c_void_p, ast).__init__(ptr)
|
||||
return ast
|
||||
|
||||
def to_ContextObj(ptr,):
|
||||
ctx = ContextObj(ptr)
|
||||
super(ctypes.c_void_p, ctx).__init__(ptr)
|
||||
return ctx
|
||||
|
||||
def to_AstVectorObj(ptr,):
|
||||
v = AstVectorObj(ptr)
|
||||
super(ctypes.c_void_p, v).__init__(ptr)
|
||||
return v
|
||||
|
||||
# NB. my-hacky-class only works for a single instance of OnClause
|
||||
# it should be replaced with a proper correlation between OnClause
|
||||
# and object references that can be passed over the FFI.
|
||||
# for UserPropagator we use a global dictionary, which isn't great code.
|
||||
|
||||
_my_hacky_class = None
|
||||
def on_clause_eh(ctx, p, clause):
|
||||
onc = _my_hacky_class
|
||||
p = _to_expr_ref(to_Ast(p), onc.ctx)
|
||||
clause = AstVector(to_AstVectorObj(clause), onc.ctx)
|
||||
onc.on_clause(p, clause)
|
||||
|
||||
_on_clause_eh = Z3_on_clause_eh(on_clause_eh)
|
||||
|
||||
class OnClause:
|
||||
def __init__(self, s, on_clause):
|
||||
self.s = s
|
||||
self.ctx = s.ctx
|
||||
self.on_clause = on_clause
|
||||
self.idx = 22
|
||||
global _my_hacky_class
|
||||
_my_hacky_class = self
|
||||
Z3_solver_register_on_clause(self.ctx.ref(), self.s.solver, self.idx, _on_clause_eh)
|
||||
|
||||
|
||||
class PropClosures:
|
||||
def __init__(self):
|
||||
|
@ -11358,11 +11476,6 @@ def user_prop_pop(ctx, cb, num_scopes):
|
|||
prop.cb = cb
|
||||
prop.pop(num_scopes)
|
||||
|
||||
def to_ContextObj(ptr,):
|
||||
ctx = ContextObj(ptr)
|
||||
super(ctypes.c_void_p, ctx).__init__(ptr)
|
||||
return ctx
|
||||
|
||||
|
||||
def user_prop_fresh(ctx, _new_ctx):
|
||||
_prop_closures.set_threaded()
|
||||
|
@ -11377,10 +11490,6 @@ def user_prop_fresh(ctx, _new_ctx):
|
|||
_prop_closures.set(new_prop.id, new_prop)
|
||||
return new_prop.id
|
||||
|
||||
def to_Ast(ptr,):
|
||||
ast = Ast(ptr)
|
||||
super(ctypes.c_void_p, ast).__init__(ptr)
|
||||
return ast
|
||||
|
||||
def user_prop_fixed(ctx, cb, id, value):
|
||||
prop = _prop_closures.get(ctx)
|
||||
|
@ -11442,6 +11551,7 @@ _user_prop_eq = Z3_eq_eh(user_prop_eq)
|
|||
_user_prop_diseq = Z3_eq_eh(user_prop_diseq)
|
||||
_user_prop_decide = Z3_decide_eh(user_prop_decide)
|
||||
|
||||
|
||||
def PropagateFunction(name, *sig):
|
||||
"""Create a function that gets tracked by user propagator.
|
||||
Every term headed by this function symbol is tracked.
|
||||
|
@ -11462,7 +11572,8 @@ def PropagateFunction(name, *sig):
|
|||
dom[i] = sig[i].ast
|
||||
ctx = rng.ctx
|
||||
return FuncDeclRef(Z3_solver_propagate_declare(ctx.ref(), to_symbol(name, ctx), arity, dom, rng.ast), ctx)
|
||||
|
||||
|
||||
|
||||
|
||||
class UserPropagateBase:
|
||||
|
||||
|
|
|
@ -120,6 +120,12 @@ class TacticObj(ctypes.c_void_p):
|
|||
def from_param(obj):
|
||||
return obj
|
||||
|
||||
class SimplifierObj(ctypes.c_void_p):
|
||||
def __init__(self, simplifier):
|
||||
self._as_parameter_ = simplifier
|
||||
|
||||
def from_param(obj):
|
||||
return obj
|
||||
|
||||
class ProbeObj(ctypes.c_void_p):
|
||||
def __init__(self, probe):
|
||||
|
|
161
src/api/z3_api.h
161
src/api/z3_api.h
|
@ -23,6 +23,7 @@ DEFINE_TYPE(Z3_param_descrs);
|
|||
DEFINE_TYPE(Z3_parser_context);
|
||||
DEFINE_TYPE(Z3_goal);
|
||||
DEFINE_TYPE(Z3_tactic);
|
||||
DEFINE_TYPE(Z3_simplifier);
|
||||
DEFINE_TYPE(Z3_probe);
|
||||
DEFINE_TYPE(Z3_stats);
|
||||
DEFINE_TYPE(Z3_solver);
|
||||
|
@ -69,6 +70,7 @@ DEFINE_TYPE(Z3_rcf_num);
|
|||
- \c Z3_ast_map: mapping from \c Z3_ast to \c Z3_ast objects.
|
||||
- \c Z3_goal: set of formulas that can be solved and/or transformed using tactics and solvers.
|
||||
- \c Z3_tactic: basic building block for creating custom solvers for specific problem domains.
|
||||
- \c Z3_simplifier: basic building block for creating custom pre-processing simplifiers.
|
||||
- \c Z3_probe: function/predicate used to inspect a goal and collect information that may be used to decide which solver and/or preprocessing step will be used.
|
||||
- \c Z3_apply_result: collection of subgoals resulting from applying of a tactic to a goal.
|
||||
- \c Z3_solver: (incremental) solver, possibly specialized by a particular tactic or logic.
|
||||
|
@ -1403,6 +1405,7 @@ typedef enum
|
|||
def_Type('PARSER_CONTEXT', 'Z3_parser_context', 'ParserContextObj')
|
||||
def_Type('GOAL', 'Z3_goal', 'GoalObj')
|
||||
def_Type('TACTIC', 'Z3_tactic', 'TacticObj')
|
||||
def_Type('SIMPLIFIER', 'Z3_simplifier', 'SimplifierObj')
|
||||
def_Type('PARAMS', 'Z3_params', 'Params')
|
||||
def_Type('PROBE', 'Z3_probe', 'ProbeObj')
|
||||
def_Type('STATS', 'Z3_stats', 'StatsObj')
|
||||
|
@ -1433,6 +1436,7 @@ Z3_DECLARE_CLOSURE(Z3_eq_eh, void, (void* ctx, Z3_solver_callback cb, Z3_as
|
|||
Z3_DECLARE_CLOSURE(Z3_final_eh, void, (void* ctx, Z3_solver_callback cb));
|
||||
Z3_DECLARE_CLOSURE(Z3_created_eh, void, (void* ctx, Z3_solver_callback cb, Z3_ast t));
|
||||
Z3_DECLARE_CLOSURE(Z3_decide_eh, void, (void* ctx, Z3_solver_callback cb, Z3_ast* t, unsigned* idx, Z3_lbool* phase));
|
||||
Z3_DECLARE_CLOSURE(Z3_on_clause_eh, void, (void* ctx, Z3_ast proof_hint, Z3_ast_vector literals));
|
||||
|
||||
|
||||
/**
|
||||
|
@ -3416,12 +3420,22 @@ extern "C" {
|
|||
|
||||
\sa Z3_mk_numeral
|
||||
\sa Z3_mk_int
|
||||
\sa Z3_mk_real_int64
|
||||
\sa Z3_mk_unsigned_int
|
||||
|
||||
def_API('Z3_mk_real', AST, (_in(CONTEXT), _in(INT), _in(INT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_real(Z3_context c, int num, int den);
|
||||
|
||||
/**
|
||||
\brief Create a real from a fraction of int64.
|
||||
|
||||
\sa Z3_mk_real
|
||||
def_API('Z3_mk_real_int64', AST, (_in(CONTEXT), _in(INT64), _in(INT64)))
|
||||
*/
|
||||
|
||||
Z3_ast Z3_API Z3_mk_real_int64(Z3_context c, int64_t num, int64_t den);
|
||||
|
||||
/**
|
||||
\brief Create a numeral of an int, bit-vector, or finite-domain sort.
|
||||
|
||||
|
@ -3762,7 +3776,7 @@ extern "C" {
|
|||
If \c s does not contain \c substr, then the value is -1,
|
||||
def_API('Z3_mk_seq_last_index', AST, (_in(CONTEXT), _in(AST), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_seq_last_index(Z3_context c, Z3_ast, Z3_ast substr);
|
||||
Z3_ast Z3_API Z3_mk_seq_last_index(Z3_context c, Z3_ast s, Z3_ast substr);
|
||||
|
||||
/**
|
||||
\brief Convert string to integer.
|
||||
|
@ -3892,7 +3906,7 @@ extern "C" {
|
|||
|
||||
def_API('Z3_mk_re_power', AST, (_in(CONTEXT), _in(AST), _in(UINT)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_re_power(Z3_context c, Z3_ast, unsigned n);
|
||||
Z3_ast Z3_API Z3_mk_re_power(Z3_context c, Z3_ast re, unsigned n);
|
||||
|
||||
/**
|
||||
\brief Create the intersection of the regular languages.
|
||||
|
@ -4050,7 +4064,10 @@ extern "C" {
|
|||
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[]);
|
||||
|
||||
/**
|
||||
\brief Create a bound variable.
|
||||
\brief Create a variable.
|
||||
|
||||
Variables are intended to be bound by a scope created by a quantifier. So we call them bound variables
|
||||
even if they appear as free variables in the expression produced by \c Z3_mk_bound.
|
||||
|
||||
Bound variables are indexed by de-Bruijn indices. It is perhaps easiest to explain
|
||||
the meaning of de-Bruijn indices by indicating the compilation process from
|
||||
|
@ -5317,8 +5334,9 @@ extern "C" {
|
|||
Z3_ast const to[]);
|
||||
|
||||
/**
|
||||
\brief Substitute the free variables in \c a with the expressions in \c to.
|
||||
\brief Substitute the variables in \c a with the expressions in \c to.
|
||||
For every \c i smaller than \c num_exprs, the variable with de-Bruijn index \c i is replaced with term \ccode{to[i]}.
|
||||
Note that a variable is created using the function \ref Z3_mk_bound.
|
||||
|
||||
def_API('Z3_substitute_vars', AST, (_in(CONTEXT), _in(AST), _in(UINT), _in_array(2, AST)))
|
||||
*/
|
||||
|
@ -5876,7 +5894,7 @@ extern "C" {
|
|||
def_API('Z3_eval_smtlib2_string', STRING, (_in(CONTEXT), _in(STRING),))
|
||||
*/
|
||||
|
||||
Z3_string Z3_API Z3_eval_smtlib2_string(Z3_context, Z3_string str);
|
||||
Z3_string Z3_API Z3_eval_smtlib2_string(Z3_context c, Z3_string str);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -6192,7 +6210,7 @@ extern "C" {
|
|||
|
||||
/**@}*/
|
||||
|
||||
/** @name Tactics and Probes */
|
||||
/** @name Tactics, Simplifiers and Probes */
|
||||
/**@{*/
|
||||
/**
|
||||
\brief Return a tactic associated with the given name.
|
||||
|
@ -6344,6 +6362,97 @@ extern "C" {
|
|||
*/
|
||||
Z3_tactic Z3_API Z3_tactic_using_params(Z3_context c, Z3_tactic t, Z3_params p);
|
||||
|
||||
|
||||
/**
|
||||
\brief Return a simplifier associated with the given name.
|
||||
The complete list of simplifiers may be obtained using the procedures #Z3_get_num_simplifiers and #Z3_get_simplifier_name.
|
||||
It may also be obtained using the command \ccode{(help-simplifier)} in the SMT 2.0 front-end.
|
||||
|
||||
Simplifiers are the basic building block for creating custom solvers for specific problem domains.
|
||||
|
||||
def_API('Z3_mk_simplifier', SIMPLIFIER, (_in(CONTEXT), _in(STRING)))
|
||||
*/
|
||||
Z3_simplifier Z3_API Z3_mk_simplifier(Z3_context c, Z3_string name);
|
||||
|
||||
/**
|
||||
\brief Increment the reference counter of the given simplifier.
|
||||
|
||||
def_API('Z3_simplifier_inc_ref', VOID, (_in(CONTEXT), _in(SIMPLIFIER)))
|
||||
*/
|
||||
void Z3_API Z3_simplifier_inc_ref(Z3_context c, Z3_simplifier t);
|
||||
|
||||
/**
|
||||
\brief Decrement the reference counter of the given simplifier.
|
||||
|
||||
def_API('Z3_simplifier_dec_ref', VOID, (_in(CONTEXT), _in(SIMPLIFIER)))
|
||||
*/
|
||||
void Z3_API Z3_simplifier_dec_ref(Z3_context c, Z3_simplifier g);
|
||||
|
||||
/**
|
||||
\brief Attach simplifier to a solver. The solver will use the simplifier for incremental pre-processing.
|
||||
|
||||
def_API('Z3_solver_add_simplifier', SOLVER, (_in(CONTEXT), _in(SOLVER), _in(SIMPLIFIER)))
|
||||
*/
|
||||
Z3_solver Z3_API Z3_solver_add_simplifier(Z3_context c, Z3_solver solver, Z3_simplifier simplifier);
|
||||
|
||||
/**
|
||||
\brief Return a simplifier that applies \c t1 to a given goal and \c t2
|
||||
to every subgoal produced by \c t1.
|
||||
|
||||
def_API('Z3_simplifier_and_then', SIMPLIFIER, (_in(CONTEXT), _in(SIMPLIFIER), _in(SIMPLIFIER)))
|
||||
*/
|
||||
Z3_simplifier Z3_API Z3_simplifier_and_then(Z3_context c, Z3_simplifier t1, Z3_simplifier t2);
|
||||
|
||||
/**
|
||||
\brief Return a simplifier that applies \c t using the given set of parameters.
|
||||
|
||||
def_API('Z3_simplifier_using_params', SIMPLIFIER, (_in(CONTEXT), _in(SIMPLIFIER), _in(PARAMS)))
|
||||
*/
|
||||
Z3_simplifier Z3_API Z3_simplifier_using_params(Z3_context c, Z3_simplifier t, Z3_params p);
|
||||
|
||||
|
||||
/**
|
||||
\brief Return the number of builtin simplifiers available in Z3.
|
||||
|
||||
\sa Z3_get_simplifier_name
|
||||
|
||||
def_API('Z3_get_num_simplifiers', UINT, (_in(CONTEXT),))
|
||||
*/
|
||||
unsigned Z3_API Z3_get_num_simplifiers(Z3_context c);
|
||||
|
||||
/**
|
||||
\brief Return the name of the idx simplifier.
|
||||
|
||||
\pre i < Z3_get_num_simplifiers(c)
|
||||
|
||||
\sa Z3_get_num_simplifiers
|
||||
|
||||
def_API('Z3_get_simplifier_name', STRING, (_in(CONTEXT), _in(UINT)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_get_simplifier_name(Z3_context c, unsigned i);
|
||||
|
||||
/**
|
||||
\brief Return a string containing a description of parameters accepted by the given simplifier.
|
||||
|
||||
def_API('Z3_simplifier_get_help', STRING, (_in(CONTEXT), _in(SIMPLIFIER)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_simplifier_get_help(Z3_context c, Z3_simplifier t);
|
||||
|
||||
/**
|
||||
\brief Return the parameter description set for the given simplifier object.
|
||||
|
||||
def_API('Z3_simplifier_get_param_descrs', PARAM_DESCRS, (_in(CONTEXT), _in(SIMPLIFIER)))
|
||||
*/
|
||||
Z3_param_descrs Z3_API Z3_simplifier_get_param_descrs(Z3_context c, Z3_simplifier t);
|
||||
|
||||
/**
|
||||
\brief Return a string containing a description of the simplifier with the given name.
|
||||
|
||||
def_API('Z3_simplifier_get_descr', STRING, (_in(CONTEXT), _in(STRING)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_simplifier_get_descr(Z3_context c, Z3_string name);
|
||||
|
||||
|
||||
/**
|
||||
\brief Return a probe that always evaluates to val.
|
||||
|
||||
|
@ -6877,6 +6986,44 @@ extern "C" {
|
|||
*/
|
||||
void Z3_API Z3_solver_get_levels(Z3_context c, Z3_solver s, Z3_ast_vector literals, unsigned sz, unsigned levels[]);
|
||||
|
||||
/**
|
||||
\brief retrieve the congruence closure root of an expression.
|
||||
The root is retrieved relative to the state where the solver was in when it completed.
|
||||
If it completed during a set of case splits, the congruence roots are relative to these case splits.
|
||||
That is, the congruences are not consequences but they are true under the current state.
|
||||
|
||||
def_API('Z3_solver_congruence_root', AST, (_in(CONTEXT), _in(SOLVER), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_solver_congruence_root(Z3_context c, Z3_solver s, Z3_ast a);
|
||||
|
||||
|
||||
/**
|
||||
\brief retrieve the next expression in the congruence class. The set of congruent siblings form a cyclic list.
|
||||
Repeated calls on the siblings will result in returning to the original expression.
|
||||
|
||||
def_API('Z3_solver_congruence_next', AST, (_in(CONTEXT), _in(SOLVER), _in(AST)))
|
||||
*/
|
||||
Z3_ast Z3_API Z3_solver_congruence_next(Z3_context c, Z3_solver s, Z3_ast a);
|
||||
|
||||
|
||||
/**
|
||||
\brief register a callback to that retrieves assumed, inferred and deleted clauses during search.
|
||||
|
||||
\param c - context.
|
||||
\param s - solver object.
|
||||
\param user_context - a context used to maintain state for callbacks.
|
||||
\param on_clause_eh - a callback that is invoked by when a clause is
|
||||
- asserted to the CDCL engine (corresponding to an input clause after pre-processing)
|
||||
- inferred by CDCL(T) using either a SAT or theory conflict/propagation
|
||||
- deleted by the CDCL(T) engine
|
||||
|
||||
def_API('Z3_solver_register_on_clause', VOID, (_in(CONTEXT), _in(SOLVER), _in(VOID_PTR), _fnptr(Z3_on_clause_eh)))
|
||||
*/
|
||||
void Z3_API Z3_solver_register_on_clause(
|
||||
Z3_context c,
|
||||
Z3_solver s,
|
||||
void* user_context,
|
||||
Z3_on_clause_eh on_clause_eh);
|
||||
|
||||
/**
|
||||
\brief register a user-properator with the solver.
|
||||
|
@ -7006,7 +7153,7 @@ extern "C" {
|
|||
def_API('Z3_solver_propagate_consequence', VOID, (_in(CONTEXT), _in(SOLVER_CALLBACK), _in(UINT), _in_array(2, AST), _in(UINT), _in_array(4, AST), _in_array(4, AST), _in(AST)))
|
||||
*/
|
||||
|
||||
void Z3_API Z3_solver_propagate_consequence(Z3_context c, Z3_solver_callback, unsigned num_fixed, Z3_ast const* fixed, unsigned num_eqs, Z3_ast const* eq_lhs, Z3_ast const* eq_rhs, Z3_ast conseq);
|
||||
void Z3_API Z3_solver_propagate_consequence(Z3_context c, Z3_solver_callback cb, unsigned num_fixed, Z3_ast const* fixed, unsigned num_eqs, Z3_ast const* eq_lhs, Z3_ast const* eq_rhs, Z3_ast conseq);
|
||||
|
||||
/**
|
||||
\brief Check whether the assertions in a given solver are consistent or not.
|
||||
|
|
|
@ -447,12 +447,17 @@ public:
|
|||
app * mk_add(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(arith_family_id, OP_ADD, arg1, arg2, arg3); }
|
||||
app * mk_add(expr_ref_vector const& args) const { return mk_add(args.size(), args.data()); }
|
||||
app * mk_add(expr_ref_buffer const& args) const { return mk_add(args.size(), args.data()); }
|
||||
app * mk_add(ptr_buffer<expr> const& args) const { return mk_add(args.size(), args.data()); }
|
||||
app * mk_add(ptr_vector<expr> const& args) const { return mk_add(args.size(), args.data()); }
|
||||
|
||||
app * mk_sub(expr * arg1, expr * arg2) const { return m_manager.mk_app(arith_family_id, OP_SUB, arg1, arg2); }
|
||||
app * mk_sub(unsigned num_args, expr * const * args) const { return m_manager.mk_app(arith_family_id, OP_SUB, num_args, args); }
|
||||
app * mk_mul(expr * arg1, expr * arg2) const { return m_manager.mk_app(arith_family_id, OP_MUL, arg1, arg2); }
|
||||
app * mk_mul(expr * arg1, expr * arg2, expr* arg3) const { return m_manager.mk_app(arith_family_id, OP_MUL, arg1, arg2, arg3); }
|
||||
app * mk_mul(unsigned num_args, expr * const * args) const { return num_args == 1 && is_app(args[0]) ? to_app(args[0]) : m_manager.mk_app(arith_family_id, OP_MUL, num_args, args); }
|
||||
app * mk_mul(ptr_buffer<expr> const& args) const { return mk_mul(args.size(), args.data()); }
|
||||
app * mk_mul(ptr_vector<expr> const& args) const { return mk_mul(args.size(), args.data()); }
|
||||
app * mk_mul(expr_ref_vector const& args) const { return mk_mul(args.size(), args.data()); }
|
||||
app * mk_uminus(expr * arg) const { return m_manager.mk_app(arith_family_id, OP_UMINUS, arg); }
|
||||
app * mk_div(expr * arg1, expr * arg2) { return m_manager.mk_app(arith_family_id, OP_DIV, arg1, arg2); }
|
||||
app * mk_idiv(expr * arg1, expr * arg2) { return m_manager.mk_app(arith_family_id, OP_IDIV, arg1, arg2); }
|
||||
|
|
|
@ -529,19 +529,6 @@ func_decl * array_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
|
|||
return nullptr;
|
||||
}
|
||||
return mk_array_ext(arity, domain, parameters[0].get_int());
|
||||
case OP_ARRAY_MAXDIFF:
|
||||
case OP_ARRAY_MINDIFF: {
|
||||
if (num_parameters != 0)
|
||||
m_manager->raise_exception("min/maxdiff don't take any parameters");
|
||||
if (arity != 2 || domain[0] != domain[1] || !is_array_sort(domain[0]) || 1 != get_array_arity(domain[0]))
|
||||
m_manager->raise_exception("min/maxdiff don't take two arrays of same sort and with integer index");
|
||||
sort* idx = get_array_domain(domain[0], 0);
|
||||
arith_util arith(*m_manager);
|
||||
if (!arith.is_int(idx))
|
||||
m_manager->raise_exception("min/maxdiff take integer index domain");
|
||||
return m_manager->mk_func_decl(k == OP_ARRAY_MAXDIFF ? symbol("maxdiff") : symbol("mindiff"),
|
||||
arity, domain, arith.mk_int(), func_decl_info(m_family_id, k));
|
||||
}
|
||||
case OP_ARRAY_DEFAULT:
|
||||
return mk_default(arity, domain);
|
||||
case OP_SET_UNION:
|
||||
|
@ -603,9 +590,6 @@ void array_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol con
|
|||
op_names.push_back(builtin_name("as-array", OP_AS_ARRAY));
|
||||
op_names.push_back(builtin_name("array-ext", OP_ARRAY_EXT));
|
||||
|
||||
op_names.push_back(builtin_name("mindiff", OP_ARRAY_MINDIFF));
|
||||
op_names.push_back(builtin_name("maxdiff", OP_ARRAY_MAXDIFF));
|
||||
|
||||
#if 0
|
||||
op_names.push_back(builtin_name("set-has-size", OP_SET_HAS_SIZE));
|
||||
op_names.push_back(builtin_name("card", OP_SET_CARD));
|
||||
|
|
|
@ -45,8 +45,6 @@ enum array_op_kind {
|
|||
OP_ARRAY_EXT,
|
||||
OP_ARRAY_DEFAULT,
|
||||
OP_ARRAY_MAP,
|
||||
OP_ARRAY_MAXDIFF,
|
||||
OP_ARRAY_MINDIFF,
|
||||
OP_SET_UNION,
|
||||
OP_SET_INTERSECT,
|
||||
OP_SET_DIFFERENCE,
|
||||
|
@ -161,8 +159,6 @@ public:
|
|||
bool is_complement(expr* n) const { return is_app_of(n, m_fid, OP_SET_COMPLEMENT); }
|
||||
bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); }
|
||||
bool is_as_array(expr * n, func_decl*& f) const { return is_as_array(n) && (f = get_as_array_func_decl(n), true); }
|
||||
bool is_maxdiff(expr const* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAXDIFF); }
|
||||
bool is_mindiff(expr const* n) const { return is_app_of(n, m_fid, OP_ARRAY_MINDIFF); }
|
||||
bool is_set_has_size(expr* e) const { return is_app_of(e, m_fid, OP_SET_HAS_SIZE); }
|
||||
bool is_set_card(expr* e) const { return is_app_of(e, m_fid, OP_SET_CARD); }
|
||||
bool is_select(func_decl* f) const { return is_decl_of(f, m_fid, OP_SELECT); }
|
||||
|
@ -189,8 +185,6 @@ public:
|
|||
bool is_store_ext(expr* e, expr_ref& a, expr_ref_vector& args, expr_ref& value);
|
||||
|
||||
MATCH_BINARY(is_subset);
|
||||
MATCH_BINARY(is_maxdiff);
|
||||
MATCH_BINARY(is_mindiff);
|
||||
};
|
||||
|
||||
class array_util : public array_recognizers {
|
||||
|
@ -213,6 +207,10 @@ public:
|
|||
return mk_store(args.size(), args.data());
|
||||
}
|
||||
|
||||
app* mk_store(ptr_buffer<expr> const& args) const {
|
||||
return mk_store(args.size(), args.data());
|
||||
}
|
||||
|
||||
app * mk_select(unsigned num_args, expr * const * args) const {
|
||||
return m_manager.mk_app(m_fid, OP_SELECT, 0, nullptr, num_args, args);
|
||||
}
|
||||
|
|
|
@ -856,11 +856,11 @@ func_decl * basic_decl_plugin::mk_proof_decl(basic_op_kind k, unsigned num_paren
|
|||
case PR_MODUS_PONENS_OEQ: return mk_proof_decl("mp~", k, 2, m_mp_oeq_decl);
|
||||
case PR_TH_LEMMA: return mk_proof_decl("th-lemma", k, num_parents, m_th_lemma_decls);
|
||||
case PR_HYPER_RESOLVE: return mk_proof_decl("hyper-res", k, num_parents, m_hyper_res_decl0);
|
||||
case PR_ASSUMPTION_ADD: return mk_proof_decl("add-assume", k, num_parents, m_assumption_add_decl);
|
||||
case PR_LEMMA_ADD: return mk_proof_decl("add-lemma", k, num_parents, m_lemma_add_decl);
|
||||
case PR_TH_ASSUMPTION_ADD: return mk_proof_decl("add-th-assume", k, num_parents, m_th_assumption_add_decl);
|
||||
case PR_TH_LEMMA_ADD: return mk_proof_decl("add-th-lemma", k, num_parents, m_th_lemma_add_decl);
|
||||
case PR_REDUNDANT_DEL: return mk_proof_decl("del-redundant", k, num_parents, m_redundant_del_decl);
|
||||
case PR_ASSUMPTION_ADD: return mk_proof_decl("assume", k, num_parents, m_assumption_add_decl);
|
||||
case PR_LEMMA_ADD: return mk_proof_decl("infer", k, num_parents, m_lemma_add_decl);
|
||||
case PR_TH_ASSUMPTION_ADD: return mk_proof_decl("th-assume", k, num_parents, m_th_assumption_add_decl);
|
||||
case PR_TH_LEMMA_ADD: return mk_proof_decl("th-lemma", k, num_parents, m_th_lemma_add_decl);
|
||||
case PR_REDUNDANT_DEL: return mk_proof_decl("del", k, num_parents, m_redundant_del_decl);
|
||||
case PR_CLAUSE_TRAIL: return mk_proof_decl("proof-trail", k, num_parents, false);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
|
@ -1673,6 +1673,7 @@ bool ast_manager::are_distinct(expr* a, expr* b) const {
|
|||
}
|
||||
|
||||
void ast_manager::add_lambda_def(func_decl* f, quantifier* q) {
|
||||
TRACE("model", tout << "add lambda def " << mk_pp(q, *this) << "\n");
|
||||
m_lambda_defs.insert(f, q);
|
||||
f->get_info()->set_lambda(true);
|
||||
inc_ref(q);
|
||||
|
@ -1969,6 +1970,14 @@ app * ast_manager::mk_app(family_id fid, decl_kind k, expr * arg1, expr * arg2,
|
|||
return mk_app(fid, k, 0, nullptr, 3, args);
|
||||
}
|
||||
|
||||
app * ast_manager::mk_app(symbol const& name, unsigned n, expr* const* args, sort* range) {
|
||||
ptr_buffer<sort> sorts;
|
||||
for (unsigned i = 0; i < n; ++i)
|
||||
sorts.push_back(args[i]->get_sort());
|
||||
return mk_app(mk_func_decl(name, n, sorts.data(), range), n, args);
|
||||
}
|
||||
|
||||
|
||||
sort * ast_manager::mk_sort(symbol const & name, sort_info * info) {
|
||||
unsigned sz = sort::get_obj_size();
|
||||
void * mem = allocate_node(sz);
|
||||
|
@ -2242,7 +2251,9 @@ app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * ar
|
|||
if (type_error) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "Wrong number of arguments (" << num_args
|
||||
<< ") passed to function " << mk_pp(decl, *this);
|
||||
<< ") passed to function " << mk_pp(decl, *this) << " ";
|
||||
for (unsigned i = 0; i < num_args; ++i)
|
||||
buffer << "\narg: " << mk_pp(args[i], *this) << "\n";
|
||||
throw ast_exception(std::move(buffer).str());
|
||||
}
|
||||
app * r = nullptr;
|
||||
|
|
|
@ -731,6 +731,8 @@ public:
|
|||
unsigned get_num_args() const { return m_num_args; }
|
||||
expr * get_arg(unsigned idx) const { SASSERT(idx < m_num_args); return m_args[idx]; }
|
||||
expr * const * get_args() const { return m_args; }
|
||||
std::tuple<expr*,expr*> args2() const { SASSERT(m_num_args == 2); return {get_arg(0), get_arg(1)}; }
|
||||
std::tuple<expr*,expr*,expr*> args3() const { SASSERT(m_num_args == 3); return {get_arg(0), get_arg(1), get_arg(2)}; }
|
||||
unsigned get_size() const { return get_obj_size(get_num_args()); }
|
||||
expr * const * begin() const { return m_args; }
|
||||
expr * const * end() const { return m_args + m_num_args; }
|
||||
|
@ -1385,6 +1387,7 @@ inline bool is_app_of(expr const * n, family_id fid, decl_kind k) { return n->ge
|
|||
inline bool is_sort_of(sort const * s, family_id fid, decl_kind k) { return s->is_sort_of(fid, k); }
|
||||
inline bool is_uninterp_const(expr const * n) { return n->get_kind() == AST_APP && to_app(n)->get_num_args() == 0 && to_app(n)->get_family_id() == null_family_id; }
|
||||
inline bool is_uninterp(expr const * n) { return n->get_kind() == AST_APP && to_app(n)->get_family_id() == null_family_id; }
|
||||
inline bool is_uninterp(func_decl const * n) { return n->get_family_id() == null_family_id; }
|
||||
inline bool is_decl_of(func_decl const * d, family_id fid, decl_kind k) { return d->get_family_id() == fid && d->get_decl_kind() == k; }
|
||||
inline bool is_ground(expr const * n) { return is_app(n) && to_app(n)->is_ground(); }
|
||||
inline bool is_non_ground(expr const * n) { return ( ! is_ground(n)); }
|
||||
|
@ -1628,6 +1631,7 @@ public:
|
|||
void add_lambda_def(func_decl* f, quantifier* q);
|
||||
quantifier* is_lambda_def(func_decl* f);
|
||||
quantifier* is_lambda_def(app* e) { return is_lambda_def(e->get_decl()); }
|
||||
obj_map<func_decl, quantifier*> const& lambda_defs() const { return m_lambda_defs; }
|
||||
|
||||
symbol const& lambda_def_qid() const { return m_lambda_def; }
|
||||
|
||||
|
@ -1881,6 +1885,8 @@ public:
|
|||
return mk_app(decl, 3, args);
|
||||
}
|
||||
|
||||
app * mk_app(symbol const& name, unsigned n, expr* const* args, sort* range);
|
||||
|
||||
app * mk_const(func_decl * decl) {
|
||||
SASSERT(decl->get_arity() == 0);
|
||||
return mk_app(decl, static_cast<unsigned>(0), static_cast<expr**>(nullptr));
|
||||
|
|
|
@ -86,6 +86,7 @@ class ll_printer {
|
|||
default:
|
||||
display_child_ref(n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
|
@ -64,6 +64,17 @@ void ast_pp_util::display_decls(std::ostream& out) {
|
|||
m_rec_decls = n;
|
||||
}
|
||||
|
||||
void ast_pp_util::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 ast_pp_util::display_skolem_decls(std::ostream& out) {
|
||||
ast_smt_pp pp(m);
|
||||
unsigned n = coll.get_num_decls();
|
||||
|
|
|
@ -40,8 +40,7 @@ class ast_pp_util {
|
|||
|
||||
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) {}
|
||||
|
||||
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 reset();
|
||||
|
||||
void collect(expr* e);
|
||||
|
||||
|
|
|
@ -561,15 +561,18 @@ class smt2_printer {
|
|||
|
||||
void pp_var(var * v) {
|
||||
format * f;
|
||||
if (v->get_idx() < m_var_names.size()) {
|
||||
symbol s = m_var_names[m_var_names.size() - v->get_idx() - 1];
|
||||
unsigned idx = v->get_idx();
|
||||
if (idx < m_var_names.size()) {
|
||||
symbol s;
|
||||
if (m_reverse && idx < m_arity)
|
||||
s = m_var_names[m_var_names.size() - m_arity + idx];
|
||||
else
|
||||
s = m_var_names[m_var_names.size() - idx - 1];
|
||||
std::string vname;
|
||||
if (is_smt2_quoted_symbol (s)) {
|
||||
vname = mk_smt2_quoted_symbol (s);
|
||||
}
|
||||
else {
|
||||
vname = s.str();
|
||||
}
|
||||
if (is_smt2_quoted_symbol (s))
|
||||
vname = mk_smt2_quoted_symbol (s);
|
||||
else
|
||||
vname = s.str();
|
||||
f = mk_string(m(), vname);
|
||||
}
|
||||
else {
|
||||
|
@ -1139,9 +1142,13 @@ public:
|
|||
r = mk_seq1<format**, f2f>(m(), args, args+3, f2f(), cmd);
|
||||
}
|
||||
|
||||
bool m_reverse = false;
|
||||
unsigned m_arity = 0;
|
||||
|
||||
void operator()(func_decl * f, expr * e, format_ref & r, char const* cmd) {
|
||||
void operator()(func_decl * f, expr * e, format_ref & r, char const* cmd, bool reverse) {
|
||||
unsigned len;
|
||||
flet<bool> _reverse(m_reverse, reverse);
|
||||
m_arity = f->get_arity();
|
||||
format * fname = m_env.pp_fdecl_name(f, len);
|
||||
register_var_names(f->get_arity());
|
||||
format * args[4];
|
||||
|
@ -1202,9 +1209,9 @@ void mk_smt2_format(func_decl * f, smt2_pp_environment & env, params_ref const &
|
|||
pr(f, r, cmd);
|
||||
}
|
||||
|
||||
void mk_smt2_format(func_decl * f, expr * e, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd) {
|
||||
void mk_smt2_format(func_decl * f, expr * e, smt2_pp_environment & env, params_ref const & p, format_ref & r, char const* cmd, bool reverse) {
|
||||
smt2_printer pr(env, p);
|
||||
pr(f, e, r, cmd);
|
||||
pr(f, e, r, cmd, reverse);
|
||||
}
|
||||
|
||||
void mk_smt2_format(unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p,
|
||||
|
@ -1251,7 +1258,6 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen
|
|||
if (!f) return out << "null";
|
||||
ast_manager & m = env.get_manager();
|
||||
format_ref r(fm(m));
|
||||
sbuffer<symbol> var_names;
|
||||
mk_smt2_format(f, env, p, r, cmd);
|
||||
if (indent > 0)
|
||||
r = mk_indent(m, indent, r.get());
|
||||
|
@ -1259,18 +1265,25 @@ std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environmen
|
|||
return out;
|
||||
}
|
||||
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
|
||||
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd, bool reverse) {
|
||||
if (!f) return out << "null";
|
||||
ast_manager & m = env.get_manager();
|
||||
format_ref r(fm(m));
|
||||
sbuffer<symbol> var_names;
|
||||
mk_smt2_format(f, e, env, p, r, cmd);
|
||||
mk_smt2_format(f, e, env, p, r, cmd, reverse);
|
||||
if (indent > 0)
|
||||
r = mk_indent(m, indent, r.get());
|
||||
pp(out, r.get(), m, p);
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
|
||||
return ast_smt2_pp(out, f, e, env, p, indent, cmd, false);
|
||||
}
|
||||
|
||||
std::ostream & ast_smt2_pp_rev(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p, unsigned indent, char const* cmd) {
|
||||
return ast_smt2_pp(out, f, e, env, p, indent, cmd, true);
|
||||
}
|
||||
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, unsigned sz, expr * const* es, smt2_pp_environment & env, params_ref const & p, unsigned indent,
|
||||
unsigned num_vars, char const * var_prefix) {
|
||||
|
|
|
@ -104,7 +104,8 @@ std::ostream & ast_smt2_pp(std::ostream & out, expr * n, smt2_pp_environment & e
|
|||
unsigned num_vars = 0, char const * var_prefix = nullptr);
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, sort * s, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0);
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "declare-fun");
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "define-fun");
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "define-fun", bool reverse = false);
|
||||
std::ostream & ast_smt2_pp_rev(std::ostream & out, func_decl * f, expr* e, smt2_pp_environment & env, params_ref const & p = params_ref(), unsigned indent = 0, char const* cmd = "define-fun");
|
||||
std::ostream & ast_smt2_pp(std::ostream & out, symbol const& s, bool is_skolem, smt2_pp_environment & env, params_ref const& p = params_ref());
|
||||
std::ostream & ast_smt2_pp_recdefs(std::ostream & out, vector<std::pair<func_decl*, expr*>> const& funs, smt2_pp_environment & env, params_ref const & p = params_ref());
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@ expr * get_clause_literal(ast_manager & m, expr * cls, unsigned idx);
|
|||
*/
|
||||
expr * mk_and(ast_manager & m, unsigned num_args, expr * const * args);
|
||||
app * mk_and(ast_manager & m, unsigned num_args, app * const * args);
|
||||
inline expr * mk_and(ast_manager & m, ptr_vector<expr> const& args) { return mk_and(m, args.size(), args.data()); }
|
||||
inline expr * mk_and(ast_manager & m, ptr_buffer<expr> const& args) { return mk_and(m, args.size(), args.data()); }
|
||||
inline expr * mk_and(ast_manager & m, expr* a, expr* b) { expr* args[2] = { a, b }; return mk_and(m, 2, args); }
|
||||
inline app_ref mk_and(app_ref_vector const& args) { return app_ref(mk_and(args.get_manager(), args.size(), args.data()), args.get_manager()); }
|
||||
inline expr_ref mk_and(expr_ref_vector const& args) { return expr_ref(mk_and(args.get_manager(), args.size(), args.data()), args.get_manager()); }
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue