mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-04 13:29:11 +00:00 
			
		
		
		
	Added ml component
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
		
							parent
							
								
									454fa7dcdd
								
							
						
					
					
						commit
						bcca613cb2
					
				
					 60 changed files with 40332 additions and 16 deletions
				
			
		
							
								
								
									
										2
									
								
								ml/add_error_checking.V3.sed
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								ml/add_error_checking.V3.sed
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,2 @@
 | 
				
			||||||
 | 
					# Customize error handling for contexts created in ML:
 | 
				
			||||||
 | 
					s/Z3_API Z3_mk_context\(_rc\|\)(\(.*\))/Z3_API Z3_mk_context\1(\2) quote(dealloc,\"Z3_set_error_handler(_res, caml_z3_error_handler);\")/g
 | 
				
			||||||
							
								
								
									
										86
									
								
								ml/add_error_checking.sed
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								ml/add_error_checking.sed
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,86 @@
 | 
				
			||||||
 | 
					# Do not add epilogue to Z3_del_context
 | 
				
			||||||
 | 
					/Z3_API .*Z3_del_context.*/b endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add error checking epilogue for all Z3_API functions that accept two Z3_contexts
 | 
				
			||||||
 | 
					:begincc
 | 
				
			||||||
 | 
					# add epilogue for two Z3_context parameters
 | 
				
			||||||
 | 
					s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3);\")\7/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if a match was found, done with all Z3_contexts and Z3_theorys
 | 
				
			||||||
 | 
					t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if complete prototype, done with two Z3_contexts
 | 
				
			||||||
 | 
					/Z3_API .*(.*)\(;\|\)[ 	  ]*$/b endcc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if incomplete prototype
 | 
				
			||||||
 | 
					/Z3_API .*(.*/{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # read another line
 | 
				
			||||||
 | 
					  N
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # add epilogue for two Z3_context parameters
 | 
				
			||||||
 | 
					  s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_context \3\4Z3_context \5\6) quote(dealloc,\"check_error_code(\3); check_error_code(\5);\")\7/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # if a match was found, done with all Z3_contexts and Z3_theorys
 | 
				
			||||||
 | 
					  t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # else keep looking for two Z3_contexts
 | 
				
			||||||
 | 
					  b begincc
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					:endcc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add error checking epilogue for all Z3_API functions that accept one Z3_context
 | 
				
			||||||
 | 
					:beginc
 | 
				
			||||||
 | 
					# add epilogue for one Z3_context parameter
 | 
				
			||||||
 | 
					s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if a match was found, done with all Z3_contexts and Z3_theorys
 | 
				
			||||||
 | 
					t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if complete prototype, done with all Z3_contexts
 | 
				
			||||||
 | 
					/Z3_API .*(.*)\(;\|\)[ 	  ]*$/b endc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if incomplete prototype
 | 
				
			||||||
 | 
					/Z3_API .*(.*/{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # read another line
 | 
				
			||||||
 | 
					  N
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # add epilogue for one Z3_context parameter
 | 
				
			||||||
 | 
					  s/Z3_API \(.*\)(\(.*\)Z3_context \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_context \3\4) quote(dealloc,\"check_error_code(\3);\")\5/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # if a match was found, done with all Z3_contexts and Z3_theorys
 | 
				
			||||||
 | 
					  t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # else keep looking for one Z3_context
 | 
				
			||||||
 | 
					  b beginc
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					:endc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Add error checking epilogue for all Z3_API functions that accept a Z3_theory
 | 
				
			||||||
 | 
					:begint
 | 
				
			||||||
 | 
					# add epilogue for one Z3_theory parameter
 | 
				
			||||||
 | 
					s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if a match was found, done with all Z3_contexts and Z3_theorys
 | 
				
			||||||
 | 
					t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# if complete prototype, done with all Z3_theorys
 | 
				
			||||||
 | 
					/Z3_API .*(.*)\(;\|\)[ 	  ]*$/b endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/Z3_API .*(.*/{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # read another line
 | 
				
			||||||
 | 
					  N
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # add epilogue for one Z3_theory parameter
 | 
				
			||||||
 | 
					  s/Z3_API \(.*\)(\(.*\)Z3_theory \([a-zA-Z]*\)\([^a-zA-Z].*\|\))\(;\|\)[ 	  ]*$/Z3_API \1(\2Z3_theory \3\4) quote(dealloc,\"check_error_code(Z3_theory_get_context(\3));\")\5/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # if a match was found, done with all Z3_theorys
 | 
				
			||||||
 | 
					  t endt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # else keep looking for one Z3_theory
 | 
				
			||||||
 | 
					  b begint
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					:endt
 | 
				
			||||||
							
								
								
									
										55
									
								
								ml/build.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ml/build.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					SETLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to generate, compile, test, and document the Z3 OCaml API
 | 
				
			||||||
 | 
					REM usage: build.cmd [32|64] [-D UNSAFE_ERRORS] [-D LEAK_CONTEXTS]
 | 
				
			||||||
 | 
					REM Invoke with "-D UNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead.
 | 
				
			||||||
 | 
					REM Invoke with "-D LEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if ""%1 == "" (
 | 
				
			||||||
 | 
					  set BITS=32
 | 
				
			||||||
 | 
					) else (
 | 
				
			||||||
 | 
					  set BITS=%1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if %BITS% == 32 (
 | 
				
			||||||
 | 
					  set ARCH=x86
 | 
				
			||||||
 | 
					  set Z3BIN= ..\external
 | 
				
			||||||
 | 
					  set Z3DBG= ..\debug
 | 
				
			||||||
 | 
					) else (
 | 
				
			||||||
 | 
					  set ARCH=x64
 | 
				
			||||||
 | 
					  set Z3BIN= ..\x64\external_64
 | 
				
			||||||
 | 
					  set Z3DBG= ..\x64\Debug
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Setting up environment
 | 
				
			||||||
 | 
					call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" %ARCH%
 | 
				
			||||||
 | 
					call ..\tools\ocaml\win%BITS%\setup.cmd
 | 
				
			||||||
 | 
					set PATH=..\tools;..\mlV3;%PATH%
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Cleaning
 | 
				
			||||||
 | 
					call .\clean.cmd
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Generating OCaml API %3 %5
 | 
				
			||||||
 | 
					call .\generate_mlapi.cmd %2 %3 %4 %5
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Compiling OCaml API
 | 
				
			||||||
 | 
					call .\compile_mlapi.cmd ..\lib %Z3BIN% %Z3DBG%
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Testing OCaml API
 | 
				
			||||||
 | 
					call .\test_mlapi.cmd ..\lib %Z3BIN% %Z3DBG%
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo { Generating OCaml API documentation
 | 
				
			||||||
 | 
					call .\update-ml-doc.cmd ..\doc
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					echo }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENDLOCAL
 | 
				
			||||||
							
								
								
									
										82
									
								
								ml/build.sed
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								ml/build.sed
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					# attempt to clean up the mess with 'unsigned'
 | 
				
			||||||
 | 
					s/__in unsigned __/__in __/g
 | 
				
			||||||
 | 
					s/__out unsigned __/__out __/g
 | 
				
			||||||
 | 
					s/__out_opt unsigned __/__out_opt __/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '@name ' -> 'Section: '
 | 
				
			||||||
 | 
					# '\sa ' -> 'See also: '
 | 
				
			||||||
 | 
					# '\brief '   -> 'Summary:  '
 | 
				
			||||||
 | 
					# '\remark ' -> 'Remark: '
 | 
				
			||||||
 | 
					# '\pre '     -> 'Precondition: '
 | 
				
			||||||
 | 
					# '\param '   -> '@param'
 | 
				
			||||||
 | 
					# '\warning ' -> 'Warning: '
 | 
				
			||||||
 | 
					# '\code' -> 'C Example:'
 | 
				
			||||||
 | 
					# '\endcode' -> ''
 | 
				
			||||||
 | 
					/\\pre/s/(/ /g;/\\pre/s/,//g;/\\pre/s/)//g;s/\\pre /- {b Precondition}: /g
 | 
				
			||||||
 | 
					/\\ccode/s/(/ /g;/\\ccode/s/\\,//g;/\\ccode/s/)//g;s/\\ccode{\(.*\)}/\[\1\]/g
 | 
				
			||||||
 | 
					s/\\defgroup .*//g
 | 
				
			||||||
 | 
					s/@name \(.*\)/{2 {L \1}}/g
 | 
				
			||||||
 | 
					s/\\sa \(.*\)/- {b See also}: {!Z3.\1}/g
 | 
				
			||||||
 | 
					s/\\see \(.*\)/- {b See}: {!Z3.\1}/g
 | 
				
			||||||
 | 
					s/<tt>/{e /g
 | 
				
			||||||
 | 
					s|</tt>| }|g
 | 
				
			||||||
 | 
					s/\\nicebox{/{e/g
 | 
				
			||||||
 | 
					s/\\brief /Summary: /g
 | 
				
			||||||
 | 
					s/\\remark /- {b Remarks}: /g
 | 
				
			||||||
 | 
					s/\\pre /- {b Precondition}: /g
 | 
				
			||||||
 | 
					s/\\param /@param /g
 | 
				
			||||||
 | 
					s/\\conly .*//g
 | 
				
			||||||
 | 
					s/\\warning /- {b Warning}: /g
 | 
				
			||||||
 | 
					s/\\code/{v /g
 | 
				
			||||||
 | 
					s/\\endcode/ v}/g
 | 
				
			||||||
 | 
					s/\\verbatim/{v /g
 | 
				
			||||||
 | 
					s/\\endverbatim/ v}/g
 | 
				
			||||||
 | 
					s/\\mlonly//g
 | 
				
			||||||
 | 
					s/\\endmlonly//g
 | 
				
			||||||
 | 
					s/\\mlh/\\\[ \[/g
 | 
				
			||||||
 | 
					s/\\endmlh/\] \\\]/g
 | 
				
			||||||
 | 
					s/\\deprecated/@deprecated/g
 | 
				
			||||||
 | 
					s/\\ / /g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '\c code ' -> '[code]'
 | 
				
			||||||
 | 
					s/\\c \([^ .,:]*\)/[\1]/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '#Z3_' -> 'Z3.'
 | 
				
			||||||
 | 
					s/#Z3_\([^ \n\.\t,)]*\)/{!Z3.\1}/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '/*@}*/' -> ''
 | 
				
			||||||
 | 
					s/\/\*@{\*\///g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '/*@{*/' -> ''
 | 
				
			||||||
 | 
					s/\/\*@}\*\///g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '/*...*/' -> ''
 | 
				
			||||||
 | 
					s/\/\*.*\*\///g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s|(\*\*/\*\*)|(\*\*%\*\*)|g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '/**' -> 'quote(mli,"(**'
 | 
				
			||||||
 | 
					s|/\*\*|quote(mli,\"(**|g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '...*/' -> '*)");'
 | 
				
			||||||
 | 
					s|[ 	  ]*\*/|*)\");|g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					s|(\*\*%\*\*)|(\*\*/\*\*)|g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 'extern "C"' -> 'extern ~~C~~'
 | 
				
			||||||
 | 
					# 'quote(foo,"bar")' -> quote(foo,~~bar~~)
 | 
				
			||||||
 | 
					# mltype("foo") -> mltype(~~foo~~)
 | 
				
			||||||
 | 
					s/extern \"C\"/extern ~~C~~/g
 | 
				
			||||||
 | 
					s/quote(\(.*\),\"\(.*\)\")/quote(\1,~~\2~~)/g
 | 
				
			||||||
 | 
					s/quote(\(.*\),\"/quote(\1,~~/g
 | 
				
			||||||
 | 
					s/\")\;/~~);/g
 | 
				
			||||||
 | 
					s/\;\"/;~~/g
 | 
				
			||||||
 | 
					s/mltype(\"\(.*\)\")/mltype(~~\1~~)/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '"' -> '\"'
 | 
				
			||||||
 | 
					s/\\\"/\"/g
 | 
				
			||||||
 | 
					s/\"/\\\"/g
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# '~~' -> '"'
 | 
				
			||||||
 | 
					s/~~/\"/g
 | 
				
			||||||
							
								
								
									
										13
									
								
								ml/clean.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								ml/clean.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to delete generated Z3 OCaml API files
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call .\cleantmp.cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM files produced by generate_mlapi.cmd
 | 
				
			||||||
 | 
					del /q 2>NUL z3_stubs.c z3.mli z3.ml z3V3_stubs.*.c z3V3.*.mli z3V3.*.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM files produced by update-ml-doc.cmd
 | 
				
			||||||
 | 
					rd 2>NUL /s /q doc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit /B 0
 | 
				
			||||||
							
								
								
									
										15
									
								
								ml/cleantmp.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								ml/cleantmp.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to delete intermediate temporary files from generating Z3 OCaml API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM files produced by generate_mlapi.cmd
 | 
				
			||||||
 | 
					del /q 2>NUL z3_api.idl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM files produced by compile_mlapi.cmd
 | 
				
			||||||
 | 
					del /q 2>NUL *.cmi *.cmo *.cmx *.cma *.cmxa *.obj *.lib *.pdb ocamlz3.exe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM files produced by test_mlapi.cmd
 | 
				
			||||||
 | 
					del /q 2>NUL test*.exe queen*.exe test_*api.out test_*apiV3.out test_*api.err test_*apiV3.err queen.out queen.err z3.log ml.log test_mlapi.log
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM backup files
 | 
				
			||||||
 | 
					del /q 2>NUL *~
 | 
				
			||||||
							
								
								
									
										95
									
								
								ml/compile_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								ml/compile_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,95 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					SETLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to compile the Z3 OCaml API
 | 
				
			||||||
 | 
					REM Compiles byte and debug native code versions with debug info, optimized native code versions without
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing z3_api.h
 | 
				
			||||||
 | 
					set Z3SRC=%1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing z3.dll
 | 
				
			||||||
 | 
					set Z3BIN=%2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing debug z3.dll
 | 
				
			||||||
 | 
					set Z3BINDBG=%3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM link Z3 statically or dynamically
 | 
				
			||||||
 | 
					set STATIC=false
 | 
				
			||||||
 | 
					REM set STATIC=true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if %STATIC% == true (
 | 
				
			||||||
 | 
					    set Z3LIB=z3lib.lib
 | 
				
			||||||
 | 
					    set Z3DBGLIB=z3lib.lib
 | 
				
			||||||
 | 
					) else (
 | 
				
			||||||
 | 
					    set Z3LIB=z3.lib
 | 
				
			||||||
 | 
					    set Z3DBGLIB=z3_dbg.lib
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM ocaml 3.11 and later calls the linker through flexlink
 | 
				
			||||||
 | 
					ocamlc -version >> ocaml_version
 | 
				
			||||||
 | 
					set /p OCAML_VERSION= <ocaml_version
 | 
				
			||||||
 | 
					del ocaml_version
 | 
				
			||||||
 | 
					if %OCAML_VERSION% GEQ 3.11 (
 | 
				
			||||||
 | 
					    set XCFLAGS=
 | 
				
			||||||
 | 
					) else (
 | 
				
			||||||
 | 
					    REM add /MT if building the multithreaded version
 | 
				
			||||||
 | 
					    set XCFLAGS=/nologo /DWIN32
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set XINCLUDE=-ccopt -I%Z3SRC%
 | 
				
			||||||
 | 
					set XLIBPATH=/LIBPATH:%Z3BIN%
 | 
				
			||||||
 | 
					set XCDBG=-g %XCFLAGS% %XINCLUDE%
 | 
				
			||||||
 | 
					set XCOPT=-ccopt /Ox -ccopt /Oy- %XCFLAGS% %XINCLUDE%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -> DBG z3_stubs.obj z3.{cmi,cmo,obj}
 | 
				
			||||||
 | 
					ocamlc -c %XCDBG% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -> DBG z3_stubs.obj z3.{cmi,cmx,obj}
 | 
				
			||||||
 | 
					ocamlopt -c %XCDBG% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM %Z3DBGLIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -> libz3_dbg.lib:
 | 
				
			||||||
 | 
					lib /nologo %XLIBPATH% /out:libz3_dbg.lib %Z3BINDBG%\%Z3DBGLIB% z3.obj z3_stubs.obj z3_theory_stubs.obj
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM z3_stubs.c z3_theory_stubs.c z3.mli z3.ml -> OPT z3_stubs.obj z3.{cmi,cmx,obj}
 | 
				
			||||||
 | 
					ocamlopt -c %XCOPT% z3_stubs.c z3_theory_stubs.c z3.mli z3.ml
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM %Z3LIB% z3.obj z3_stubs.obj z3_theory_stubs.obj -> libz3.lib:
 | 
				
			||||||
 | 
					lib /nologo %XLIBPATH% /out:libz3.lib %Z3BIN%\%Z3LIB% z3.obj z3_stubs.obj z3_theory_stubs.obj
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM ole32.lib is needed by camlidl
 | 
				
			||||||
 | 
					REM camlidl.lib is the runtime library for camlidl
 | 
				
			||||||
 | 
					REM psapi.lib is needed when statically linking Z3 for process statistics functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM libz3_dbg.lib ole32.lib camlidl.lib z3.cmo -> z3_dbg.cma
 | 
				
			||||||
 | 
					ocamlc -custom -a %XCDBG% -cclib -L"%CD%\..\bin" -cclib -lz3_dbg -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmo -o z3_dbg.cma
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM libz3.lib ole32.lib camlidl.lib z3.cmo -> z3.cma
 | 
				
			||||||
 | 
					ocamlc -custom -a -cclib -L"%CD%\..\bin" -cclib -lz3 -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmo -o z3.cma
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM libz3_dbg.lib ole32.lib camlidl.lib z3.cmx -> z3_dbg.cmxa
 | 
				
			||||||
 | 
					ocamlopt -a -cclib -L"%CD%\..\bin" -cclib -lz3_dbg -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmx -o z3_dbg.cmxa
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM libz3.lib ole32.lib camlidl.lib z3.cmx -> z3.cmxa
 | 
				
			||||||
 | 
					ocamlopt -a -cclib -L"%CD%\..\bin" -cclib -lz3 -cclib ole32.lib -cclib -lcamlidl -cclib psapi.lib z3.cmx -o z3.cmxa
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM build OCaml toplevel 'ocamlz3' pre-linked with Z3
 | 
				
			||||||
 | 
					ocamlmktop -o ocamlz3 z3.cma
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					del /q 2>NUL z3.cmo z3.cmx *.obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENDLOCAL
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ml/diff.exe
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ml/diff.exe
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										162
									
								
								ml/error_handling.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										162
									
								
								ml/error_handling.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,162 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error_handling
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Error handling in the OCaml API for Z3.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The wrapper of each Z3 API routine that takes a Z3_context or a Z3_theory
 | 
				
			||||||
 | 
					    argument calls check_error_code before returning.  (These calls are added
 | 
				
			||||||
 | 
					    in generate_mlapi.cmd using the build.sed script.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    There are two error handling schemes implemented, depending on whether
 | 
				
			||||||
 | 
					    (UN)SAFE_ERRORS is set.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - SAFE_ERRORS checks Z3_error_code after each call and raises an OCaml
 | 
				
			||||||
 | 
					      exception in error conditions.  Z3_set_error_handler is not exposed by
 | 
				
			||||||
 | 
					      the SAFE_ERRORS version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - UNSAFE_ERRORS sets a Z3 error handler routine that either calls a
 | 
				
			||||||
 | 
					      globally registered OCaml function or, by default, raises an OCaml
 | 
				
			||||||
 | 
					      exception.  This avoids overhead of repeatedly checking
 | 
				
			||||||
 | 
					      Z3_get_error_code, but leaves Z3 in a broken state.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The current SAFE_ERRORS implementation interacts badly with theory plugin
 | 
				
			||||||
 | 
					    callbacks.  Z3 errors are converted into OCaml exceptions, which the
 | 
				
			||||||
 | 
					    wrappers of theory plugin callbacks are not expecting.  Therefore, if a
 | 
				
			||||||
 | 
					    theory plugin calls a Z3 API routine that triggers an error, an OCaml
 | 
				
			||||||
 | 
					    exception will be raised and bypass any C++ destructors pushed onto the
 | 
				
			||||||
 | 
					    stack by Z3 before the call to the plugin and after the preceding OCaml
 | 
				
			||||||
 | 
					    exception handler.  One solution to this would be to modify the theory
 | 
				
			||||||
 | 
					    plugin callback registration functions to wrap callbacks in an OCaml
 | 
				
			||||||
 | 
					    exception handler.  Since OCaml exceptions are cheap to raise at the
 | 
				
			||||||
 | 
					    expense of some cost to install a handler, this may not be desirable.
 | 
				
			||||||
 | 
					    Another solution would be to modify check_error_code to detect if it is
 | 
				
			||||||
 | 
					    executing in a plugin callback and simply maintain the Z3_error_code, or
 | 
				
			||||||
 | 
					    raise a C++ exception, instead of raising an OCaml exception.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Josh Berdine (jjb) 2012-03-21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if !defined(UNSAFE_ERRORS) && !defined(SAFE_ERRORS)
 | 
				
			||||||
 | 
					#define SAFE_ERRORS
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef SAFE_ERRORS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(** Exceptions raised by Z3. It is safe to continue interacting with Z3 after
 | 
				
			||||||
 | 
					    catching [Error] exceptions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - {b See also}: {!get_error_msg}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					exception Error of context * error_code
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					quote(ml,"
 | 
				
			||||||
 | 
					/* Register dynamically-generated exception tag for use from C */
 | 
				
			||||||
 | 
					let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK))
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"
 | 
				
			||||||
 | 
					value camlidl_c2ml_z3_Z3_error_code(Z3_error_code * _c2, camlidl_ctx _ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Error checking routine that raises OCaml Error exceptions */
 | 
				
			||||||
 | 
					void check_error_code (Z3_context c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
 | 
				
			||||||
 | 
					  value* exn_tag = NULL;
 | 
				
			||||||
 | 
					  value ctx_err[2];
 | 
				
			||||||
 | 
					  Z3_error_code e;
 | 
				
			||||||
 | 
					  e = Z3_get_error_code(c);
 | 
				
			||||||
 | 
					  if (e != Z3_OK) {
 | 
				
			||||||
 | 
					    ctx_err[0] = c2ml_Z3_context(&c);
 | 
				
			||||||
 | 
					    ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs);
 | 
				
			||||||
 | 
					    exn_tag = caml_named_value(\"Z3.Error\");
 | 
				
			||||||
 | 
					    if (*exn_tag == 0) {
 | 
				
			||||||
 | 
					      fprintf(stderr, \"Z3.Error not found\");
 | 
				
			||||||
 | 
					      exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    caml_raise_with_args(*exn_tag, 2, ctx_err);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Disable default error handler, all error checking is done by check_error_code */
 | 
				
			||||||
 | 
					void* error_handler_static = NULL;
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(** Exceptions raised by Z3.  {b Warning}: It is unsafe to continue
 | 
				
			||||||
 | 
					    interacting with Z3 after catching [Error] exceptions. To recover from
 | 
				
			||||||
 | 
					    error conditions, use {!set_error_handler} to set an error handler that
 | 
				
			||||||
 | 
					    does nothing, and then test {!get_error_code} after every call to Z3.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - {b See also}: {!get_error_msg}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					exception Error of context * error_code
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					quote(ml,"
 | 
				
			||||||
 | 
					/* Register dynamically-generated exception tag for use from C */
 | 
				
			||||||
 | 
					let _ = Callback.register_exception \"Z3.Error\" (Error (Obj.magic None, OK))
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"
 | 
				
			||||||
 | 
					/* Error checking routine that does nothing */
 | 
				
			||||||
 | 
					void check_error_code(Z3_context c) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* All contexts share the same handler */
 | 
				
			||||||
 | 
					static value caml_error_handler = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void error_handler_static (Z3_context c, Z3_error_code e)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  static struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
 | 
				
			||||||
 | 
					  value* exn_tag = NULL;
 | 
				
			||||||
 | 
					  value ctx_err[2];
 | 
				
			||||||
 | 
					  ctx_err[0] = c2ml_Z3_context(&c);
 | 
				
			||||||
 | 
					  ctx_err[1] = camlidl_c2ml_z3_Z3_error_code(&e, &_ctxs);
 | 
				
			||||||
 | 
					  if (caml_error_handler) {
 | 
				
			||||||
 | 
					    caml_callback2(caml_error_handler, ctx_err[0], ctx_err[1]);
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    /* if no handler set, raise OCaml Error exception */
 | 
				
			||||||
 | 
					    exn_tag = caml_named_value(\"Z3.Error\");
 | 
				
			||||||
 | 
					    if (*exn_tag == 0) {
 | 
				
			||||||
 | 
					      fprintf(stderr, \"Z3.Error not found\");
 | 
				
			||||||
 | 
					      exit(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    caml_raise_with_args(*exn_tag, 2, ctx_err);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ml2c_Z3_error_handler (value ml_handler, void* c_handler)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  caml_error_handler = ml_handler;
 | 
				
			||||||
 | 
					  c_handler = (void*)error_handler_static;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Never called */
 | 
				
			||||||
 | 
					value c2ml_Z3_error_handler (void* _)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef [mltype("context -> error_code -> unit"),
 | 
				
			||||||
 | 
					         ml2c(ml2c_Z3_error_handler),
 | 
				
			||||||
 | 
					         c2ml(c2ml_Z3_error_handler)
 | 
				
			||||||
 | 
					        ] void Z3_error_handler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"#define Z3_error_handler void*");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										69
									
								
								ml/generate_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								ml/generate_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to generate the Z3 OCaml API
 | 
				
			||||||
 | 
					REM Invoke with "-D UNSAFE_ERRORS" to build version that does not support recoverable errors, but avoids some error-checking overhead.
 | 
				
			||||||
 | 
					REM Invoke with "-D LEAK_CONTEXTS" to build version that leaks Z3_context objects, but avoids some garbage-collection overhead.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM ../lib/z3_api.h -> z3V3_api.idl using add_error_checking.V3.sed and build.sed
 | 
				
			||||||
 | 
					sed -f add_error_checking.V3.sed ../lib/z3_api.h | sed -f build.sed >z3V3_api.idl
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM z3.idl -> z3V3_stubs.c, z3V3.mli, z3V3.ml
 | 
				
			||||||
 | 
					camlidl -D MLAPIV3 %* z3.idl
 | 
				
			||||||
 | 
					move >NUL z3_stubs.c z3V3_stubs.c
 | 
				
			||||||
 | 
					move >NUL z3.ml z3V3.ml
 | 
				
			||||||
 | 
					move >NUL z3.mli z3V3.mli
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM ../lib/z3_api.h -> z3_api.idl
 | 
				
			||||||
 | 
					REM add calls to error checking routine
 | 
				
			||||||
 | 
					REM convert from doxygen to ocamldoc markup and other syntactic munging
 | 
				
			||||||
 | 
					sed <../lib/z3_api.h -f add_error_checking.sed | ^
 | 
				
			||||||
 | 
					sed -f build.sed >z3_api.idl
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM z3.idl -> z3_stubs.c, z3.mli, z3.ml
 | 
				
			||||||
 | 
					camlidl %* z3.idl
 | 
				
			||||||
 | 
					if errorlevel 1 goto :EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM sometimes z3_stubs.c can be generated with mixed line endings, which can confuse sed and grep
 | 
				
			||||||
 | 
					dos2unix 2>NUL z3V3_stubs.c ; unix2dos 2>NUL z3V3_stubs.c
 | 
				
			||||||
 | 
					dos2unix 2>NUL z3_stubs.c ; unix2dos 2>NUL z3_stubs.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM modify generated z3.ml{,i} to remove "Z3_" prefix from names
 | 
				
			||||||
 | 
					move >NUL z3V3.mli z3V3.1.mli && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3V3.1.mli >z3V3.mli && del z3V3.1.mli
 | 
				
			||||||
 | 
					move >NUL z3V3.ml z3V3.1.ml && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3V3.1.ml >z3V3.ml && del z3V3.1.ml
 | 
				
			||||||
 | 
					move >NUL z3.mli z3.1.mli && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3.1.mli >z3.mli && del z3.1.mli
 | 
				
			||||||
 | 
					move >NUL z3.ml z3.1.ml && sed "s/{\!Z3\./{!/g;s/\<[zZ]3_//g" z3.1.ml >z3.ml && del z3.1.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM modify generated z3V3 files to rename z3_ to z3V3_
 | 
				
			||||||
 | 
					move >NUL z3V3.mli z3V3.2.mli && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3.2.mli >z3V3.mli && del z3V3.2.mli
 | 
				
			||||||
 | 
					move >NUL z3V3.ml z3V3.2.ml && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3.2.ml >z3V3.ml && del z3V3.2.ml
 | 
				
			||||||
 | 
					move >NUL z3V3_stubs.c z3V3_stubs.2.c && sed "s/camlidl\(.*\)_z3_/camlidl\1_z3V3_/g" z3V3_stubs.2.c >z3V3_stubs.c && del z3V3_stubs.2.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM substitute out type equations for enums and options
 | 
				
			||||||
 | 
					REM reverse order of substitution of enums to avoid matching prefixes such as enum_1 of enum_10
 | 
				
			||||||
 | 
					grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]*[0-9]*\)$" z3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\2/\1/g|g" | sed "1!G;h;$!d" >rename.sed
 | 
				
			||||||
 | 
					grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]* option*\)$" z3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\1/\2/g|g" >>rename.sed
 | 
				
			||||||
 | 
					move >NUL z3.mli z3.3.mli && sed -f rename.sed z3.3.mli >z3.mli && del z3.3.mli
 | 
				
			||||||
 | 
					move >NUL z3.ml z3.3.ml && sed -f rename.sed z3.3.ml >z3.ml && del z3.3.ml
 | 
				
			||||||
 | 
					del rename.sed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]*[0-9]*\)$" z3V3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\2/\1/g|g" | sed "1!G;h;$!d" >rename.sed
 | 
				
			||||||
 | 
					grep "^and \([a-z][a-zA-Z_]*\) = \([a-z][a-zA-Z_]* option*\)$" z3V3.mli | sed "s|and \([a-zA-Z_]*\) = \([ a-zA-Z_0-9]*\)|s/\1/\2/g|g" >>rename.sed
 | 
				
			||||||
 | 
					move >NUL z3V3.mli z3V3.3.mli && sed -f rename.sed z3V3.3.mli >z3V3.mli && del z3V3.3.mli
 | 
				
			||||||
 | 
					move >NUL z3V3.ml z3V3.3.ml && sed -f rename.sed z3V3.3.ml >z3V3.ml && del z3V3.3.ml
 | 
				
			||||||
 | 
					del rename.sed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM remove cyclic definitions introduced by substituting type equations
 | 
				
			||||||
 | 
					move >NUL z3V3.mli z3V3.4.mli && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3V3.4.mli >z3V3.mli && del z3V3.4.mli
 | 
				
			||||||
 | 
					move >NUL z3V3.ml z3V3.4.ml && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3V3.4.ml >z3V3.ml && del z3V3.4.ml
 | 
				
			||||||
 | 
					move >NUL z3.mli z3.4.mli && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3.4.mli >z3.mli && del z3.4.mli
 | 
				
			||||||
 | 
					move >NUL z3.ml z3.4.ml && sed "s/^and \([a-z][a-zA-Z_ ]*\) = \1$//g" z3.4.ml >z3.ml && del z3.4.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM append Z3.V3 module onto Z3 module
 | 
				
			||||||
 | 
					type z3V3.ml >> z3.ml
 | 
				
			||||||
 | 
					type z3V3.mli >> z3.mli
 | 
				
			||||||
 | 
					sed "1,22d" z3V3_stubs.c >> z3_stubs.c
 | 
				
			||||||
 | 
					del /q 2>NUL z3V3_api.idl z3V3.ml z3V3.mli z3V3_stubs.c
 | 
				
			||||||
							
								
								
									
										55
									
								
								ml/import.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								ml/import.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,55 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					SETLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:CHECKARG1
 | 
				
			||||||
 | 
					if not "%1"=="" (
 | 
				
			||||||
 | 
					  set SDTROOT=%1
 | 
				
			||||||
 | 
					  goto :CHECKARG2
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					goto :FAIL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:CHECKARG2
 | 
				
			||||||
 | 
					if "%2"=="" (
 | 
				
			||||||
 | 
					  goto :IMPORT
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					goto :FAIL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:IMPORT
 | 
				
			||||||
 | 
					cd import
 | 
				
			||||||
 | 
					sd edit ...
 | 
				
			||||||
 | 
					del z3.h z3_api.h z3_macros.h z3lib.lib msbig_rational.lib z3.exe test_capi.c test_mlapi_header.html z3_mlapi_header.html mldoc_footer.html tabs.css z3.png z3_ml.css
 | 
				
			||||||
 | 
					copy %SDTROOT%\lib\z3.h
 | 
				
			||||||
 | 
					copy %SDTROOT%\lib\z3_api.h
 | 
				
			||||||
 | 
					copy %SDTROOT%\lib\z3_macros.h
 | 
				
			||||||
 | 
					copy %SDTROOT%\release_mt\z3lib.lib
 | 
				
			||||||
 | 
					copy %SDTROOT%\release_mt\msbig_rational.lib
 | 
				
			||||||
 | 
					copy %SDTROOT%\release_mt\z3.exe
 | 
				
			||||||
 | 
					copy %SDTROOT%\test_capi\test_capi.c
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\test_mlapi_header.html
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\z3_mlapi_header.html
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\mldoc_footer.html
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\html\tabs.css
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\z3.png
 | 
				
			||||||
 | 
					copy %SDTROOT%\doc\z3_ml.css
 | 
				
			||||||
 | 
					sd add ...
 | 
				
			||||||
 | 
					sd revert -a ...
 | 
				
			||||||
 | 
					cd ..
 | 
				
			||||||
 | 
					goto :END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:FAIL
 | 
				
			||||||
 | 
					echo "Usage:"
 | 
				
			||||||
 | 
					echo "  %0 SDTROOT"
 | 
				
			||||||
 | 
					echo ""
 | 
				
			||||||
 | 
					echo "Examples:"
 | 
				
			||||||
 | 
					echo "  %0 \\risebuild\drops\z32\2.0.51220.7"
 | 
				
			||||||
 | 
					echo "  %0 \\risebuild\drops\z32\latest"
 | 
				
			||||||
 | 
					echo "  %0 J:\SD\other\sdt1\src\z3_2"
 | 
				
			||||||
 | 
					echo ""
 | 
				
			||||||
 | 
					goto :END
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:END
 | 
				
			||||||
 | 
					ENDLOCAL
 | 
				
			||||||
							
								
								
									
										11
									
								
								ml/mlx_get_app_args.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ml/mlx_get_app_args.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_app_num_args}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_app_arg}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_app_args: context -> app -> ast array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										11
									
								
								ml/mlx_get_array_sort.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ml/mlx_get_array_sort.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_array_sort c t ] \] is the domain and the range of [t].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_array_sort_domain}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_array_sort_range}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_array_sort: context -> sort -> sort * sort
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										13
									
								
								ml/mlx_get_datatype_sort.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								ml/mlx_get_datatype_sort.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_datatype_sort c ty ] \] is the array of triples [(constructor, recognizer, fields)] where [constructor] is the constructor declaration of [ty], [recognizer] is the recognizer for the [constructor], and [fields] is the array of fields in [ty].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_datatype_sort_num_constructors}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_datatype_sort_constructor}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_datatype_sort_recognizer}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_datatype_sort_constructor_accessor}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_datatype_sort: context -> sort -> datatype_constructor array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										11
									
								
								ml/mlx_get_domains.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ml/mlx_get_domains.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_domains c d ] \] is the array of parameters of [d].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_domain_size}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_domain}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_domains: context -> func_decl -> sort array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										6
									
								
								ml/mlx_get_error_msg.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ml/mlx_get_error_msg.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,6 @@
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: Return a string describing the given error code.
 | 
				
			||||||
 | 
					*) 
 | 
				
			||||||
 | 
					val get_error_msg: context -> error_code -> string
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										11
									
								
								ml/mlx_get_pattern_terms.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ml/mlx_get_pattern_terms.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_pattern_terms c p ] \] is the ast's in pattern.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_pattern_num_terms}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_pattern}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_pattern_terms: context -> pattern -> ast array;;
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										12
									
								
								ml/mlx_get_tuple_sort.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								ml/mlx_get_tuple_sort.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ get_tuple_sort c ty ] \] is the pair [(mk_decl, fields)] where [mk_decl] is the constructor declaration of [ty], and [fields] is the array of fields in [ty].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!get_tuple_sort_mk_decl}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_tuple_sort_num_fields}
 | 
				
			||||||
 | 
					  - {b See also}: {!get_tuple_sort_field_decl}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_tuple_sort: context -> sort -> (func_decl * func_decl array)
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										36
									
								
								ml/mlx_mk_context_x.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ml/mlx_mk_context_x.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					quote(mlmli,"external mk_context: (string * string) list -> context = \"caml_z3_mk_context\"
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					// Note: lack of whitespace and comments in the previous 2 lines is important for the documentation generation
 | 
				
			||||||
 | 
					quote(c,"
 | 
				
			||||||
 | 
					value caml_z3_mk_context(value key_val_list)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  CAMLparam1( key_val_list );
 | 
				
			||||||
 | 
					  CAMLlocal4( item, vkey, vval, _vres );
 | 
				
			||||||
 | 
					  char * ckey;
 | 
				
			||||||
 | 
					  char * cval;
 | 
				
			||||||
 | 
					  Z3_config cfg;
 | 
				
			||||||
 | 
					  Z3_context _res;
 | 
				
			||||||
 | 
					  struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL };
 | 
				
			||||||
 | 
					  camlidl_ctx _ctx = &_ctxs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  cfg = Z3_mk_config();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  while (key_val_list != Val_emptylist)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    item = Field(key_val_list, 0);
 | 
				
			||||||
 | 
					    vkey = Field(item, 0);
 | 
				
			||||||
 | 
					    vval = Field(item, 1);
 | 
				
			||||||
 | 
					    ckey = camlidl_malloc_string(vkey, _ctx);
 | 
				
			||||||
 | 
					    cval = camlidl_malloc_string(vval, _ctx);
 | 
				
			||||||
 | 
					    Z3_set_param_value(cfg, ckey, cval);
 | 
				
			||||||
 | 
					    key_val_list = Field(key_val_list, 1);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  _res = Z3_mk_context_rc(cfg);
 | 
				
			||||||
 | 
					  Z3_del_config(cfg);
 | 
				
			||||||
 | 
					  _vres = camlidl_c2ml_z3_Z3_context(&_res, _ctx);
 | 
				
			||||||
 | 
					  camlidl_free(_ctx);
 | 
				
			||||||
 | 
					  Z3_set_error_handler(_res, error_handler_static);
 | 
				
			||||||
 | 
					  CAMLreturn(_vres);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										28
									
								
								ml/mlx_mk_datatypes.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								ml/mlx_mk_datatypes.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,28 @@
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(** A constructor of a datatype is described by: *)
 | 
				
			||||||
 | 
					type datatype_constructor_desc = {
 | 
				
			||||||
 | 
					  constructor_desc : symbol;            	(** name of the constructor function *)
 | 
				
			||||||
 | 
					  recognizer_desc : symbol;             	(** name of the recognizer function *)
 | 
				
			||||||
 | 
					  accessor_descs : (symbol * sort) array;	(** names and sorts of the fields *)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** A datatype is described by a name and constructor descriptors. *)
 | 
				
			||||||
 | 
					type datatype_desc = symbol * datatype_constructor_desc array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** A constructor of a datatype is represented by: *)
 | 
				
			||||||
 | 
					type datatype_constructor = {
 | 
				
			||||||
 | 
					  constructor : func_decl;              	(** constructor function *)
 | 
				
			||||||
 | 
					  recognizer : func_decl;               	(** recognizer function *)
 | 
				
			||||||
 | 
					  accessors : func_decl array;          	(** field accessor functions *)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** A datatype is represented by a sort and constructors. *)
 | 
				
			||||||
 | 
					type datatype = sort * datatype_constructor array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(** [mk_datatypes ctx sorts_to_descriptors] creates mutually recursive datatypes described by
 | 
				
			||||||
 | 
					    [sorts_to_descriptors], which is a function from the sorts of the datatypes to be created to
 | 
				
			||||||
 | 
					    descriptors of the datatypes' constructors. {b See also}: {!Test_mlapi.forest_example} *)
 | 
				
			||||||
 | 
					val mk_datatypes: context -> (sort array -> (datatype_desc array) option) -> datatype array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										21
									
								
								ml/mlx_mk_numeral.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								ml/mlx_mk_numeral.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ numeral_refined ] \] is the refined view of a numeral .
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type numeral_refined =
 | 
				
			||||||
 | 
					  | Numeral_int      of int * sort
 | 
				
			||||||
 | 
					  | Numeral_int64    of int64 * sort
 | 
				
			||||||
 | 
					  | Numeral_large    of string * sort
 | 
				
			||||||
 | 
					  | Numeral_rational of numeral_refined * numeral_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ embed_numeral c nr ] \] constructs the numeral described by [nr].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b See also}: {!numeral_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val embed_numeral: context -> numeral_refined -> ast
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										69
									
								
								ml/mlx_mk_sort.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								ml/mlx_mk_sort.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,69 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   A datatype constructor descriptor.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type datatype_constructor_desc = {
 | 
				
			||||||
 | 
					  constructor_desc : symbol;            	(** name of the constructor function *)
 | 
				
			||||||
 | 
					  recognizer_desc : symbol;             	(** name of the recognizer function *)
 | 
				
			||||||
 | 
					  accessor_descs : (symbol * sort) array;	(** names and sorts of the fields *)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   A datatype is described by a name and constructor descriptors.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type datatype_desc = symbol * datatype_constructor_desc array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   A datatype constructor representation.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type datatype_constructor = {
 | 
				
			||||||
 | 
					  constructor : func_decl;              	(** constructor function *)
 | 
				
			||||||
 | 
					  recognizer : func_decl;               	(** recognizer function *)
 | 
				
			||||||
 | 
					  accessors : func_decl array;          	(** field accessor functions *)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   A datatype is represented by a sort and constructors.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type datatype = sort * datatype_constructor array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Refined view of a {!sort}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b See also}: {!mk_sort}
 | 
				
			||||||
 | 
					   - {b See also}: {!sort_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type sort_refined =
 | 
				
			||||||
 | 
					  | Sort_uninterpreted of symbol
 | 
				
			||||||
 | 
					  | Sort_bool
 | 
				
			||||||
 | 
					  | Sort_int
 | 
				
			||||||
 | 
					  | Sort_bv of int
 | 
				
			||||||
 | 
					  | Sort_finite_domain of symbol * int64
 | 
				
			||||||
 | 
					  | Sort_real
 | 
				
			||||||
 | 
					  | Sort_array of sort * sort
 | 
				
			||||||
 | 
					  | Sort_datatype of datatype_constructor array
 | 
				
			||||||
 | 
					  | Sort_relation of sort array
 | 
				
			||||||
 | 
					  | Sort_unknown
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ mk_sort c sr ] \] constructs the sort described by [sr].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b Precondition}: [sr] is not of form [Sort_relation] or [Sort_unknown], which cannot be directly constructed
 | 
				
			||||||
 | 
					   - {b See also}: {!mk_datatypes}
 | 
				
			||||||
 | 
					   - {b See also}: {!sort_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val mk_sort: context -> sort_refined -> sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   \[ [mk_datatypes ctx sorts_to_descriptors] \] creates mutually recursive datatypes described by
 | 
				
			||||||
 | 
					   [sorts_to_descriptors], which is a function from the sorts of the datatypes to be created to
 | 
				
			||||||
 | 
					   descriptors of the datatypes' constructors.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b See also}: {!Test_mlapi.forest_example}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val mk_datatypes: context -> (sort array -> (datatype_desc array) option) -> datatype array
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										22
									
								
								ml/mlx_mk_symbol.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ml/mlx_mk_symbol.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,22 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Refined view of a {!symbol}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b See also}: {!mk_symbol}
 | 
				
			||||||
 | 
					   - {b See also}: {!symbol_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type symbol_refined =
 | 
				
			||||||
 | 
					  | Symbol_int of int
 | 
				
			||||||
 | 
					  | Symbol_string of string
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ mk_symbol c sr ] \] constructs the symbol described by [sr].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!symbol_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val mk_symbol: context -> symbol_refined -> symbol
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										19
									
								
								ml/mlx_model.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								ml/mlx_model.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   A model assigns uninterpreted sorts to finite universes of distinct values, constants to values,
 | 
				
			||||||
 | 
					   and arrays and functions to finite maps from argument values to result values plus a default
 | 
				
			||||||
 | 
					   value for all other arguments.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type model_refined = {
 | 
				
			||||||
 | 
					  sorts : (sort, ast_vector) Hashtbl.t;
 | 
				
			||||||
 | 
					  consts : (func_decl, ast) Hashtbl.t;
 | 
				
			||||||
 | 
					  arrays : (func_decl, (ast, ast) Hashtbl.t * ast) Hashtbl.t;
 | 
				
			||||||
 | 
					  funcs : (func_decl, (ast array, ast) Hashtbl.t * ast) Hashtbl.t;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(** 
 | 
				
			||||||
 | 
					   Summary: [model_refine c m] is the refined model of [m].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val model_refine : context -> model -> model_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										10
									
								
								ml/mlx_numeral_refine.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ml/mlx_numeral_refine.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ numeral_refine c a ] \] is the refined view of [a].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b Precondition}: [get_ast_kind c a = NUMERAL_AST]
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val numeral_refine : context -> ast -> numeral_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										40
									
								
								ml/mlx_parse_smtlib.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								ml/mlx_parse_smtlib.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ parse_smtlib_string_x c str sort_names sorts decl_names decls ] \]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Parse the given string using the SMT-LIB parser. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The symbol table of the parser can be initialized using the given sorts and declarations. 
 | 
				
			||||||
 | 
					  The symbols in the arrays [sort_names] and [decl_names] don't need to match the names
 | 
				
			||||||
 | 
					  of the sorts and declarations in the arrays [sorts] and [decls]. This is an useful feature
 | 
				
			||||||
 | 
					  since we can use arbitrary names to reference sorts and declarations defined using the API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_file_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: Similar to {!parse_smtlib_string_x}, but reads the benchmark from a file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_string_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_file_formula}
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_string_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_string_formula}
 | 
				
			||||||
 | 
					  - {b See also}: {!parse_smtlib_file_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										8
									
								
								ml/mlx_sort_refine.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ml/mlx_sort_refine.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ sort_refine c s ] \] is the refined view of [s].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val sort_refine: context -> sort -> sort_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										10
									
								
								ml/mlx_statistics.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ml/mlx_statistics.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					type stat_datum = Stat_int of int | Stat_float of float
 | 
				
			||||||
 | 
					type stats_refined = (string, stat_datum) Hashtbl.t
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(** 
 | 
				
			||||||
 | 
					   Summary: [stats_refine c s] is the refined stats of [s].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val stats_refine : context -> stats -> stats_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										8
									
								
								ml/mlx_symbol_refine.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								ml/mlx_symbol_refine.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ symbol_refine c s ] \] is the refined view of [s].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val symbol_refine: context -> symbol -> symbol_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										37
									
								
								ml/mlx_term_refine.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								ml/mlx_term_refine.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,37 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ binder_type ] \] is a universal or existential quantifier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!term_refined}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type binder_type = Forall | Exists
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  Summary: \[ [ term_refined ] \] is the refinement of a {!ast} .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!term_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type term_refined =
 | 
				
			||||||
 | 
					  | Term_numeral    of numeral_refined
 | 
				
			||||||
 | 
					  | Term_app        of decl_kind * func_decl * ast array
 | 
				
			||||||
 | 
					  | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast
 | 
				
			||||||
 | 
					  | Term_var        of int * sort
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ mk_term c tr ] \] constructs the term described by [tr].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					   - {b Precondition}: [tr] is not of form
 | 
				
			||||||
 | 
					   - {b See also}: {!term_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					(* val mk_term: context -> term_refined -> ast *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Summary: \[ [ term_refine c a ] \] is the refined view of [a].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val term_refine : context -> ast -> term_refined
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										72
									
								
								ml/msbuild.proj
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								ml/msbuild.proj
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,72 @@
 | 
				
			||||||
 | 
					<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <MyIn Include="
 | 
				
			||||||
 | 
					      build.sed;
 | 
				
			||||||
 | 
					      clean.cmd;
 | 
				
			||||||
 | 
					      diff.exe;
 | 
				
			||||||
 | 
					      import\mldoc_footer.html;
 | 
				
			||||||
 | 
					      import\msbig_rational.lib;
 | 
				
			||||||
 | 
					      import\tabs.css;
 | 
				
			||||||
 | 
					      import\test_capi.c;
 | 
				
			||||||
 | 
					      import\test_mlapi_header.html;
 | 
				
			||||||
 | 
					      import\z3.exe;
 | 
				
			||||||
 | 
					      import\z3.h;
 | 
				
			||||||
 | 
					      import\z3.png;
 | 
				
			||||||
 | 
					      import\z3_api.h;
 | 
				
			||||||
 | 
					      import\z3_ml.css;
 | 
				
			||||||
 | 
					      import\z3_mlapi_header.html;
 | 
				
			||||||
 | 
					      import\z3lib.lib;
 | 
				
			||||||
 | 
					      import.cmd;
 | 
				
			||||||
 | 
					      msbuild.proj;
 | 
				
			||||||
 | 
					      queen.ml;
 | 
				
			||||||
 | 
					      queen.regress.err;
 | 
				
			||||||
 | 
					      queen.regress.txt;
 | 
				
			||||||
 | 
					      readme.txt;
 | 
				
			||||||
 | 
					      regress.cmd;
 | 
				
			||||||
 | 
					      sed.exe;
 | 
				
			||||||
 | 
					      test_capi.regress.err;
 | 
				
			||||||
 | 
					      test_capi.regress.txt;
 | 
				
			||||||
 | 
					      test_mlapi.ml;
 | 
				
			||||||
 | 
					      test_mlapi.regress.err;
 | 
				
			||||||
 | 
					      test_mlapi.regress.txt;
 | 
				
			||||||
 | 
					      update-ml-doc.cmd;
 | 
				
			||||||
 | 
					      x3.ml;
 | 
				
			||||||
 | 
					      x3.mli;
 | 
				
			||||||
 | 
					      z3.idl;
 | 
				
			||||||
 | 
					      z3.proj;
 | 
				
			||||||
 | 
					    "/>
 | 
				
			||||||
 | 
					    <MyOut Include="
 | 
				
			||||||
 | 
					      doc\index.html;
 | 
				
			||||||
 | 
					      libz3.lib;
 | 
				
			||||||
 | 
					      queen.err;
 | 
				
			||||||
 | 
					      queen.exe;
 | 
				
			||||||
 | 
					      queen.txt;
 | 
				
			||||||
 | 
					      test_capi.err;
 | 
				
			||||||
 | 
					      test_capi.exe;
 | 
				
			||||||
 | 
					      test_capi.txt;
 | 
				
			||||||
 | 
					      test_mlapi.err;
 | 
				
			||||||
 | 
					      test_mlapi.exe;
 | 
				
			||||||
 | 
					      test_mlapi.txt;
 | 
				
			||||||
 | 
					      z3.cmi;
 | 
				
			||||||
 | 
					      z3.cmxa;
 | 
				
			||||||
 | 
					      z3.lib;
 | 
				
			||||||
 | 
					      z3.mli;
 | 
				
			||||||
 | 
					    "/>
 | 
				
			||||||
 | 
					    <CleanDependsOn Include="MyBeforeClean"/>
 | 
				
			||||||
 | 
					    <BuildDependsOn Include="MyBeforeBuild"/>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <Target Name="MyBeforeClean">
 | 
				
			||||||
 | 
					    <Exec Command ="clean.cmd" />
 | 
				
			||||||
 | 
					  </Target>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <Target Name="MyBeforeBuild" 
 | 
				
			||||||
 | 
					    Inputs="@(MyIn)"
 | 
				
			||||||
 | 
					    Outputs="@(MyOut)" >
 | 
				
			||||||
 | 
					    <Exec Command ="build.cmd" />
 | 
				
			||||||
 | 
					  </Target>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <Import Project="$(SLAMSRC)\msbuild\sdv.targets" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										112
									
								
								ml/queen.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								ml/queen.ml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,112 @@
 | 
				
			||||||
 | 
					(*
 | 
				
			||||||
 | 
					  queen.exe - JakobL@2007-09-22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Demonstration of how Z3 can be used to find solutions to the
 | 
				
			||||||
 | 
					  N-Queens problem.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  See: http://en.wikipedia.org/wiki/Eight_queens_puzzle
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Problem specification: Is the following constraint system satisfiable,
 | 
				
			||||||
 | 
					  for increasing n>=1, what are the models?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constant
 | 
				
			||||||
 | 
					      n: 8;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    variable
 | 
				
			||||||
 | 
					      row: array n of [0..n-1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rule
 | 
				
			||||||
 | 
					      forall i in [0..n-2]:
 | 
				
			||||||
 | 
					        (forall j in [i+1..n-1]:
 | 
				
			||||||
 | 
					           ((row[i] <> row[j]) and 
 | 
				
			||||||
 | 
					           (i+row[i]) <> (j+row[j]) and
 | 
				
			||||||
 | 
					           (i+row[j]) <> (j+row[i])));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  The answer is yes for n different from 2 and 3.  The number of solutions are:
 | 
				
			||||||
 | 
					    * n=1: 1
 | 
				
			||||||
 | 
					    * n=2: 0
 | 
				
			||||||
 | 
					    * n=3: 0
 | 
				
			||||||
 | 
					    * n=4: 2
 | 
				
			||||||
 | 
					    * n=5: 10
 | 
				
			||||||
 | 
					    * n=6: 4
 | 
				
			||||||
 | 
					    * n=7: 40
 | 
				
			||||||
 | 
					    * n=8: 92
 | 
				
			||||||
 | 
					    * n=9: 352
 | 
				
			||||||
 | 
					    * n=10: 724
 | 
				
			||||||
 | 
					    ...
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Z3 = Z3.V3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Auxillary functions *)
 | 
				
			||||||
 | 
					let ( |> ) x f = f x;;
 | 
				
			||||||
 | 
					let printf = Printf.printf;;
 | 
				
			||||||
 | 
					let mk_var ctx name ty = Z3.mk_const ctx (Z3.mk_int_symbol ctx name) ty;;
 | 
				
			||||||
 | 
					let mk_int_var ctx name = Z3.mk_int_sort ctx |> mk_var ctx name;;
 | 
				
			||||||
 | 
					let mk_int ctx v = Z3.mk_int ctx v (Z3.mk_int_sort ctx);;
 | 
				
			||||||
 | 
					let checkreturn v = match v with | (true,r) -> r | _ -> failwith "checkreturn";;
 | 
				
			||||||
 | 
					let get_numeral_value_int a1 a2 = Z3.get_numeral_int a1 a2 |> checkreturn;;
 | 
				
			||||||
 | 
					let iterate_x lower upper f = for i = lower to upper do f i done;;
 | 
				
			||||||
 | 
					let forall_x ctx lower upper f = Z3.mk_and ctx (Array.init (1+upper-lower) (fun i->f (i+lower)))
 | 
				
			||||||
 | 
					let exist_x ctx lower upper f = Z3.mk_or ctx (Array.init (1+upper-lower) (fun i->f (i+lower)))
 | 
				
			||||||
 | 
					let get_value ctx model f = let (ok, v) = Z3.eval_func_decl ctx model f in (assert ok; v)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let queen_n n =
 | 
				
			||||||
 | 
					  let ctx = Z3.mk_context_x
 | 
				
			||||||
 | 
					    [|("MODEL","true");
 | 
				
			||||||
 | 
					      ("RELEVANCY","0")|] in
 | 
				
			||||||
 | 
					  let ( &&& ) x y = Z3.mk_and ctx [|x;y|] in
 | 
				
			||||||
 | 
					  let ( <~> ) x y = Z3.mk_not ctx (Z3.mk_eq ctx x y) in
 | 
				
			||||||
 | 
					  let ( <<= ) x y = Z3.mk_le ctx x y in
 | 
				
			||||||
 | 
					  let ( +++ ) x y = Z3.mk_add ctx [|x;y|] in
 | 
				
			||||||
 | 
					  let row = Array.init n (fun i->mk_int_var ctx i) in
 | 
				
			||||||
 | 
					  let c x =  mk_int ctx x in (* make constant *)
 | 
				
			||||||
 | 
					  let v x =  row.(x) in (* make variable *)
 | 
				
			||||||
 | 
					  let constraint_domain=forall_x ctx (0) (n-1) (fun x-> ((c 0) <<= (v x)) &&& ((v x) <<= (c (n-1)))) in
 | 
				
			||||||
 | 
					  let constraint_queen=
 | 
				
			||||||
 | 
					    forall_x ctx (0) (n-2) (fun i->
 | 
				
			||||||
 | 
					      forall_x ctx (i+1) (n-1) (fun j->
 | 
				
			||||||
 | 
					         ((v i) <~> (v j)) &&&
 | 
				
			||||||
 | 
					         (((c i)+++(v i)) <~> ((c j)+++(v j))) &&&
 | 
				
			||||||
 | 
					         (((c i)+++(v j)) <~> ((c j)+++(v i)))
 | 
				
			||||||
 | 
					       )
 | 
				
			||||||
 | 
					    ) in
 | 
				
			||||||
 | 
					  let res = constraint_domain &&& constraint_queen in
 | 
				
			||||||
 | 
					  Z3.assert_cnstr ctx res;
 | 
				
			||||||
 | 
					  let rec f i =
 | 
				
			||||||
 | 
					    (match Z3.check_and_get_model ctx with
 | 
				
			||||||
 | 
					    | (Z3.L_FALSE,_) ->
 | 
				
			||||||
 | 
					      printf "queen %d, total models: %d\n" n i;
 | 
				
			||||||
 | 
					      flush stdout;
 | 
				
			||||||
 | 
					    | (Z3.L_UNDEF,_) -> failwith "Z3.L_UNDEF"
 | 
				
			||||||
 | 
					    | (Z3.L_TRUE,model) ->
 | 
				
			||||||
 | 
					    begin
 | 
				
			||||||
 | 
					      let model_constants=Z3.get_model_constants ctx model in
 | 
				
			||||||
 | 
					      let vars=Array.map (fun mc->Z3.mk_app ctx mc [||]) model_constants in
 | 
				
			||||||
 | 
					      let vals=Array.map (fun mc->get_value ctx model mc |> get_numeral_value_int ctx) model_constants in
 | 
				
			||||||
 | 
					      Z3.del_model ctx model;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let line = String.make n '-' in
 | 
				
			||||||
 | 
					      let q_line i = let r = String.make n ' ' in String.set r i 'Q'; r in
 | 
				
			||||||
 | 
					      printf "queen %d, model #%d:\n" n (i+1);
 | 
				
			||||||
 | 
					      printf "\n";
 | 
				
			||||||
 | 
					      printf "  /%s\\\n" line;
 | 
				
			||||||
 | 
					      iterate_x 0 (n-1) (fun x->printf "  |%s|\n" (q_line (vals.(x))));
 | 
				
			||||||
 | 
					      printf "  \\%s/\n" line;
 | 
				
			||||||
 | 
					      printf "\n";
 | 
				
			||||||
 | 
					      flush stdout;
 | 
				
			||||||
 | 
					      let negated_model = exist_x ctx 0 (n-1) (fun x->(vars.(x)) <~> (c (vals.(x)))) in
 | 
				
			||||||
 | 
					      Z3.assert_cnstr ctx negated_model;
 | 
				
			||||||
 | 
					      f (i+1);
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					    ) in
 | 
				
			||||||
 | 
					  f 0;
 | 
				
			||||||
 | 
					  Z3.del_context ctx;
 | 
				
			||||||
 | 
					  ();;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let queen() =
 | 
				
			||||||
 | 
					  for n = 1 to 8 do
 | 
				
			||||||
 | 
					    queen_n n
 | 
				
			||||||
 | 
					  done;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let _ = queen();;
 | 
				
			||||||
							
								
								
									
										0
									
								
								ml/queen.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ml/queen.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										1852
									
								
								ml/queen.regress.out
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1852
									
								
								ml/queen.regress.out
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										144
									
								
								ml/readme.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								ml/readme.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,144 @@
 | 
				
			||||||
 | 
					Z3 - JakobL@2011-12-20
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					What:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Z3 is a high-performance theorem prover being developed at Microsoft
 | 
				
			||||||
 | 
					Research by Nikolaj Bjørner (NBjorner) and Leonardo de Moura
 | 
				
			||||||
 | 
					(Leonardo).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This folder contains the Z3 ML module used by the SLAM verification
 | 
				
			||||||
 | 
					engine.  The Z3 ML module provides a complete ML interface to the Z3
 | 
				
			||||||
 | 
					x86 native library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Multiple source depots:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This folder is hosted in two separate source depots:
 | 
				
			||||||
 | 
					* SDT (sdport=BGIT-SDTVMDEPOT:5010): //depot/src/z3_2/ml/
 | 
				
			||||||
 | 
					* SLAM (SDPort=BGIT-SDSLAM:7021): //depot/src/main/slam/engine/slam2/z3/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Goal is to have identical contents in both source depots.  Reason for
 | 
				
			||||||
 | 
					hosting in SDT source depot: to allow for testing of the Z3 ML module
 | 
				
			||||||
 | 
					'close' to Z3.  Reason for maintaining in SLAM source depot: to allow
 | 
				
			||||||
 | 
					for building SLAM without access to SDT.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Discrepancy between usage and files in the two source depots are in
 | 
				
			||||||
 | 
					the following marked with [SDT] or [SLAM].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					How to use the Z3 ML Module:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* doc\index.html: Reference documentation of the ML interface. Notice:
 | 
				
			||||||
 | 
					  This is generated during build and hence first available afterwards.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* z3.mli: Provides the actual Z3 ML Signature, generated at build
 | 
				
			||||||
 | 
					  time.  The Reference documentation is built from this file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* test_mlapi.ml: Sample program that demonstrate how to use the Z3 ML library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* queen.ml: Sample program that demonstrate how to use the Z3 ML library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* import\z3.exe: Z3 shell: Useful for trying out queries. ([SDT]: in
 | 
				
			||||||
 | 
					  %SDTROOT%\release_mt\z3.exe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Building and linking:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Z3 ML is used as any other ML library.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Prerequisites:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [SLAM]: Just a standard 'SDV Build Environment'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [SDT]: NB. Make sure to use an x86 build window.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Install OCaml:
 | 
				
			||||||
 | 
					  * Install from: \\sdv-fs.ntdev.corp.microsoft.com\software\3rdParty\ocaml-3.07pl2-win-msvc.exe 
 | 
				
			||||||
 | 
					    Or from z3_2\tools
 | 
				
			||||||
 | 
					  * Install to: C:\ocaml 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Install CamlIDL:
 | 
				
			||||||
 | 
					  * Install from: \\sdv-fs.ntdev.corp.microsoft.com\software\Installers\camlidl-1.04-2.exe 
 | 
				
			||||||
 | 
					    Or from z3_2\tools
 | 
				
			||||||
 | 
					  * Install to: C:\ocaml 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Build z3.sln's configuration 'release_mt':
 | 
				
			||||||
 | 
					  cd %SDTROOT%\src\z3_2
 | 
				
			||||||
 | 
					  msbuild /target:lib /p:configuration=release_mt
 | 
				
			||||||
 | 
					  msbuild /target:shell /p:configuration=release_mt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To build and run regressions:
 | 
				
			||||||
 | 
					* [SLAM]: mb
 | 
				
			||||||
 | 
					* [SDT]: build
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To clean:
 | 
				
			||||||
 | 
					* [SLAM]: mc
 | 
				
			||||||
 | 
					* [SDT]: clean
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					To link with your favorite app:
 | 
				
			||||||
 | 
					* [SLAM]: Reference z3.proj from your msbuild.proj file:
 | 
				
			||||||
 | 
					  <Import Project="$(SLAMSRC)\slam\engine\slam2\z3\z3.proj" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* [SDT]: Link the Z3 ML library as well as supporting libraries:
 | 
				
			||||||
 | 
					  ocamlopt -ccopt "/MT /nologo /DWIN32" ole32.lib %OCAMLLIB%\libcamlidl.lib -I %SDTROOT%\src\z3_2\ml %SDTROOT%\src\z3_2\ml\z3.cmxa -o queen.exe queen.ml
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Files:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					* readme.txt: This file
 | 
				
			||||||
 | 
					* build.cmd: Build script [SDT]: invoke directly; [SLAM]: invoked automatically
 | 
				
			||||||
 | 
					* clean.cmd: [SDT]: Script for cleaning; [SLAM]: use mc for cleaning
 | 
				
			||||||
 | 
					* regress.cmd: Script for updating regressions.  Not for regular users.
 | 
				
			||||||
 | 
					* build.sed, update-ml-doc.cmd: Supporting scripts for building.
 | 
				
			||||||
 | 
					* diff.exe.exe: Supporting tool for building.  Obtained from [SLAM] from //depot/src/main/tools/Win32/UnxUtils.zip.
 | 
				
			||||||
 | 
					* sed.exe: Supporting tool for building.  Obtained from http://sed.sourceforge.net/ -> "super sed v3.59 for Windows by Paolo Bonzini" -> sed-3.59.zip -> sed-3.59.exe. See http://www.pement.org/sed/ for a good overview of sed for Windows.
 | 
				
			||||||
 | 
					* msbuild.proj: [SLAM only]: Used by mb and mc
 | 
				
			||||||
 | 
					* z3.proj: [SLAM only]: Project file for consumers of the Z3 module
 | 
				
			||||||
 | 
					* import.cmd: [SLAM only]: Script to import files from SDT.
 | 
				
			||||||
 | 
					* z3.idl,z3_api.idl: Interface definition files, z3_api.idl is autogenerated during build.
 | 
				
			||||||
 | 
					* z3.h: Supporting header file for z3.idl
 | 
				
			||||||
 | 
					* x3.{mli,ml}: Module X3 contains Z3 ML specific extensions.  Do not use directly, included in Z3 during build.
 | 
				
			||||||
 | 
					* queen.ml:  Z3 ML test program.
 | 
				
			||||||
 | 
					* test_mlapi.ml: Z3 ML test program.
 | 
				
			||||||
 | 
					* z3_theory_stubs.c and test_theory.ml: Theory plugin and test.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*.regress.*: Regression files, used by build.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[SLAM only]:
 | 
				
			||||||
 | 
					* import\z3lib.lib: Z3 C library.
 | 
				
			||||||
 | 
					* import\msbig_rational.lib: Supporting C library.
 | 
				
			||||||
 | 
					* import\test_capi.c: Z3 C test program.
 | 
				
			||||||
 | 
					* import\{z3.h,z3_api.h,z3_macros.h}: Z3 C header files.
 | 
				
			||||||
 | 
					* import\{mldoc_footer.html,tabs.css,test_mlapi_header.html,z3.png,z3_ml.css,z3_mlapi_header.html}: Files for automated documentation generation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Import from MSR:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Certain files are imported from MSR.  See above list for details as
 | 
				
			||||||
 | 
					well as import.cmd script.  To determine the version of z3.exe you are
 | 
				
			||||||
 | 
					using, a bit of investigate work will lead you to exact build:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Run import\z3.exe -version. This will generate:
 | 
				
			||||||
 | 
					  Version (major minor build revision): 0 1 0 0
 | 
				
			||||||
 | 
					Or:
 | 
				
			||||||
 | 
					  Version (major minor build revision): 0 1 10828 7
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The first example indicate a private drop imported with something like
 | 
				
			||||||
 | 
					'import.cmd J:\SD\other\sdt1\src\z3_2'.  The second example indicate
 | 
				
			||||||
 | 
					drop 10828 from risebuild imported with something like 'import.cmd
 | 
				
			||||||
 | 
					\\risebuild\drops\z32\2.0.51220.7'.   
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TODO: Update following: Look at
 | 
				
			||||||
 | 
					http://pexbuild3/ccnet/ViewFarmReport.aspx -> View All Builds ->
 | 
				
			||||||
 | 
					10828.  This will give you the SD change number.  Voila!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					==============================================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Known issues:
 | 
				
			||||||
 | 
					*  warning LNK4099: This message is shown when linking.  Please ignore.
 | 
				
			||||||
							
								
								
									
										10
									
								
								ml/regress.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								ml/regress.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					call .\build.cmd
 | 
				
			||||||
 | 
					sd edit test_capi.regress.txt test_capi.regress.err test_mlapi.regress.txt test_mlapi.regress.err queen.regress.txt queen.regress.err
 | 
				
			||||||
 | 
					move test_capi.txt test_capi.regress.txt
 | 
				
			||||||
 | 
					move test_capi.err test_capi.regress.err
 | 
				
			||||||
 | 
					move test_mlapi.txt test_mlapi.regress.txt
 | 
				
			||||||
 | 
					move test_mlapi.err test_mlapi.regress.err
 | 
				
			||||||
 | 
					move queen.txt queen.regress.txt
 | 
				
			||||||
 | 
					move queen.err queen.regress.err
 | 
				
			||||||
 | 
					sd revert -a test_capi.regress.txt test_capi.regress.err test_mlapi.regress.txt test_mlapi.regress.err queen.regress.txt queen.regress.err
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								ml/sed.exe
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								ml/sed.exe
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										5
									
								
								ml/test_capi.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ml/test_capi.regress.err
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					WARNING: invalid function application, sort mismatch on argument at position 1
 | 
				
			||||||
 | 
					WARNING: (define iff Bool Bool Bool) applied to: 
 | 
				
			||||||
 | 
					x of sort Int
 | 
				
			||||||
 | 
					y of sort Bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										386
									
								
								ml/test_capi.regress.out
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										386
									
								
								ml/test_capi.regress.out
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,386 @@
 | 
				
			||||||
 | 
					Z3 4.0.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					simple_example
 | 
				
			||||||
 | 
					CONTEXT:
 | 
				
			||||||
 | 
					(solver)END OF CONTEXT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DeMorgan
 | 
				
			||||||
 | 
					DeMorgan is valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_model_example1
 | 
				
			||||||
 | 
					model for: x xor y
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> false
 | 
				
			||||||
 | 
					x -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_model_example2
 | 
				
			||||||
 | 
					model for: x < y + 1, x > 2
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 3
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					model for: x < y + 1, x > 2, not(x = y)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 4
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove_example1
 | 
				
			||||||
 | 
					prove: x = y implies g(x) = g(y)
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: x = y implies g(g(x)) = g(y)
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					y -> U!val!0
 | 
				
			||||||
 | 
					x -> U!val!0
 | 
				
			||||||
 | 
					g -> {
 | 
				
			||||||
 | 
					  U!val!0 -> U!val!1
 | 
				
			||||||
 | 
					  U!val!1 -> U!val!2
 | 
				
			||||||
 | 
					  else -> U!val!1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove_example2
 | 
				
			||||||
 | 
					prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					z -> -1
 | 
				
			||||||
 | 
					y -> -7719
 | 
				
			||||||
 | 
					x -> -7719
 | 
				
			||||||
 | 
					g -> {
 | 
				
			||||||
 | 
					  -7719 -> 0
 | 
				
			||||||
 | 
					  0 -> 2
 | 
				
			||||||
 | 
					  -1 -> 3
 | 
				
			||||||
 | 
					  else -> 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					push_pop_example1
 | 
				
			||||||
 | 
					assert: x >= 'big number'
 | 
				
			||||||
 | 
					push
 | 
				
			||||||
 | 
					number of scopes: 1
 | 
				
			||||||
 | 
					assert: x <= 3
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					pop
 | 
				
			||||||
 | 
					number of scopes: 0
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					x = 1000000000000000000000000000000000000000000000000000000:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					assert: y > x
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y = 1000000000000000000000000000000000000000000000000000001:int
 | 
				
			||||||
 | 
					x = 1000000000000000000000000000000000000000000000000000000:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quantifier_example1
 | 
				
			||||||
 | 
					pattern: {(f #0 #1)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					assert axiom:
 | 
				
			||||||
 | 
					(forall (k!0 Int) (k!1 Int) (= (inv!0 (f k!1 k!0)) k!0) :pat {(f k!1 k!0)})
 | 
				
			||||||
 | 
					prove: f(x, y) = f(w, v) implies y = v
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: f(x, y) = f(w, v) implies x = w
 | 
				
			||||||
 | 
					that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable
 | 
				
			||||||
 | 
					unknown
 | 
				
			||||||
 | 
					potential model:
 | 
				
			||||||
 | 
					w = 2:int
 | 
				
			||||||
 | 
					v = 1:int
 | 
				
			||||||
 | 
					y = 1:int
 | 
				
			||||||
 | 
					x = 0:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					f = {(else|->(define f!52 Int Int Int)[(define k!50 Int Int)[#unknown], (define k!51 Int Int)[#unknown]])}
 | 
				
			||||||
 | 
					#51 = {(2:int|->2:int), (1:int|->1:int), (15:int|->15:int), (11:int|->11:int), (0:int|->0:int), (19:int|->19:int), (else|->2:int)}
 | 
				
			||||||
 | 
					f!52 = {(0:int, 1:int|->3:int), (2:int, 1:int|->3:int), (0:int, 0:int|->4:int), (2:int, 0:int|->5:int), (6:int, 2:int|->7:int), (2:int, 2:int|->8:int), (0:int, 2:int|->9:int), (6:int, 0:int|->10:int), (0:int, 11:int|->12:int), (2:int, 11:int|->13:int), (6:int, 11:int|->14:int), (0:int, 15:int|->16:int), (2:int, 15:int|->17:int), (6:int, 15:int|->18:int), (0:int, 19:int|->20:int), (6:int, 19:int|->21:int), (2:int, 19:int|->22:int), (else|->3:int)}
 | 
				
			||||||
 | 
					inv!0 = {(3:int|->1:int), (4:int|->0:int), (5:int|->0:int), (7:int|->2:int), (8:int|->2:int), (9:int|->2:int), (10:int|->0:int), (12:int|->11:int), (13:int|->11:int), (14:int|->11:int), (16:int|->15:int), (17:int|->15:int), (18:int|->15:int), (20:int|->19:int), (21:int|->19:int), (22:int|->19:int), (else|->2:int)}
 | 
				
			||||||
 | 
					#50 = {(2:int|->2:int), (6:int|->6:int), (0:int|->0:int), (else|->2:int)}
 | 
				
			||||||
 | 
					reason for last failure: 7 (7 = quantifiers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example1
 | 
				
			||||||
 | 
					prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))
 | 
				
			||||||
 | 
					(implies (= (store a1 i1 v1) (store a2 i2 v2))
 | 
				
			||||||
 | 
					         (or (= i1 i3) (= i2 i3) (= (select a1 i3) (select a2 i3))))
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example2
 | 
				
			||||||
 | 
					n = 2
 | 
				
			||||||
 | 
					(distinct k!0 k!1)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#1 = {((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 3
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					#2 = (define as-array[k!2] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#1 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#2 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 4
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2 k!3)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					#2 = (define as-array[k!2] (Array Bool Bool))
 | 
				
			||||||
 | 
					#3 = (define as-array[k!3] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define true Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					#1 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#2 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#3 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 5
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2 k!3 k!4)
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example3
 | 
				
			||||||
 | 
					domain: int
 | 
				
			||||||
 | 
					range:  bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tuple_example1
 | 
				
			||||||
 | 
					tuple_sort: (real, real)
 | 
				
			||||||
 | 
					prove: get_x(mk_pair(x, y)) = 1 implies x = 1
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: get_x(mk_pair(x, y)) = 1 implies y = 1
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					y -> 0
 | 
				
			||||||
 | 
					x -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: get_x(p1) = get_x(p2) implies p1 = p2
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					p1 -> (mk_pair 1 0)
 | 
				
			||||||
 | 
					p2 -> (mk_pair 1 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					p2 -> (mk_pair 10 1)
 | 
				
			||||||
 | 
					p1 -> (mk_pair 0 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bitvector_example1
 | 
				
			||||||
 | 
					disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					x -> bv2147483656[32]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bitvector_example2
 | 
				
			||||||
 | 
					find values of x and y, such that x ^ y - 103 == x * y
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> bv3905735879[32]
 | 
				
			||||||
 | 
					x -> bv3787456528[32]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eval_example1
 | 
				
			||||||
 | 
					MODEL:
 | 
				
			||||||
 | 
					y -> 4
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					evaluating x+y
 | 
				
			||||||
 | 
					result = 7:int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					two_contexts_example1
 | 
				
			||||||
 | 
					k!0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_code_example1
 | 
				
			||||||
 | 
					last call succeeded.
 | 
				
			||||||
 | 
					last call failed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_code_example2
 | 
				
			||||||
 | 
					before Z3_mk_iff
 | 
				
			||||||
 | 
					Z3 error: type error.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example1
 | 
				
			||||||
 | 
					formula 0: (> x y)
 | 
				
			||||||
 | 
					formula 1: (> x 0)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 0
 | 
				
			||||||
 | 
					x -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example2
 | 
				
			||||||
 | 
					formula: (> x y)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> -1
 | 
				
			||||||
 | 
					x -> 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example3
 | 
				
			||||||
 | 
					assert axiom:
 | 
				
			||||||
 | 
					(forall (x Int) (y Int) (= (g x y) (g y x)) :qid {k!1})
 | 
				
			||||||
 | 
					formula: (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y))) :qid {k!1})
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example4
 | 
				
			||||||
 | 
					declaration 0: (define y Int)
 | 
				
			||||||
 | 
					declaration 1: (define sk_hack Bool Bool)
 | 
				
			||||||
 | 
					declaration 2: (define x Int)
 | 
				
			||||||
 | 
					assumption 0: (= x 20)
 | 
				
			||||||
 | 
					formula 0: (> x y)
 | 
				
			||||||
 | 
					formula 1: (> x 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example5
 | 
				
			||||||
 | 
					Z3 error: parser error.
 | 
				
			||||||
 | 
					Error message: 'ERROR: line 1 column 41: could not find sort symbol 'y'.
 | 
				
			||||||
 | 
					'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					numeral_example
 | 
				
			||||||
 | 
					Numerals n1:1/2 n2:1/2
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					Numerals n1:-1/3 n2:-33333333333333333333333333333333333333333333333333/100000000000000000000000000000000000000000000000000
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ite_example
 | 
				
			||||||
 | 
					term: (if false 1 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					list_example
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					Formula (implies (is_cons u) (= u (cons (head u) (tail u))))
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					u -> nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tree_example
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					Formula (implies (is_cons u) (= u (cons (car u) (cdr u))))
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					u -> nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					forest_example
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					binary_tree_example
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum_example
 | 
				
			||||||
 | 
					(define apple[fruit:0] fruit)
 | 
				
			||||||
 | 
					(define banana[fruit:1] fruit)
 | 
				
			||||||
 | 
					(define orange[fruit:2] fruit)
 | 
				
			||||||
 | 
					(define is_apple[fruit:0] fruit Bool)
 | 
				
			||||||
 | 
					(define is_banana[fruit:1] fruit Bool)
 | 
				
			||||||
 | 
					(define is_orange[fruit:2] fruit Bool)
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsat_core_and_proof_example
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					proof: [unit-resolution
 | 
				
			||||||
 | 
					  [def-axiom (or (or (not PredA) PredB (not PredC)) (not PredB))]
 | 
				
			||||||
 | 
					  [unit-resolution
 | 
				
			||||||
 | 
					    [def-axiom (or (or (not PredA) (not PredB) (not PredC)) PredB)]
 | 
				
			||||||
 | 
					    [unit-resolution
 | 
				
			||||||
 | 
					      [mp
 | 
				
			||||||
 | 
					        [asserted (or (and PredA PredB PredC) P1)]
 | 
				
			||||||
 | 
					        [monotonicity
 | 
				
			||||||
 | 
					          [rewrite
 | 
				
			||||||
 | 
					            (iff (and PredA PredB PredC)
 | 
				
			||||||
 | 
					                 (not (or (not PredA) (not PredB) (not PredC))))]
 | 
				
			||||||
 | 
					          (iff (or (and PredA PredB PredC) P1)
 | 
				
			||||||
 | 
					               (or (not (or (not PredA) (not PredB) (not PredC))) P1))]
 | 
				
			||||||
 | 
					        (or (not (or (not PredA) (not PredB) (not PredC))) P1)]
 | 
				
			||||||
 | 
					      [asserted (not P1)]
 | 
				
			||||||
 | 
					      (not (or (not PredA) (not PredB) (not PredC)))]
 | 
				
			||||||
 | 
					    PredB]
 | 
				
			||||||
 | 
					  [unit-resolution
 | 
				
			||||||
 | 
					    [mp
 | 
				
			||||||
 | 
					      [asserted (or (and PredA (not PredB) PredC) P2)]
 | 
				
			||||||
 | 
					      [monotonicity
 | 
				
			||||||
 | 
					        [rewrite
 | 
				
			||||||
 | 
					          (iff (and PredA (not PredB) PredC)
 | 
				
			||||||
 | 
					               (not (or (not PredA) PredB (not PredC))))]
 | 
				
			||||||
 | 
					        (iff (or (and PredA (not PredB) PredC) P2)
 | 
				
			||||||
 | 
					             (or (not (or (not PredA) PredB (not PredC))) P2))]
 | 
				
			||||||
 | 
					      (or (not (or (not PredA) PredB (not PredC))) P2)]
 | 
				
			||||||
 | 
					    [asserted (not P2)]
 | 
				
			||||||
 | 
					    (not (or (not PredA) PredB (not PredC)))]
 | 
				
			||||||
 | 
					  false]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					core:
 | 
				
			||||||
 | 
					(not P1)
 | 
				
			||||||
 | 
					(not P2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					get_implied_equalities example
 | 
				
			||||||
 | 
					Class a |-> 0
 | 
				
			||||||
 | 
					Class b |-> 0
 | 
				
			||||||
 | 
					Class c |-> 0
 | 
				
			||||||
 | 
					Class d |-> 3
 | 
				
			||||||
 | 
					Class (f a) |-> 0
 | 
				
			||||||
 | 
					Class (f b) |-> 0
 | 
				
			||||||
 | 
					Class (f c) |-> 0
 | 
				
			||||||
 | 
					asserting f(a) <= b
 | 
				
			||||||
 | 
					Class a |-> 0
 | 
				
			||||||
 | 
					Class b |-> 0
 | 
				
			||||||
 | 
					Class c |-> 0
 | 
				
			||||||
 | 
					Class d |-> 3
 | 
				
			||||||
 | 
					Class (f a) |-> 0
 | 
				
			||||||
 | 
					Class (f b) |-> 0
 | 
				
			||||||
 | 
					Class (f c) |-> 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					incremental_example1
 | 
				
			||||||
 | 
					unsat core: 0 2 3 
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					unsat core: 0 2 3 
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					unsat core: 0 2 3 
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					reference_counter_example
 | 
				
			||||||
 | 
					model for: x xor y
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> false
 | 
				
			||||||
 | 
					x -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					smt2parser_example
 | 
				
			||||||
 | 
					formulas: (and (bvuge a bv16[8]) (bvule a bv240[8]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					substitute_example
 | 
				
			||||||
 | 
					substitution result: (f (f a 0) 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					substitute_vars_example
 | 
				
			||||||
 | 
					substitution result: (f (f a (g b)) a)
 | 
				
			||||||
							
								
								
									
										58
									
								
								ml/test_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								ml/test_mlapi.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					SETLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Script to test the Z3 OCaml API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing z3_api.h
 | 
				
			||||||
 | 
					set Z3SRC=%1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing z3.dll and z3.lib
 | 
				
			||||||
 | 
					set Z3BIN=%2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM directory containing debug z3.dll
 | 
				
			||||||
 | 
					set Z3BINDBG=%3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set PATH=.;%2;%3;%PATH%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Build test_capi
 | 
				
			||||||
 | 
					cl /nologo /I %Z3SRC% %Z3BIN%\z3.lib ..\test_capi\test_capi.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Build test_mlapi
 | 
				
			||||||
 | 
					ocamlc -w -a -o test_mlapi.byte.exe z3.cma test_mlapi.ml
 | 
				
			||||||
 | 
					ocamlopt -w -a -o test_mlapi.exe z3.cmxa test_mlapi.ml
 | 
				
			||||||
 | 
					ocamlc -g -w -a -o test_mlapi.byte.dbg.exe z3_dbg.cma test_mlapi.ml
 | 
				
			||||||
 | 
					ocamlopt -g -w -a -o test_mlapi.dbg.exe z3_dbg.cmxa test_mlapi.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Build test_mlapiV3
 | 
				
			||||||
 | 
					ocamlopt -g -w -a -o test_mlapiV3.dbg.exe z3_dbg.cmxa test_mlapiV3.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Build test_theory
 | 
				
			||||||
 | 
					ocamlopt -g -w -a -o test_theory.dbg.exe z3_dbg.cmxa test_theory.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Build queen
 | 
				
			||||||
 | 
					ocamlopt -g -w -a -o queen.exe z3_dbg.cmxa queen.ml
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo Execute test_capi, test_mlapi, test_mlapiV3 and queen
 | 
				
			||||||
 | 
					test_capi.exe >test_capi.out 2>test_capi.orig.err
 | 
				
			||||||
 | 
					test_mlapi.dbg.exe >test_mlapi.out 2>test_mlapi.orig.err
 | 
				
			||||||
 | 
					test_mlapiV3.dbg.exe >test_mlapiV3.out 2>test_mlapiV3.orig.err
 | 
				
			||||||
 | 
					queen.exe >queen.out 2>queen.orig.err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Strip pointers as they will always differ
 | 
				
			||||||
 | 
					sed <test_capi.orig.err >test_capi.err "s/ \[.*\]/ [...]/g"
 | 
				
			||||||
 | 
					sed <test_mlapi.orig.err >test_mlapi.err "s/ \[.*\]/ [...]/g"
 | 
				
			||||||
 | 
					sed <test_mlapiV3.orig.err >test_mlapiV3.err "s/ \[.*\]/ [...]/g"
 | 
				
			||||||
 | 
					sed <queen.orig.err >queen.err "s/ \[.*\]/ [...]/g"
 | 
				
			||||||
 | 
					del test_capi.orig.err test_mlapi.orig.err test_mlapiV3.orig.err queen.orig.err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					REM Compare with regressions
 | 
				
			||||||
 | 
					diff test_capi.regress.out test_capi.out >NUL || echo Regression failed, see: windiff test_capi.regress.out test_capi.out
 | 
				
			||||||
 | 
					diff test_mlapi.regress.out test_mlapi.out >NUL || echo Regression failed, see: windiff test_mlapi.regress.out test_mlapi.out
 | 
				
			||||||
 | 
					diff test_mlapiV3.regress.out test_mlapiV3.out >NUL || echo Regression failed, see: windiff test_mlapiV3.regress.out test_mlapiV3.out
 | 
				
			||||||
 | 
					diff test_capi.regress.err test_capi.err >NUL || echo Regression failed, see: windiff test_capi.regress.err test_capi.err
 | 
				
			||||||
 | 
					diff test_mlapi.regress.err test_mlapi.err >NUL || echo Regression failed, see: windiff test_mlapi.regress.err test_mlapi.err
 | 
				
			||||||
 | 
					diff test_mlapiV3.regress.err test_mlapiV3.err >NUL || echo Regression failed, see: windiff test_mlapiV3.regress.err test_mlapiV3.err
 | 
				
			||||||
 | 
					diff queen.regress.out queen.out >NUL || echo Regression failed, see: windiff queen.regress.out queen.out
 | 
				
			||||||
 | 
					diff queen.regress.err queen.err >NUL || echo Regression failed, see: windiff queen.regress.err queen.err
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ENDLOCAL
 | 
				
			||||||
							
								
								
									
										209
									
								
								ml/test_mlapi.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										209
									
								
								ml/test_mlapi.ml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,209 @@
 | 
				
			||||||
 | 
					(** Examples of using the OCaml API for Z3. *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**/**)
 | 
				
			||||||
 | 
					(* pause documentation *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(*
 | 
				
			||||||
 | 
					   @name Auxiliary Functions
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   printf
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let printf = Printf.printf
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   fprintf
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let fprintf = Printf.fprintf
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Exit gracefully in case of error.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let exitf message = fprintf stderr "BUG: %s.\n" message ; exit 1
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Create and print datatypes
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let mk_datatypes ctx generator =
 | 
				
			||||||
 | 
					  let datatypes = Z3.mk_datatypes ctx generator in
 | 
				
			||||||
 | 
					  printf "datatype created:\n%!" ;
 | 
				
			||||||
 | 
					  Array.iter (fun (sort, ctors) ->
 | 
				
			||||||
 | 
					    printf "sort: %s\n%!" (Z3.sort_to_string ctx sort) ;
 | 
				
			||||||
 | 
					    Array.iter (fun {Z3.constructor; recognizer; accessors} ->
 | 
				
			||||||
 | 
					      printf "constructor: %s%! recognizer: %s%! accessors:"
 | 
				
			||||||
 | 
					        (Z3.func_decl_to_string ctx constructor)
 | 
				
			||||||
 | 
					        (Z3.func_decl_to_string ctx recognizer) ;
 | 
				
			||||||
 | 
					      Array.iter (fun accessor ->
 | 
				
			||||||
 | 
					        printf " %s%!" (Z3.func_decl_to_string ctx accessor)
 | 
				
			||||||
 | 
					      ) accessors ;
 | 
				
			||||||
 | 
					      printf "\n"
 | 
				
			||||||
 | 
					    ) ctors
 | 
				
			||||||
 | 
					  ) datatypes ;
 | 
				
			||||||
 | 
					  printf "\n" ;
 | 
				
			||||||
 | 
					  datatypes
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Create a variable using the given name and type.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let mk_var ctx name ty = Z3.mk_const ctx (Z3.mk_string_symbol ctx name) ty
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* resume documentation *)
 | 
				
			||||||
 | 
					(**/**)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Prove that the constraints already asserted into the logical
 | 
				
			||||||
 | 
					   context implies the given formula.  The result of the proof is
 | 
				
			||||||
 | 
					   displayed.
 | 
				
			||||||
 | 
					   Z3 is a satisfiability checker. So, one can prove {e f } by showing
 | 
				
			||||||
 | 
					   that {e (not f) } is unsatisfiable.
 | 
				
			||||||
 | 
					   The context {e ctx } is not modified by this function.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let prove ctx slv f is_valid =
 | 
				
			||||||
 | 
					  (* save the current state of the context *)
 | 
				
			||||||
 | 
					  Z3.solver_push ctx slv ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let not_f = Z3.mk_not ctx f in
 | 
				
			||||||
 | 
					  Z3.solver_assert ctx slv not_f ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (match Z3.solver_check ctx slv with
 | 
				
			||||||
 | 
					  | Z3.L_FALSE ->
 | 
				
			||||||
 | 
					      (* proved *)
 | 
				
			||||||
 | 
					      printf "valid\n" ;
 | 
				
			||||||
 | 
					      if not is_valid then exitf "unexpected result"
 | 
				
			||||||
 | 
					  | Z3.L_UNDEF ->
 | 
				
			||||||
 | 
					      (* Z3 failed to prove/disprove f. *)
 | 
				
			||||||
 | 
					      printf "unknown\n" ;
 | 
				
			||||||
 | 
					      let m = Z3.solver_get_model ctx slv in
 | 
				
			||||||
 | 
					      (* m should be viewed as a potential counterexample. *)
 | 
				
			||||||
 | 
					      printf "potential counterexample:\n%s\n" (Z3.model_to_string ctx m) ;
 | 
				
			||||||
 | 
					      if is_valid then exitf "unexpected result"
 | 
				
			||||||
 | 
					  | Z3.L_TRUE ->
 | 
				
			||||||
 | 
					      (* disproved *)
 | 
				
			||||||
 | 
					      printf "invalid\n" ;
 | 
				
			||||||
 | 
					      let m = Z3.solver_get_model ctx slv in
 | 
				
			||||||
 | 
					      (* the model returned by Z3 is a counterexample *)
 | 
				
			||||||
 | 
					      printf "counterexample:\n%s\n" (Z3.model_to_string ctx m) ;
 | 
				
			||||||
 | 
					      if is_valid then exitf "unexpected result"
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					  (* restore context *)
 | 
				
			||||||
 | 
					  Z3.solver_pop ctx slv 1
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* n-ary trees and forests in OCaml *)
 | 
				
			||||||
 | 
					type tree = Leaf of int | Node of forest
 | 
				
			||||||
 | 
					and forest = tree list
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					   Demonstrates the usage of {!Z3.mk_datatypes} with an example of forests of trees.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					let forest_example () =
 | 
				
			||||||
 | 
					  let ctx = Z3.mk_context [] in
 | 
				
			||||||
 | 
					  let slv = Z3.mk_solver ctx
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let int_sort = Z3.mk_int_sort ctx in
 | 
				
			||||||
 | 
					  let sym name = Z3.mk_string_symbol ctx name
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  (* n-ary trees and forests in Z3 *)
 | 
				
			||||||
 | 
					  match
 | 
				
			||||||
 | 
					    mk_datatypes ctx
 | 
				
			||||||
 | 
					      (function [|tree; forest|] -> Some
 | 
				
			||||||
 | 
					        [|(sym"tree",
 | 
				
			||||||
 | 
					           [|{Z3.constructor_desc= sym"leaf"; recognizer_desc= sym"is_leaf"; accessor_descs= [|(sym"data", int_sort)|]};
 | 
				
			||||||
 | 
					             {Z3.constructor_desc= sym"node"; recognizer_desc= sym"is_node"; accessor_descs= [|(sym"children", forest)|]}|]);
 | 
				
			||||||
 | 
					          (sym"forest",
 | 
				
			||||||
 | 
					           [|{Z3.constructor_desc= sym"nil" ; recognizer_desc= sym"is_nil" ; accessor_descs= [||]};
 | 
				
			||||||
 | 
					             {Z3.constructor_desc= sym"cons"; recognizer_desc= sym"is_cons"; accessor_descs= [|(sym"hd", tree); (sym"tl", forest)|]}|])|]
 | 
				
			||||||
 | 
					        | _ -> None
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					  with
 | 
				
			||||||
 | 
					    [|(tree,
 | 
				
			||||||
 | 
					       [|{Z3.constructor= leaf; recognizer= is_leaf; accessors= [|data|]};
 | 
				
			||||||
 | 
					         {Z3.constructor= node; recognizer= is_node; accessors= [|children|]}|]);
 | 
				
			||||||
 | 
					      (forest,
 | 
				
			||||||
 | 
					       [|{Z3.constructor= nil ; recognizer= is_nil ; accessors= [||]};
 | 
				
			||||||
 | 
					         {Z3.constructor= cons; recognizer= is_cons; accessors= [|hd; tl|]}|])|]
 | 
				
			||||||
 | 
					    ->
 | 
				
			||||||
 | 
					      (* translate from OCaml to Z3 *)
 | 
				
			||||||
 | 
					      let rec ml2z3_tree = function
 | 
				
			||||||
 | 
					        | Leaf(i) -> Z3.mk_app ctx leaf [|Z3.mk_int ctx i (Z3.mk_int_sort ctx)|]
 | 
				
			||||||
 | 
					        | Node(f) -> Z3.mk_app ctx node [|ml2z3_forest f|]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      and ml2z3_forest = function
 | 
				
			||||||
 | 
					        | [] -> Z3.mk_app ctx nil [||]
 | 
				
			||||||
 | 
					        | t :: f -> Z3.mk_app ctx cons [|ml2z3_tree t; ml2z3_forest f|]
 | 
				
			||||||
 | 
					      in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* construct some OCaml trees *)
 | 
				
			||||||
 | 
					      let t0 = Leaf 0 in
 | 
				
			||||||
 | 
					      let t12 = Node [Leaf 1; Leaf 2] in
 | 
				
			||||||
 | 
					      let t123 = Node [t12; Leaf 3] in
 | 
				
			||||||
 | 
					      let t1212 = Node [t12; t12] in
 | 
				
			||||||
 | 
					      let t412 = Node [Leaf 4; t12] in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* construct some Z3 trees using the translation from OCaml *)
 | 
				
			||||||
 | 
					      let t1 = ml2z3_tree t12 in		printf "t1: %s\n%!" (Z3.ast_to_string ctx t1) ;
 | 
				
			||||||
 | 
					      let t2 = ml2z3_tree t123 in		printf "t2: %s\n%!" (Z3.ast_to_string ctx t2) ;
 | 
				
			||||||
 | 
					      let t3 = ml2z3_tree t1212 in		printf "t3: %s\n%!" (Z3.ast_to_string ctx t3) ;
 | 
				
			||||||
 | 
					      let t4 = ml2z3_tree t412 in		printf "t4: %s\n%!" (Z3.ast_to_string ctx t4) ;
 | 
				
			||||||
 | 
					      let f1 = ml2z3_forest [t0] in		printf "f1: %s\n%!" (Z3.ast_to_string ctx f1) ;
 | 
				
			||||||
 | 
					      let f2 = ml2z3_forest [t12] in		printf "f2: %s\n%!" (Z3.ast_to_string ctx f2) ;
 | 
				
			||||||
 | 
					      let f3 = ml2z3_forest [t12; t0] in	printf "f3: %s\n%!" (Z3.ast_to_string ctx f3) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* or using the Z3 API *)
 | 
				
			||||||
 | 
					      let nil = Z3.mk_app ctx nil [||] in
 | 
				
			||||||
 | 
					      let cons t f = Z3.mk_app ctx cons [|t; f|] in
 | 
				
			||||||
 | 
					      let leaf i = Z3.mk_app ctx leaf [|Z3.mk_int ctx i (Z3.mk_int_sort ctx)|] in
 | 
				
			||||||
 | 
					      let node f = Z3.mk_app ctx node [|f|] in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let t0 = leaf 0 in
 | 
				
			||||||
 | 
					      let t12 = node (cons (leaf 1) (cons (leaf 2) nil)) in
 | 
				
			||||||
 | 
					      let t123 = node (cons t12 (cons (leaf 3) nil)) in
 | 
				
			||||||
 | 
					      let t1212 = node (cons t12 (cons t12 nil)) in
 | 
				
			||||||
 | 
					      let t412 = node (cons (leaf 4) (cons t12 nil)) in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      let t1 = t12 in				printf "t1: %s\n%!" (Z3.ast_to_string ctx t1) ;
 | 
				
			||||||
 | 
					      let t2 = t123 in				printf "t2: %s\n%!" (Z3.ast_to_string ctx t2) ;
 | 
				
			||||||
 | 
					      let t3 = t1212 in				printf "t3: %s\n%!" (Z3.ast_to_string ctx t3) ;
 | 
				
			||||||
 | 
					      let t4 = t412 in				printf "t4: %s\n%!" (Z3.ast_to_string ctx t4) ;
 | 
				
			||||||
 | 
					      let f1 = cons t0 nil in			printf "f1: %s\n%!" (Z3.ast_to_string ctx f1) ;
 | 
				
			||||||
 | 
					      let f2 = cons t12 nil in			printf "f2: %s\n%!" (Z3.ast_to_string ctx f2) ;
 | 
				
			||||||
 | 
					      let f3 = cons t12 f1 in			printf "f3: %s\n%!" (Z3.ast_to_string ctx f3) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* nil != cons(nil,nil) *)
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx nil f1)) true ;
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx (leaf 5) t1)) true ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* cons(x,u) = cons(x, v) => u = v *)
 | 
				
			||||||
 | 
					      let u = mk_var ctx "u" forest in
 | 
				
			||||||
 | 
					      let v = mk_var ctx "v" forest in
 | 
				
			||||||
 | 
					      let x = mk_var ctx "x" tree in
 | 
				
			||||||
 | 
					      let y = mk_var ctx "y" tree in
 | 
				
			||||||
 | 
					      let l1 = cons x u in			printf "l1: %s\n%!" (Z3.ast_to_string ctx l1) ;
 | 
				
			||||||
 | 
					      let l2 = cons y v in			printf "l2: %s\n%!" (Z3.ast_to_string ctx l2) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_implies ctx (Z3.mk_eq ctx l1 l2) (Z3.mk_eq ctx u v)) true ;
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_implies ctx (Z3.mk_eq ctx l1 l2) (Z3.mk_eq ctx x y)) true ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* is_nil(u) or is_cons(u) *)
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_or ctx [|Z3.mk_app ctx is_nil [|u|]; Z3.mk_app ctx is_cons [|u|]|]) true ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* occurs check u != cons(x,u) *)
 | 
				
			||||||
 | 
					      prove ctx slv (Z3.mk_not ctx (Z3.mk_eq ctx u l1)) true ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  | _ ->
 | 
				
			||||||
 | 
					      exitf "unexpected datatype signature"
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let _ =
 | 
				
			||||||
 | 
					  ignore( Z3.open_log "test_mlapi.log" );
 | 
				
			||||||
 | 
					  forest_example () ;
 | 
				
			||||||
 | 
					;;
 | 
				
			||||||
							
								
								
									
										0
									
								
								ml/test_mlapi.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ml/test_mlapi.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										32
									
								
								ml/test_mlapi.regress.out
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								ml/test_mlapi.regress.out
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,32 @@
 | 
				
			||||||
 | 
					datatype created:
 | 
				
			||||||
 | 
					sort: tree
 | 
				
			||||||
 | 
					constructor: (define leaf[tree:0] Int tree) recognizer: (define is_leaf[tree:0] tree Bool) accessors: (define data[tree:0:0] tree Int)
 | 
				
			||||||
 | 
					constructor: (define node[tree:1] forest tree) recognizer: (define is_node[tree:1] tree Bool) accessors: (define children[tree:1:0] tree forest)
 | 
				
			||||||
 | 
					sort: forest
 | 
				
			||||||
 | 
					constructor: (define nil[forest:0] forest) recognizer: (define is_nil[forest:0] forest Bool) accessors:
 | 
				
			||||||
 | 
					constructor: (define cons[forest:1] tree forest forest) recognizer: (define is_cons[forest:1] forest Bool) accessors: (define hd[forest:1:0] forest tree) (define tl[forest:1:1] forest forest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					t1: (node (cons (leaf 1) (cons (leaf 2) nil)))
 | 
				
			||||||
 | 
					t2: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 3) nil)))
 | 
				
			||||||
 | 
					t3: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil)))
 | 
				
			||||||
 | 
					            (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)))
 | 
				
			||||||
 | 
					t4: (node (cons (leaf 4) (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)))
 | 
				
			||||||
 | 
					f1: (cons (leaf 0) nil)
 | 
				
			||||||
 | 
					f2: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)
 | 
				
			||||||
 | 
					f3: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 0) nil))
 | 
				
			||||||
 | 
					t1: (node (cons (leaf 1) (cons (leaf 2) nil)))
 | 
				
			||||||
 | 
					t2: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 3) nil)))
 | 
				
			||||||
 | 
					t3: (node (cons (node (cons (leaf 1) (cons (leaf 2) nil)))
 | 
				
			||||||
 | 
					            (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)))
 | 
				
			||||||
 | 
					t4: (node (cons (leaf 4) (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)))
 | 
				
			||||||
 | 
					f1: (cons (leaf 0) nil)
 | 
				
			||||||
 | 
					f2: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) nil)
 | 
				
			||||||
 | 
					f3: (cons (node (cons (leaf 1) (cons (leaf 2) nil))) (cons (leaf 0) nil))
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					l1: (cons x u)
 | 
				
			||||||
 | 
					l2: (cons y v)
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
							
								
								
									
										1418
									
								
								ml/test_mlapiV3.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1418
									
								
								ml/test_mlapiV3.ml
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										5
									
								
								ml/test_mlapiV3.regress.err
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ml/test_mlapiV3.regress.err
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,5 @@
 | 
				
			||||||
 | 
					WARNING: invalid function application, sort mismatch on argument at position 1
 | 
				
			||||||
 | 
					WARNING: (define iff Bool Bool Bool) applied to: 
 | 
				
			||||||
 | 
					x of sort Int
 | 
				
			||||||
 | 
					y of sort Bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										312
									
								
								ml/test_mlapiV3.regress.out
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										312
									
								
								ml/test_mlapiV3.regress.out
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,312 @@
 | 
				
			||||||
 | 
					Z3 4.0.0.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					simple_example
 | 
				
			||||||
 | 
					CONTEXT:
 | 
				
			||||||
 | 
					(solver)END OF CONTEXT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DeMorgan
 | 
				
			||||||
 | 
					DeMorgan is valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_model_example1
 | 
				
			||||||
 | 
					model for: x xor y
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> false
 | 
				
			||||||
 | 
					x -> true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_model_example2
 | 
				
			||||||
 | 
					model for: x < y + 1, x > 2
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 3
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					model for: x < y + 1, x > 2, not(x = y)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 4
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove_example1
 | 
				
			||||||
 | 
					prove: x = y implies g(x) = g(y)
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: x = y implies g(g(x)) = g(y)
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					y -> U!val!0
 | 
				
			||||||
 | 
					x -> U!val!0
 | 
				
			||||||
 | 
					g -> {
 | 
				
			||||||
 | 
					  U!val!0 -> U!val!1
 | 
				
			||||||
 | 
					  U!val!1 -> U!val!2
 | 
				
			||||||
 | 
					  else -> U!val!1
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove_example2
 | 
				
			||||||
 | 
					prove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < 0
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: not(g(g(x) - g(y)) = g(z)), x + z <= y <= x implies z < -1
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					z -> -1
 | 
				
			||||||
 | 
					y -> -7719
 | 
				
			||||||
 | 
					x -> -7719
 | 
				
			||||||
 | 
					g -> {
 | 
				
			||||||
 | 
					  -7719 -> 0
 | 
				
			||||||
 | 
					  0 -> 2
 | 
				
			||||||
 | 
					  -1 -> 3
 | 
				
			||||||
 | 
					  else -> 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					push_pop_example1
 | 
				
			||||||
 | 
					assert: x >= 'big number'
 | 
				
			||||||
 | 
					push
 | 
				
			||||||
 | 
					number of scopes: 1
 | 
				
			||||||
 | 
					assert: x <= 3
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					pop
 | 
				
			||||||
 | 
					number of scopes: 0
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					x = 1000000000000000000000000000000000000000000000000000000:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					assert: y > x
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y = 1000000000000000000000000000000000000000000000000000001:int
 | 
				
			||||||
 | 
					x = 1000000000000000000000000000000000000000000000000000000:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quantifier_example1
 | 
				
			||||||
 | 
					pattern: {(f #0 #1)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					assert axiom:
 | 
				
			||||||
 | 
					(forall (k!0 Int) (k!1 Int) (= (inv!0 (f k!1 k!0)) k!0) :pat {(f k!1 k!0)})
 | 
				
			||||||
 | 
					prove: f(x, y) = f(w, v) implies y = v
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: f(x, y) = f(w, v) implies x = w
 | 
				
			||||||
 | 
					that is: not(f(x, y) = f(w, v) implies x = w) is satisfiable
 | 
				
			||||||
 | 
					unknown
 | 
				
			||||||
 | 
					potential model:
 | 
				
			||||||
 | 
					w = 2:int
 | 
				
			||||||
 | 
					v = 1:int
 | 
				
			||||||
 | 
					y = 1:int
 | 
				
			||||||
 | 
					x = 0:int
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					f = {(0:int, 1:int|->3:int), (2:int, 1:int|->3:int), (else|->3:int)}
 | 
				
			||||||
 | 
					inv!0 = {(3:int|->1:int), (else|->1:int)}
 | 
				
			||||||
 | 
					reason for last failure: 7 (7 = quantifiers)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example1
 | 
				
			||||||
 | 
					prove: store(a1, i1, v1) = store(a2, i2, v2) implies (i1 = i3 or i2 = i3 or select(a1, i3) = select(a2, i3))
 | 
				
			||||||
 | 
					(implies (= (store a1 i1 v1) (store a2 i2 v2))
 | 
				
			||||||
 | 
					         (or (= i1 i3) (= i2 i3) (= (select a1 i3) (select a2 i3))))
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example2
 | 
				
			||||||
 | 
					n = 2
 | 
				
			||||||
 | 
					(distinct k!0 k!1)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#1 = {((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 3
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					#2 = (define as-array[k!2] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#1 = {((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#2 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 4
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2 k!3)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					#0 = (define as-array[k!0] (Array Bool Bool))
 | 
				
			||||||
 | 
					#1 = (define as-array[k!1] (Array Bool Bool))
 | 
				
			||||||
 | 
					#2 = (define as-array[k!2] (Array Bool Bool))
 | 
				
			||||||
 | 
					#3 = (define as-array[k!3] (Array Bool Bool))
 | 
				
			||||||
 | 
					function interpretations:
 | 
				
			||||||
 | 
					#0 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define true Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					#1 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define false Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#2 = {((define true Bool)|->(define true Bool)), ((define false Bool)|->(define true Bool)), (else|->(define true Bool))}
 | 
				
			||||||
 | 
					#3 = {((define true Bool)|->(define false Bool)), ((define false Bool)|->(define false Bool)), (else|->(define false Bool))}
 | 
				
			||||||
 | 
					n = 5
 | 
				
			||||||
 | 
					(distinct k!0 k!1 k!2 k!3 k!4)
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					array_example3
 | 
				
			||||||
 | 
					domain: int
 | 
				
			||||||
 | 
					range:  bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tuple_example1
 | 
				
			||||||
 | 
					tuple_sort: (real, real)
 | 
				
			||||||
 | 
					prove: get_x(mk_pair(x, y)) = 1 implies x = 1
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: get_x(mk_pair(x, y)) = 1 implies y = 1
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					y -> 0
 | 
				
			||||||
 | 
					x -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove: get_x(p1) = get_x(p2) and get_y(p1) = get_y(p2) implies p1 = p2
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: get_x(p1) = get_x(p2) implies p1 = p2
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					p1 -> (mk_pair 1 0)
 | 
				
			||||||
 | 
					p2 -> (mk_pair 1 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					prove: p2 = update(p1, 0, 10) implies get_x(p2) = 10
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					disprove: p2 = update(p1, 0, 10) implies get_y(p2) = 10
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					p2 -> (mk_pair 10 1)
 | 
				
			||||||
 | 
					p1 -> (mk_pair 0 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bitvector_example1
 | 
				
			||||||
 | 
					disprove: x - 10 <= 0 IFF x <= 10 for (32-bit) machine integers
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					x -> bv2147483656[32]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bitvector_example2
 | 
				
			||||||
 | 
					find values of x and y, such that x ^ y - 103 == x * y
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> bv3905735879[32]
 | 
				
			||||||
 | 
					x -> bv3787456528[32]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eval_example1
 | 
				
			||||||
 | 
					MODEL:
 | 
				
			||||||
 | 
					y -> 4
 | 
				
			||||||
 | 
					x -> 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					evaluating x+y
 | 
				
			||||||
 | 
					result = 7:int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					two_contexts_example1
 | 
				
			||||||
 | 
					k!0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_code_example1
 | 
				
			||||||
 | 
					last call succeeded.
 | 
				
			||||||
 | 
					last call failed.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					error_code_example2
 | 
				
			||||||
 | 
					before Z3_mk_iff
 | 
				
			||||||
 | 
					Z3 error: type error.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example1
 | 
				
			||||||
 | 
					formula 0: (> x y)
 | 
				
			||||||
 | 
					formula 1: (> x 0)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> 0
 | 
				
			||||||
 | 
					x -> 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example2
 | 
				
			||||||
 | 
					formula: (> x y)
 | 
				
			||||||
 | 
					sat
 | 
				
			||||||
 | 
					y -> -1
 | 
				
			||||||
 | 
					x -> 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example3
 | 
				
			||||||
 | 
					assert axiom:
 | 
				
			||||||
 | 
					(forall (x Int) (y Int) (= (g x y) (g y x)) :qid {k!1})
 | 
				
			||||||
 | 
					formula: (forall (x Int) (y Int) (implies (= x y) (= (g x 0) (g 0 y))) :qid {k!1})
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example4
 | 
				
			||||||
 | 
					declaration 0: (define y Int)
 | 
				
			||||||
 | 
					declaration 1: (define sk_hack Bool Bool)
 | 
				
			||||||
 | 
					declaration 2: (define x Int)
 | 
				
			||||||
 | 
					assumption 0: (= x 20)
 | 
				
			||||||
 | 
					formula 0: (> x y)
 | 
				
			||||||
 | 
					formula 1: (> x 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					parser_example5
 | 
				
			||||||
 | 
					Z3 error: parser error.
 | 
				
			||||||
 | 
					Error message: 'ERROR: line 1 column 41: could not find sort symbol 'y'.
 | 
				
			||||||
 | 
					'.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ite_example
 | 
				
			||||||
 | 
					term: (if false 1 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum_example
 | 
				
			||||||
 | 
					(define apple[fruit:0] fruit)
 | 
				
			||||||
 | 
					(define banana[fruit:1] fruit)
 | 
				
			||||||
 | 
					(define orange[fruit:2] fruit)
 | 
				
			||||||
 | 
					(define is_apple[fruit:0] fruit Bool)
 | 
				
			||||||
 | 
					(define is_banana[fruit:1] fruit Bool)
 | 
				
			||||||
 | 
					(define is_orange[fruit:2] fruit Bool)
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					invalid
 | 
				
			||||||
 | 
					counterexample:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					valid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsat_core_and_proof_example
 | 
				
			||||||
 | 
					unsat
 | 
				
			||||||
 | 
					proof: [unit-resolution
 | 
				
			||||||
 | 
					  [def-axiom (or (or (not PredA) PredC (not PredB)) (not PredC))]
 | 
				
			||||||
 | 
					  [unit-resolution
 | 
				
			||||||
 | 
					    [def-axiom (or (or (not PredA) (not PredB) (not PredC)) PredC)]
 | 
				
			||||||
 | 
					    [unit-resolution
 | 
				
			||||||
 | 
					      [mp
 | 
				
			||||||
 | 
					        [asserted (or (and PredA PredB PredC) P1)]
 | 
				
			||||||
 | 
					        [monotonicity
 | 
				
			||||||
 | 
					          [rewrite
 | 
				
			||||||
 | 
					            (iff (and PredA PredB PredC)
 | 
				
			||||||
 | 
					                 (not (or (not PredA) (not PredB) (not PredC))))]
 | 
				
			||||||
 | 
					          (iff (or (and PredA PredB PredC) P1)
 | 
				
			||||||
 | 
					               (or (not (or (not PredA) (not PredB) (not PredC))) P1))]
 | 
				
			||||||
 | 
					        (or (not (or (not PredA) (not PredB) (not PredC))) P1)]
 | 
				
			||||||
 | 
					      [asserted (not P1)]
 | 
				
			||||||
 | 
					      (not (or (not PredA) (not PredB) (not PredC)))]
 | 
				
			||||||
 | 
					    PredC]
 | 
				
			||||||
 | 
					  [unit-resolution
 | 
				
			||||||
 | 
					    [mp
 | 
				
			||||||
 | 
					      [asserted (or (and PredA (not PredC) PredB) P2)]
 | 
				
			||||||
 | 
					      [monotonicity
 | 
				
			||||||
 | 
					        [rewrite
 | 
				
			||||||
 | 
					          (iff (and PredA (not PredC) PredB)
 | 
				
			||||||
 | 
					               (not (or (not PredA) PredC (not PredB))))]
 | 
				
			||||||
 | 
					        (iff (or (and PredA (not PredC) PredB) P2)
 | 
				
			||||||
 | 
					             (or (not (or (not PredA) PredC (not PredB))) P2))]
 | 
				
			||||||
 | 
					      (or (not (or (not PredA) PredC (not PredB))) P2)]
 | 
				
			||||||
 | 
					    [asserted (not P2)]
 | 
				
			||||||
 | 
					    (not (or (not PredA) PredC (not PredB)))]
 | 
				
			||||||
 | 
					  false]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					core:
 | 
				
			||||||
 | 
					(not P2)
 | 
				
			||||||
 | 
					(not P1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					abstract_example
 | 
				
			||||||
 | 
					formula: (> x y)
 | 
				
			||||||
 | 
					abstracted formula: (> #0 y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					get_implied_equalities example
 | 
				
			||||||
 | 
					Class a |-> 0
 | 
				
			||||||
 | 
					Class b |-> 0
 | 
				
			||||||
 | 
					Class c |-> 0
 | 
				
			||||||
 | 
					Class d |-> 3
 | 
				
			||||||
 | 
					Class (f a) |-> 0
 | 
				
			||||||
 | 
					Class (f b) |-> 0
 | 
				
			||||||
 | 
					Class (f c) |-> 0
 | 
				
			||||||
 | 
					asserting f(a) <= b
 | 
				
			||||||
 | 
					Class a |-> 0
 | 
				
			||||||
 | 
					Class b |-> 0
 | 
				
			||||||
 | 
					Class c |-> 0
 | 
				
			||||||
 | 
					Class d |-> 3
 | 
				
			||||||
 | 
					Class (f a) |-> 0
 | 
				
			||||||
 | 
					Class (f b) |-> 0
 | 
				
			||||||
 | 
					Class (f c) |-> 0
 | 
				
			||||||
							
								
								
									
										42
									
								
								ml/test_theory.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								ml/test_theory.ml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,42 @@
 | 
				
			||||||
 | 
					module Z3 = Z3.V3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let print_lbool lb = 
 | 
				
			||||||
 | 
					    match lb with
 | 
				
			||||||
 | 
					    | Z3.L_FALSE -> Printf.printf "false\n"
 | 
				
			||||||
 | 
					    | Z3.L_TRUE -> Printf.printf "true\n"
 | 
				
			||||||
 | 
					    | Z3.L_UNDEF -> Printf.printf "undef\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* simple sanity test of theory plugin *)
 | 
				
			||||||
 | 
					let test_theory() =
 | 
				
			||||||
 | 
					    let ctx = Z3.mk_context_x [| |] in
 | 
				
			||||||
 | 
					    let th  = Z3.mk_theory ctx "test-theory" in
 | 
				
			||||||
 | 
					    let _   = Z3.set_push_callback th (fun () -> Printf.printf "push\n") in 
 | 
				
			||||||
 | 
					    let _   = Z3.set_pop_callback th (fun () -> Printf.printf "pop\n") in 
 | 
				
			||||||
 | 
					    let _   = Z3.set_delete_callback th (fun () -> Printf.printf "delete\n") in 
 | 
				
			||||||
 | 
					    let _   = Z3.set_final_check_callback th (fun () -> (Printf.printf "final\n"; true)) in 
 | 
				
			||||||
 | 
					    let _   = Z3.set_delete_callback th (fun () -> Printf.printf "deleted\n") in
 | 
				
			||||||
 | 
					    let f_sym = Z3.mk_string_symbol ctx "f" in
 | 
				
			||||||
 | 
					    let a_sym = Z3.mk_string_symbol ctx "a" in
 | 
				
			||||||
 | 
					    let b_sym = Z3.mk_string_symbol ctx "b" in
 | 
				
			||||||
 | 
					    let int_sort = Z3.mk_int_sort ctx in
 | 
				
			||||||
 | 
					    let f   = Z3.theory_mk_func_decl ctx th f_sym [|int_sort |] int_sort in
 | 
				
			||||||
 | 
					    let a   = Z3.theory_mk_constant ctx th a_sym int_sort in
 | 
				
			||||||
 | 
					    let b   = Z3.theory_mk_constant ctx th b_sym int_sort in
 | 
				
			||||||
 | 
					    let reduce_f g args =
 | 
				
			||||||
 | 
					        Printf.printf "reduce %s\n" (Z3.func_decl_to_string ctx g);
 | 
				
			||||||
 | 
					        match g, args with
 | 
				
			||||||
 | 
					        | _, [| a' |] when Z3.is_eq_func_decl ctx g f && Z3.is_eq_ast ctx a' a -> Some b
 | 
				
			||||||
 | 
					        | _, _ -> None
 | 
				
			||||||
 | 
					    in
 | 
				
			||||||
 | 
					    let _   = Z3.set_reduce_app_callback th reduce_f in 
 | 
				
			||||||
 | 
					    (* b != f(b) is consistent *)
 | 
				
			||||||
 | 
					    let _   = Z3.assert_cnstr ctx (Z3.mk_not ctx (Z3.mk_eq ctx b (Z3.mk_app ctx f [| b |]))) in
 | 
				
			||||||
 | 
					    let res = Z3.check ctx in
 | 
				
			||||||
 | 
					    print_lbool res;
 | 
				
			||||||
 | 
					    (* b != f(a) is not consistent *)
 | 
				
			||||||
 | 
					    let _   = Z3.assert_cnstr ctx (Z3.mk_not ctx (Z3.mk_eq ctx b (Z3.mk_app ctx f [| a |]))) in
 | 
				
			||||||
 | 
					    let res = Z3.check ctx in
 | 
				
			||||||
 | 
					    print_lbool res;
 | 
				
			||||||
 | 
					    Z3.del_context ctx
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let _ = test_theory() 
 | 
				
			||||||
							
								
								
									
										36
									
								
								ml/update-ml-doc.cmd
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								ml/update-ml-doc.cmd
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					@echo off
 | 
				
			||||||
 | 
					SETLOCAL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					call ..\tools\ocaml\win32\setup.cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rd 2>NUL /s /q doc
 | 
				
			||||||
 | 
					md doc
 | 
				
			||||||
 | 
					cd doc
 | 
				
			||||||
 | 
					set MLDIR=..
 | 
				
			||||||
 | 
					set DOCDIR=..\%1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ocamldoc.opt.exe -hide Z3,Z3.V3,Test_mlapi -html -css-style z3_ml.css -I %MLDIR% %MLDIR%\test_mlapi.ml %MLDIR%\z3.mli
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..\sed.exe "s|<pre><span class=\"keyword\">val\(.*\)</pre>|<div class=\"function\"><span class=\"keyword\">val\1</div>|g;s|<pre><span class=\"keyword\">type\(.*\)</pre>|<div class=\"function\"><span class=\"keyword\">type\1</div>|g;s|<code><span class=\"keyword\">type\(.*\) = </code>|<div class=\"function\"><span class=\"keyword\">type\1 = </div>|g" Z3.html > Z3.new.html
 | 
				
			||||||
 | 
					move >NUL Z3.new.html Z3.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..\sed.exe "s|<pre><span class=\"keyword\">val\(.*\)</pre>|<div class=\"function\"><span class=\"keyword\">val\1</div>|g" Test_mlapi.html > Test_mlapi.new.html
 | 
				
			||||||
 | 
					move >NUL Test_mlapi.new.html Test_mlapi.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..\sed.exe "s|<h1>Index of values</h1>|<h1>OCaml: Index</h1>|" Index_values.html > Index_values.new.html
 | 
				
			||||||
 | 
					move >NUL Index_values.new.html Index_values.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					copy >NUL %DOCDIR%\tabs.css
 | 
				
			||||||
 | 
					copy >NUL %DOCDIR%\z3.png
 | 
				
			||||||
 | 
					copy >NUL %DOCDIR%\z3_ml.css
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..\sed.exe "1,23d" Test_mlapi.html | ..\sed.exe "$d" > Test_mlapi.new.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type 2>NUL %DOCDIR%\test_mlapi_header.html Test_mlapi.new.html %DOCDIR%\mldoc_footer.html >Test_mlapi.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..\sed.exe "1,37d" Z3.html > Z3.new.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type 2>NUL %DOCDIR%\z3_mlapi_header.html Z3.new.html >Z3.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit /B 0
 | 
				
			||||||
 | 
					ENDLOCAL
 | 
				
			||||||
							
								
								
									
										366
									
								
								ml/x3.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										366
									
								
								ml/x3.ml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,366 @@
 | 
				
			||||||
 | 
					/* Copyright (c) Microsoft Corporation */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote (ml,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Internal auxiliary functions: *)
 | 
				
			||||||
 | 
					(*
 | 
				
			||||||
 | 
					(* Transform a pair of arrays into an array of pairs *)
 | 
				
			||||||
 | 
					let array_combine a b =
 | 
				
			||||||
 | 
					  if Array.length a <> Array.length b then raise (Invalid_argument \"array_combine\");
 | 
				
			||||||
 | 
					  Array.init (Array.length a) (fun i -> (a.(i), b.(i)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* [a |> b] is the pipeline operator for [b(a)] *)
 | 
				
			||||||
 | 
					let ( |> ) x f = f x
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Find the index of an element in an array, raises Not_found is missing *)
 | 
				
			||||||
 | 
					let find equal x a =
 | 
				
			||||||
 | 
					  let len = Array.length a in
 | 
				
			||||||
 | 
					  let rec find_ i =
 | 
				
			||||||
 | 
					    if i >= len then
 | 
				
			||||||
 | 
					      raise Not_found
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					      if equal x a.(i) then
 | 
				
			||||||
 | 
					        i
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        find_ (i+1)
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  find_ 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Symbols *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let symbol_refine c s =
 | 
				
			||||||
 | 
					  match get_symbol_kind c s with
 | 
				
			||||||
 | 
					  | INT_SYMBOL -> Symbol_int (get_symbol_int c s)
 | 
				
			||||||
 | 
					  | STRING_SYMBOL -> Symbol_string (get_symbol_string c s)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mk_symbol c = function
 | 
				
			||||||
 | 
					  | Symbol_int(i) -> mk_int_symbol c i
 | 
				
			||||||
 | 
					  | Symbol_string(s) -> mk_string_symbol c s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Sorts *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_datatype_sort c s = 
 | 
				
			||||||
 | 
					  Array.init (get_datatype_sort_num_constructors c s) (fun i -> 
 | 
				
			||||||
 | 
					    let constructor = get_datatype_sort_constructor c s i in
 | 
				
			||||||
 | 
					    let recognizer = get_datatype_sort_recognizer c s i in
 | 
				
			||||||
 | 
					    let accessors =
 | 
				
			||||||
 | 
					      Array.init (get_domain_size c constructor) (fun j ->
 | 
				
			||||||
 | 
					        get_datatype_sort_constructor_accessor c s i j
 | 
				
			||||||
 | 
					      ) in
 | 
				
			||||||
 | 
					    {constructor; recognizer; accessors}
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let sort_refine c s =
 | 
				
			||||||
 | 
					  match get_sort_kind c s with
 | 
				
			||||||
 | 
					  | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c s)
 | 
				
			||||||
 | 
					  | BOOL_SORT -> Sort_bool
 | 
				
			||||||
 | 
					  | INT_SORT -> Sort_int
 | 
				
			||||||
 | 
					  | BV_SORT -> Sort_bv (get_bv_sort_size c s)
 | 
				
			||||||
 | 
					  | FINITE_DOMAIN_SORT ->
 | 
				
			||||||
 | 
					      (match get_finite_domain_sort_size c s with
 | 
				
			||||||
 | 
					      | Some(sz) -> Sort_finite_domain (get_sort_name c s, sz)
 | 
				
			||||||
 | 
					      | None -> failwith \"Z3.sort_refine: failed to get size of finite-domain sort\"
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					  | REAL_SORT -> Sort_real
 | 
				
			||||||
 | 
					  | ARRAY_SORT -> Sort_array (get_array_sort_domain c s, get_array_sort_range c s)
 | 
				
			||||||
 | 
					  | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c s)
 | 
				
			||||||
 | 
					  | RELATION_SORT -> Sort_relation (Array.init (get_relation_arity c s) (fun i -> get_relation_column c s i))
 | 
				
			||||||
 | 
					  | UNKNOWN_SORT -> Sort_unknown
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mk_sort c = function
 | 
				
			||||||
 | 
					  | Sort_uninterpreted(s) -> mk_uninterpreted_sort c s
 | 
				
			||||||
 | 
					  | Sort_bool -> mk_bool_sort c
 | 
				
			||||||
 | 
					  | Sort_int -> mk_int_sort c
 | 
				
			||||||
 | 
					  | Sort_bv(size) -> mk_bv_sort c size
 | 
				
			||||||
 | 
					  | Sort_finite_domain(name,size) -> mk_finite_domain_sort c name size
 | 
				
			||||||
 | 
					  | Sort_real -> mk_real_sort c
 | 
				
			||||||
 | 
					  | Sort_array(domain,range) -> mk_array_sort c domain range
 | 
				
			||||||
 | 
					  | Sort_datatype(constructors) -> get_range c constructors.(0).constructor
 | 
				
			||||||
 | 
					  | Sort_relation(_) -> invalid_arg \"Z3.mk_sort: cannot construct relation sorts\"
 | 
				
			||||||
 | 
					  | Sort_unknown(_) -> invalid_arg \"Z3.mk_sort: cannot construct unknown sorts\"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Replacement datatypes creation API *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mk_datatypes ctx generator =
 | 
				
			||||||
 | 
					  let usort0 = mk_uninterpreted_sort ctx (mk_int_symbol ctx 0)
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let rec find_num_sorts i =
 | 
				
			||||||
 | 
					    if i = max_int then invalid_arg \"mk_datatypes: too many sorts\"
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    match generator (Array.make i usort0) with
 | 
				
			||||||
 | 
					    | None -> find_num_sorts (i+1)
 | 
				
			||||||
 | 
					    | Some(a) when Array.length a = i -> i
 | 
				
			||||||
 | 
					    | Some _ -> invalid_arg \"mk_datatypes: number of sorts and datatype descriptors must be equal\"
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let num_sorts = find_num_sorts 0
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let sorts0 = Array.init num_sorts (fun i -> mk_uninterpreted_sort ctx (mk_int_symbol ctx i))
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let ctorss_descriptors =
 | 
				
			||||||
 | 
					    match generator sorts0 with
 | 
				
			||||||
 | 
					    | Some(ctorss_descriptors) -> ctorss_descriptors
 | 
				
			||||||
 | 
					    | None -> invalid_arg \"mk_datatypes: generator failed\"
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let names = Array.map fst ctorss_descriptors
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let ctorss =
 | 
				
			||||||
 | 
					    Array.map (fun (_, ctors_descriptor) ->
 | 
				
			||||||
 | 
					      Array.map (fun {constructor_desc; recognizer_desc; accessor_descs} ->
 | 
				
			||||||
 | 
					        let field_names = Array.map fst accessor_descs
 | 
				
			||||||
 | 
					        in
 | 
				
			||||||
 | 
					        let sort_refs = Array.make (Array.length accessor_descs) 0
 | 
				
			||||||
 | 
					        in
 | 
				
			||||||
 | 
					        let field_sorts =
 | 
				
			||||||
 | 
					          Array.mapi (fun i (_, sort) ->
 | 
				
			||||||
 | 
					            try
 | 
				
			||||||
 | 
					              let j = find (fun s t -> is_eq_sort ctx s t) sort sorts0 in
 | 
				
			||||||
 | 
					              sort_refs.(i) <- j ;
 | 
				
			||||||
 | 
					              None
 | 
				
			||||||
 | 
					            with Not_found ->
 | 
				
			||||||
 | 
					              Some(sort)
 | 
				
			||||||
 | 
					          ) accessor_descs
 | 
				
			||||||
 | 
					        in
 | 
				
			||||||
 | 
					        mk_constructor ctx constructor_desc recognizer_desc field_names field_sorts sort_refs
 | 
				
			||||||
 | 
					      ) ctors_descriptor
 | 
				
			||||||
 | 
					    ) ctorss_descriptors
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let constructor_lists = Array.map (mk_constructor_list ctx) ctorss
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let sorts,_ = mk_datatypes ctx names constructor_lists
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  let datatypes =
 | 
				
			||||||
 | 
					    Array.mapi (fun i sort ->
 | 
				
			||||||
 | 
					      (sort,
 | 
				
			||||||
 | 
					       Array.mapi (fun j ctor ->
 | 
				
			||||||
 | 
					         let num_fields = Array.length (snd ctorss_descriptors.(i)).(j).accessor_descs in
 | 
				
			||||||
 | 
					         let constructor, recognizer, accessors = query_constructor ctx ctor num_fields in
 | 
				
			||||||
 | 
					         {constructor; recognizer; accessors}
 | 
				
			||||||
 | 
					       ) ctorss.(i))
 | 
				
			||||||
 | 
					    ) sorts
 | 
				
			||||||
 | 
					  in
 | 
				
			||||||
 | 
					  Array.iter (fun ctor_list ->
 | 
				
			||||||
 | 
					    del_constructor_list ctx ctor_list
 | 
				
			||||||
 | 
					  ) constructor_lists
 | 
				
			||||||
 | 
					  ;
 | 
				
			||||||
 | 
					  Array.iter (fun ctors ->
 | 
				
			||||||
 | 
					    Array.iter (fun ctor ->
 | 
				
			||||||
 | 
					      del_constructor ctx ctor
 | 
				
			||||||
 | 
					    ) ctors
 | 
				
			||||||
 | 
					  ) ctorss
 | 
				
			||||||
 | 
					  ;
 | 
				
			||||||
 | 
					  datatypes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Numerals *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let rec numeral_refine c t =
 | 
				
			||||||
 | 
					  assert( get_ast_kind c t = NUMERAL_AST );
 | 
				
			||||||
 | 
					  let sort = get_sort c t in
 | 
				
			||||||
 | 
					  let is_int, i = get_numeral_int c t in
 | 
				
			||||||
 | 
					  if is_int then 
 | 
				
			||||||
 | 
					    Numeral_int (i, sort)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  let is_int64, i = get_numeral_int64 c t in
 | 
				
			||||||
 | 
					  if is_int64 then 
 | 
				
			||||||
 | 
					    Numeral_int64 (i, sort)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					  if get_sort_kind c sort <> REAL_SORT then
 | 
				
			||||||
 | 
					    Numeral_large (get_numeral_string c t, sort)
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    let n = numeral_refine c (get_numerator c t) in
 | 
				
			||||||
 | 
					    let d = numeral_refine c (get_denominator c t) in
 | 
				
			||||||
 | 
					    Numeral_rational (n, d)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let to_real c x =
 | 
				
			||||||
 | 
					  if get_sort_kind c (get_sort c x) = REAL_SORT then
 | 
				
			||||||
 | 
					    x
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    mk_int2real c x
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let rec embed_numeral c = function
 | 
				
			||||||
 | 
					  | Numeral_int (i, s) -> mk_int c i s
 | 
				
			||||||
 | 
					  | Numeral_int64 (i, s) -> mk_int64 c i s
 | 
				
			||||||
 | 
					  | Numeral_large (l, s) -> mk_numeral c l s
 | 
				
			||||||
 | 
					  | Numeral_rational (Numeral_int(n,_), Numeral_int(d,_)) -> mk_real c n d
 | 
				
			||||||
 | 
					  | Numeral_rational (n, d) ->
 | 
				
			||||||
 | 
					      mk_div c (to_real c (embed_numeral c n)) (to_real c (embed_numeral c d))
 | 
				
			||||||
 | 
					      (* Or should the following be used instead?
 | 
				
			||||||
 | 
					      let n_str = get_numeral_string c (embed_numeral c n) in
 | 
				
			||||||
 | 
					      let d_str = get_numeral_string c (embed_numeral c d) in
 | 
				
			||||||
 | 
					      mk_numeral c (n_str ^ \" / \" ^ d_str) (mk_real_sort c)
 | 
				
			||||||
 | 
					      *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Terms *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_app_args c a =
 | 
				
			||||||
 | 
					  Array.init (get_app_num_args c a) (get_app_arg c a);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_domains c d =
 | 
				
			||||||
 | 
					  Array.init (get_domain_size c d) (get_domain c d);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_pattern_terms c p = 
 | 
				
			||||||
 | 
					  Array.init (get_pattern_num_terms c p) (get_pattern c p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let term_refine c t = 
 | 
				
			||||||
 | 
					  match get_ast_kind c t with
 | 
				
			||||||
 | 
					  | NUMERAL_AST ->
 | 
				
			||||||
 | 
					      Term_numeral (numeral_refine c t)
 | 
				
			||||||
 | 
					  | APP_AST ->
 | 
				
			||||||
 | 
					      let t' = to_app c t in
 | 
				
			||||||
 | 
					      let f = get_app_decl c t' in
 | 
				
			||||||
 | 
					      let num_args = get_app_num_args c t' in
 | 
				
			||||||
 | 
					      let args = Array.init num_args (get_app_arg c t') in
 | 
				
			||||||
 | 
					      let k = get_decl_kind c f in
 | 
				
			||||||
 | 
					      Term_app (k, f, args)
 | 
				
			||||||
 | 
					  | QUANTIFIER_AST -> 
 | 
				
			||||||
 | 
					      let bt = if is_quantifier_forall c t then Forall else Exists in
 | 
				
			||||||
 | 
					      let w = get_quantifier_weight c t                            in
 | 
				
			||||||
 | 
					      let np = get_quantifier_num_patterns c t                     in
 | 
				
			||||||
 | 
					      let pats = Array.init np (get_quantifier_pattern_ast c t)    in
 | 
				
			||||||
 | 
					      let pats = Array.map (get_pattern_terms c) pats              in
 | 
				
			||||||
 | 
					      let nb = get_quantifier_num_bound c t                        in
 | 
				
			||||||
 | 
					      let bound =
 | 
				
			||||||
 | 
					        Array.init nb (fun i ->
 | 
				
			||||||
 | 
					          (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i)
 | 
				
			||||||
 | 
					        ) in
 | 
				
			||||||
 | 
					      let body = get_quantifier_body c t in
 | 
				
			||||||
 | 
					      Term_quantifier (bt, w, pats, bound, body)
 | 
				
			||||||
 | 
					  | VAR_AST -> 
 | 
				
			||||||
 | 
					      Term_var (get_index_value c t, get_sort c t)
 | 
				
			||||||
 | 
					  | _ ->
 | 
				
			||||||
 | 
					      assert false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* let mk_term c = function *)
 | 
				
			||||||
 | 
					(*   | Term_numeral (numeral, sort) -> mk_numeral c numeral sort *)
 | 
				
			||||||
 | 
					(*   | Term_app (kind, decl, args) -> *)
 | 
				
			||||||
 | 
					(*   | Term_quantifier (strength, weight, pats, bound, body) -> *)
 | 
				
			||||||
 | 
					(*   | Term_var (index, sort) -> *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Refined model API *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let model_refine c m =
 | 
				
			||||||
 | 
					  let num_sorts = model_get_num_sorts c m in
 | 
				
			||||||
 | 
					  let sorts = Hashtbl.create num_sorts in
 | 
				
			||||||
 | 
					  for i = 0 to num_sorts - 1 do
 | 
				
			||||||
 | 
					    let sort = model_get_sort c m i in
 | 
				
			||||||
 | 
					    let universe = model_get_sort_universe c m sort in
 | 
				
			||||||
 | 
					    Hashtbl.add sorts sort universe
 | 
				
			||||||
 | 
					  done;
 | 
				
			||||||
 | 
					  let num_consts = model_get_num_consts c m in
 | 
				
			||||||
 | 
					  let consts = Hashtbl.create num_consts in
 | 
				
			||||||
 | 
					  let arrays = Hashtbl.create 0 in
 | 
				
			||||||
 | 
					  for i = 0 to num_consts - 1 do
 | 
				
			||||||
 | 
					    let const_decl = model_get_const_decl c m i in
 | 
				
			||||||
 | 
					    match model_get_const_interp c m const_decl with
 | 
				
			||||||
 | 
					    | Some(const_interp) ->
 | 
				
			||||||
 | 
					        if is_as_array c const_interp then
 | 
				
			||||||
 | 
					          let array_decl = get_as_array_func_decl c const_interp in
 | 
				
			||||||
 | 
					          match model_get_func_interp c m array_decl with
 | 
				
			||||||
 | 
					          | Some(array_interp) ->
 | 
				
			||||||
 | 
					              let num_entries = func_interp_get_num_entries c array_interp in
 | 
				
			||||||
 | 
					              let tbl = Hashtbl.create num_entries in
 | 
				
			||||||
 | 
					              for i = 0 to num_entries - 1 do
 | 
				
			||||||
 | 
					                let entry = func_interp_get_entry c array_interp i in
 | 
				
			||||||
 | 
					                assert( func_entry_get_num_args c entry = 1 );
 | 
				
			||||||
 | 
					                let arg = func_entry_get_arg c entry 0 in
 | 
				
			||||||
 | 
					                let value = func_entry_get_value c entry in
 | 
				
			||||||
 | 
					                Hashtbl.add tbl arg value
 | 
				
			||||||
 | 
					              done;
 | 
				
			||||||
 | 
					              let default = func_interp_get_else c array_interp in
 | 
				
			||||||
 | 
					              Hashtbl.add arrays const_decl (tbl, default)
 | 
				
			||||||
 | 
					          | None ->
 | 
				
			||||||
 | 
					              ()
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          Hashtbl.add consts const_decl const_interp
 | 
				
			||||||
 | 
					    | None ->
 | 
				
			||||||
 | 
					        ()
 | 
				
			||||||
 | 
					  done;
 | 
				
			||||||
 | 
					  let num_funcs = model_get_num_funcs c m in
 | 
				
			||||||
 | 
					  let funcs = Hashtbl.create num_funcs in
 | 
				
			||||||
 | 
					  for i = 0 to num_funcs - 1 do
 | 
				
			||||||
 | 
					    let func_decl = model_get_func_decl c m i in
 | 
				
			||||||
 | 
					    if not (Hashtbl.mem arrays func_decl) then
 | 
				
			||||||
 | 
					      match model_get_func_interp c m func_decl with
 | 
				
			||||||
 | 
					      | Some(func_interp) ->
 | 
				
			||||||
 | 
					          let num_entries = func_interp_get_num_entries c func_interp in
 | 
				
			||||||
 | 
					          let tbl = Hashtbl.create num_entries in
 | 
				
			||||||
 | 
					          for i = 0 to num_entries - 1 do
 | 
				
			||||||
 | 
					            let entry = func_interp_get_entry c func_interp i in
 | 
				
			||||||
 | 
					            let num_args = func_entry_get_num_args c entry in
 | 
				
			||||||
 | 
					            let args = Array.init num_args (fun i -> func_entry_get_arg c entry i) in
 | 
				
			||||||
 | 
					            let value = func_entry_get_value c entry in
 | 
				
			||||||
 | 
					            Hashtbl.add tbl args value
 | 
				
			||||||
 | 
					          done;
 | 
				
			||||||
 | 
					          let default = func_interp_get_else c func_interp in
 | 
				
			||||||
 | 
					          Hashtbl.add funcs func_decl (tbl, default)
 | 
				
			||||||
 | 
					      | None ->
 | 
				
			||||||
 | 
					          ()
 | 
				
			||||||
 | 
					  done;
 | 
				
			||||||
 | 
					  {sorts; consts; arrays; funcs}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Extended parser API *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_formulas c = 
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_assumptions c = 
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_decls c =
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_decls c) (get_smtlib_decl c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_parse_results c =
 | 
				
			||||||
 | 
					  (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_string_x c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  parse_smtlib_string c a1 a2 a3 a4 a5 ;
 | 
				
			||||||
 | 
					  get_smtlib_parse_results c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_file_x c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  parse_smtlib_file c a1 a2 a3 a4 a5 ;
 | 
				
			||||||
 | 
					  get_smtlib_parse_results c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  parse_smtlib_string c a1 a2 a3 a4 a5 ;
 | 
				
			||||||
 | 
					  match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_string_formula\"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  parse_smtlib_file c a1 a2 a3 a4 a5 ;
 | 
				
			||||||
 | 
					  match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_file_formula\"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Error handling *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_error_msg c e =
 | 
				
			||||||
 | 
					  match e with
 | 
				
			||||||
 | 
					  | PARSER_ERROR -> (get_error_msg_ex c e) ^ \": \" ^ (get_smtlib_error c)
 | 
				
			||||||
 | 
					  | _ -> get_error_msg_ex c e
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Refined stats API *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let stats_refine c s =
 | 
				
			||||||
 | 
					  let num_stats = stats_size c s in
 | 
				
			||||||
 | 
					  let tbl = Hashtbl.create num_stats in
 | 
				
			||||||
 | 
					  for i = 0 to num_stats - 1 do
 | 
				
			||||||
 | 
					    let key = stats_get_key c s i in
 | 
				
			||||||
 | 
					    let datum =
 | 
				
			||||||
 | 
					      if stats_is_uint c s i then
 | 
				
			||||||
 | 
					        Stat_int(stats_get_uint_value c s i)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
					        Stat_float(stats_get_double_value c s i) in
 | 
				
			||||||
 | 
					    Hashtbl.add tbl key datum
 | 
				
			||||||
 | 
					  done;
 | 
				
			||||||
 | 
					  tbl
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										378
									
								
								ml/x3V3.ml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								ml/x3V3.ml
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,378 @@
 | 
				
			||||||
 | 
					quote (ml,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Internal auxillary functions: *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Transform a pair of arrays into an array of pairs *)
 | 
				
			||||||
 | 
					let array_combine a b =
 | 
				
			||||||
 | 
					  if Array.length a <> Array.length b then raise (Invalid_argument \"array_combine\");
 | 
				
			||||||
 | 
					  Array.init (Array.length a) (fun i->(a.(i),b.(i)));;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* [a |> b] is the pipeline operator for [b(a)] *)
 | 
				
			||||||
 | 
					let ( |> ) x f = f x;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Extensions, except for refinement: *)
 | 
				
			||||||
 | 
					let mk_context_x configs = 
 | 
				
			||||||
 | 
					  let config = mk_config() in
 | 
				
			||||||
 | 
					  let f(param_id,param_value) = set_param_value config param_id param_value in
 | 
				
			||||||
 | 
					  Array.iter f configs;
 | 
				
			||||||
 | 
					  let context = mk_context config in
 | 
				
			||||||
 | 
					  del_config config;
 | 
				
			||||||
 | 
					  context;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_app_args c a =
 | 
				
			||||||
 | 
					  Array.init (get_app_num_args c a) (get_app_arg c a);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_domains c d =
 | 
				
			||||||
 | 
					  Array.init (get_domain_size c d) (get_domain c d);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_array_sort c t = (get_array_sort_domain c t, get_array_sort_range c t);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_tuple_sort c ty = 
 | 
				
			||||||
 | 
					  (get_tuple_sort_mk_decl c ty,
 | 
				
			||||||
 | 
					   Array.init (get_tuple_sort_num_fields c ty) (get_tuple_sort_field_decl c ty));;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type datatype_constructor_refined = { 
 | 
				
			||||||
 | 
					   constructor : func_decl; 
 | 
				
			||||||
 | 
					   recognizer : func_decl; 
 | 
				
			||||||
 | 
					   accessors : func_decl array 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_datatype_sort c ty = 
 | 
				
			||||||
 | 
					  Array.init (get_datatype_sort_num_constructors c ty)
 | 
				
			||||||
 | 
					  (fun idx_c -> 
 | 
				
			||||||
 | 
					   let constr = get_datatype_sort_constructor c ty idx_c in
 | 
				
			||||||
 | 
					   let recog = get_datatype_sort_recognizer  c ty idx_c in
 | 
				
			||||||
 | 
					   let num_acc = get_domain_size c constr in
 | 
				
			||||||
 | 
					   { constructor = constr;
 | 
				
			||||||
 | 
					     recognizer = recog;
 | 
				
			||||||
 | 
					     accessors = Array.init num_acc (get_datatype_sort_constructor_accessor c ty idx_c);
 | 
				
			||||||
 | 
					   })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_model_constants c m =
 | 
				
			||||||
 | 
					  Array.init (get_model_num_constants c m) (get_model_constant c m);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_model_func_entry c m i j =
 | 
				
			||||||
 | 
					  (Array.init
 | 
				
			||||||
 | 
					     (get_model_func_entry_num_args c m i j)
 | 
				
			||||||
 | 
					     (get_model_func_entry_arg c m i j),
 | 
				
			||||||
 | 
					   get_model_func_entry_value c m i j);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_model_func_entries c m i =
 | 
				
			||||||
 | 
					  Array.init (get_model_func_num_entries c m i) (get_model_func_entry c m i);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_model_funcs c m =
 | 
				
			||||||
 | 
					  Array.init (get_model_num_funcs c m)
 | 
				
			||||||
 | 
					    (fun i->(get_model_func_decl c m i |> get_decl_name c,
 | 
				
			||||||
 | 
					             get_model_func_entries c m i,
 | 
				
			||||||
 | 
					             get_model_func_else c m i));;
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					let get_smtlib_formulas c = 
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_formulas c) (get_smtlib_formula c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_assumptions c = 
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_assumptions c) (get_smtlib_assumption c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_decls c =
 | 
				
			||||||
 | 
					  Array.init (get_smtlib_num_decls c) (get_smtlib_decl c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_smtlib_parse_results c =
 | 
				
			||||||
 | 
					  (get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_string_formula c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  (parse_smtlib_string c a1 a2 a3 a4 a5;
 | 
				
			||||||
 | 
					   match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_string_formula\");;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_file_formula c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  (parse_smtlib_file c a1 a2 a3 a4 a5;
 | 
				
			||||||
 | 
					   match get_smtlib_formulas c with [|f|] -> f | _ -> failwith \"Z3: parse_smtlib_file_formula\");;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_string_x c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  (parse_smtlib_string c a1 a2 a3 a4 a5; get_smtlib_parse_results c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let parse_smtlib_file_x c a1 a2 a3 a4 a5 = 
 | 
				
			||||||
 | 
					  (parse_smtlib_file c a1 a2 a3 a4 a5; get_smtlib_parse_results c);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(* Refinement: *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type symbol_refined =
 | 
				
			||||||
 | 
					  | Symbol_int of int
 | 
				
			||||||
 | 
					  | Symbol_string of string
 | 
				
			||||||
 | 
					  | Symbol_unknown;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let symbol_refine c s =
 | 
				
			||||||
 | 
					  match get_symbol_kind c s with
 | 
				
			||||||
 | 
					  | INT_SYMBOL -> Symbol_int (get_symbol_int c s)
 | 
				
			||||||
 | 
					  | STRING_SYMBOL -> Symbol_string (get_symbol_string c s);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type sort_refined =
 | 
				
			||||||
 | 
					  | Sort_uninterpreted of symbol
 | 
				
			||||||
 | 
					  | Sort_bool
 | 
				
			||||||
 | 
					  | Sort_int
 | 
				
			||||||
 | 
					  | Sort_real
 | 
				
			||||||
 | 
					  | Sort_bv of int
 | 
				
			||||||
 | 
					  | Sort_array of (sort * sort)
 | 
				
			||||||
 | 
					  | Sort_datatype of datatype_constructor_refined array
 | 
				
			||||||
 | 
					  | Sort_relation
 | 
				
			||||||
 | 
					  | Sort_finite_domain
 | 
				
			||||||
 | 
					  | Sort_unknown of symbol;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let sort_refine c ty =
 | 
				
			||||||
 | 
					  match get_sort_kind c ty with
 | 
				
			||||||
 | 
					  | UNINTERPRETED_SORT -> Sort_uninterpreted (get_sort_name c ty)
 | 
				
			||||||
 | 
					  | BOOL_SORT -> Sort_bool
 | 
				
			||||||
 | 
					  | INT_SORT -> Sort_int
 | 
				
			||||||
 | 
					  | REAL_SORT -> Sort_real
 | 
				
			||||||
 | 
					  | BV_SORT -> Sort_bv (get_bv_sort_size c ty)
 | 
				
			||||||
 | 
					  | ARRAY_SORT -> Sort_array (get_array_sort_domain c ty, get_array_sort_range c ty)
 | 
				
			||||||
 | 
					  | DATATYPE_SORT -> Sort_datatype (get_datatype_sort c ty)
 | 
				
			||||||
 | 
					  | RELATION_SORT -> Sort_relation 
 | 
				
			||||||
 | 
					  | FINITE_DOMAIN_SORT -> Sort_finite_domain
 | 
				
			||||||
 | 
					  | UNKNOWN_SORT -> Sort_unknown (get_sort_name c ty);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_pattern_terms c p = 
 | 
				
			||||||
 | 
					  Array.init (get_pattern_num_terms c p) (get_pattern c p)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type binder_type = | Forall | Exists 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type numeral_refined = 
 | 
				
			||||||
 | 
					  | Numeral_small  of int64 * int64
 | 
				
			||||||
 | 
					  | Numeral_large  of string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type term_refined = 
 | 
				
			||||||
 | 
					  | Term_app        of decl_kind * func_decl * ast array
 | 
				
			||||||
 | 
					  | Term_quantifier of binder_type * int * ast array array * (symbol *sort) array * ast
 | 
				
			||||||
 | 
					  | Term_numeral    of numeral_refined * sort
 | 
				
			||||||
 | 
					  | Term_var        of int * sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let term_refine c t = 
 | 
				
			||||||
 | 
					  match get_ast_kind c t with
 | 
				
			||||||
 | 
					  | NUMERAL_AST -> 
 | 
				
			||||||
 | 
					      let (is_small, n, d) = get_numeral_small c t in
 | 
				
			||||||
 | 
					      if is_small then 
 | 
				
			||||||
 | 
						Term_numeral(Numeral_small(n,d), get_sort c t)
 | 
				
			||||||
 | 
					      else
 | 
				
			||||||
 | 
						Term_numeral(Numeral_large(get_numeral_string c t), get_sort c t)
 | 
				
			||||||
 | 
					  | APP_AST   -> 
 | 
				
			||||||
 | 
					      let t' = to_app c t in
 | 
				
			||||||
 | 
					      let f =  get_app_decl c t' in
 | 
				
			||||||
 | 
					      let num_args = get_app_num_args c t' in
 | 
				
			||||||
 | 
					      let args = Array.init num_args (get_app_arg c t') in
 | 
				
			||||||
 | 
					      let k = get_decl_kind c f in
 | 
				
			||||||
 | 
					      Term_app (k, f, args)
 | 
				
			||||||
 | 
					  | QUANTIFIER_AST -> 
 | 
				
			||||||
 | 
					      let bt = if is_quantifier_forall c t then Forall else Exists in
 | 
				
			||||||
 | 
					      let w = get_quantifier_weight c t                            in
 | 
				
			||||||
 | 
					      let np = get_quantifier_num_patterns c t                     in
 | 
				
			||||||
 | 
					      let pats = Array.init np (get_quantifier_pattern_ast c t)    in
 | 
				
			||||||
 | 
					      let pats = Array.map (get_pattern_terms c) pats              in
 | 
				
			||||||
 | 
					      let nb = get_quantifier_num_bound c t                        in
 | 
				
			||||||
 | 
					      let bound = Array.init nb 
 | 
				
			||||||
 | 
						  (fun i -> (get_quantifier_bound_name c t i, get_quantifier_bound_sort c t i)) in
 | 
				
			||||||
 | 
					      let body = get_quantifier_body c t in
 | 
				
			||||||
 | 
					      Term_quantifier(bt, w, pats, bound, body)
 | 
				
			||||||
 | 
					  | VAR_AST -> 
 | 
				
			||||||
 | 
					      Term_var(get_index_value c t, get_sort c t)
 | 
				
			||||||
 | 
					  | _ -> assert false
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					type theory_callbacks = 
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					     mutable delete_theory : unit -> unit;
 | 
				
			||||||
 | 
					     mutable reduce_eq : ast -> ast -> ast option;
 | 
				
			||||||
 | 
					     mutable reduce_app : func_decl -> ast array -> ast option;
 | 
				
			||||||
 | 
					     mutable reduce_distinct : ast array -> ast option;
 | 
				
			||||||
 | 
					     mutable final_check : unit -> bool;
 | 
				
			||||||
 | 
					     mutable new_app : ast -> unit;
 | 
				
			||||||
 | 
					     mutable new_elem : ast -> unit;
 | 
				
			||||||
 | 
					     mutable init_search: unit -> unit;
 | 
				
			||||||
 | 
					     mutable push: unit -> unit;
 | 
				
			||||||
 | 
					     mutable pop: unit -> unit;
 | 
				
			||||||
 | 
					     mutable restart : unit -> unit;
 | 
				
			||||||
 | 
					     mutable reset: unit -> unit;
 | 
				
			||||||
 | 
					     mutable new_eq : ast -> ast -> unit;
 | 
				
			||||||
 | 
					     mutable new_diseq : ast -> ast -> unit;
 | 
				
			||||||
 | 
					     mutable new_assignment: ast -> bool -> unit;
 | 
				
			||||||
 | 
					     mutable new_relevant : ast -> unit;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mk_theory_callbacks() = 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					     delete_theory = (fun () -> ());
 | 
				
			||||||
 | 
					     reduce_eq = (fun _ _ -> None);
 | 
				
			||||||
 | 
					     reduce_app = (fun _ _ -> None);
 | 
				
			||||||
 | 
					     reduce_distinct = (fun _ -> None);
 | 
				
			||||||
 | 
					     final_check = (fun _ -> true);
 | 
				
			||||||
 | 
					     new_app = (fun _ -> ());
 | 
				
			||||||
 | 
					     new_elem = (fun _ -> ());
 | 
				
			||||||
 | 
					     init_search= (fun () -> ());
 | 
				
			||||||
 | 
					     push= (fun () -> ());
 | 
				
			||||||
 | 
					     pop= (fun () -> ());
 | 
				
			||||||
 | 
					     restart = (fun () -> ());
 | 
				
			||||||
 | 
					     reset= (fun () -> ());
 | 
				
			||||||
 | 
					     new_eq = (fun _ _ -> ());
 | 
				
			||||||
 | 
					     new_diseq = (fun _ _ -> ());
 | 
				
			||||||
 | 
					     new_assignment = (fun _ _ -> ());
 | 
				
			||||||
 | 
					     new_relevant = (fun _ -> ());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					external get_theory_callbacks : theory -> theory_callbacks = \"get_theory_callbacks\"
 | 
				
			||||||
 | 
					external mk_theory_register : context -> string -> theory_callbacks -> theory = \"mk_theory_register\"
 | 
				
			||||||
 | 
					external set_delete_callback_register : theory -> unit = \"set_delete_callback_register\"
 | 
				
			||||||
 | 
					external set_reduce_app_callback_register : theory -> unit = \"set_reduce_app_callback_register\"
 | 
				
			||||||
 | 
					external set_reduce_eq_callback_register : theory -> unit = \"set_reduce_eq_callback_register\"
 | 
				
			||||||
 | 
					external set_reduce_distinct_callback_register : theory -> unit = \"set_reduce_distinct_callback_register\"
 | 
				
			||||||
 | 
					external set_new_app_callback_register : theory -> unit = \"set_new_app_callback_register\"
 | 
				
			||||||
 | 
					external set_new_elem_callback_register : theory -> unit = \"set_new_elem_callback_register\"
 | 
				
			||||||
 | 
					external set_init_search_callback_register : theory -> unit = \"set_init_search_callback_register\"
 | 
				
			||||||
 | 
					external set_push_callback_register : theory -> unit = \"set_push_callback_register\"
 | 
				
			||||||
 | 
					external set_pop_callback_register : theory -> unit = \"set_pop_callback_register\"
 | 
				
			||||||
 | 
					external set_restart_callback_register : theory -> unit = \"set_restart_callback_register\"
 | 
				
			||||||
 | 
					external set_reset_callback_register : theory -> unit = \"set_reset_callback_register\"
 | 
				
			||||||
 | 
					external set_final_check_callback_register : theory -> unit = \"set_final_check_callback_register\"
 | 
				
			||||||
 | 
					external set_new_eq_callback_register : theory -> unit = \"set_new_eq_callback_register\"
 | 
				
			||||||
 | 
					external set_new_diseq_callback_register : theory -> unit = \"set_new_diseq_callback_register\"
 | 
				
			||||||
 | 
					external set_new_assignment_callback_register : theory -> unit = \"set_new_assignment_callback_register\"
 | 
				
			||||||
 | 
					external set_new_relevant_callback_register : theory -> unit = \"set_new_relevant_callback_register\"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let is_some opt = 
 | 
				
			||||||
 | 
					    match opt with
 | 
				
			||||||
 | 
					    | Some v -> true
 | 
				
			||||||
 | 
					    | None   -> false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_some opt = 
 | 
				
			||||||
 | 
					    match opt with
 | 
				
			||||||
 | 
					    | Some v -> v
 | 
				
			||||||
 | 
					    | None   -> failwith \"None unexpected\"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_delete (th:theory_callbacks) = th.delete_theory ()
 | 
				
			||||||
 | 
					let set_delete_callback th cb = 
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.delete_theory <- cb;
 | 
				
			||||||
 | 
					    set_delete_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mk_theory context name = 
 | 
				
			||||||
 | 
					    Callback.register \"is_some\" is_some;
 | 
				
			||||||
 | 
					    Callback.register \"get_some\" get_some;
 | 
				
			||||||
 | 
					    Callback.register \"apply_delete\" apply_delete;
 | 
				
			||||||
 | 
					    let cbs = mk_theory_callbacks() in
 | 
				
			||||||
 | 
					    mk_theory_register context name cbs
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_reduce_app (th:theory_callbacks) f args = th.reduce_app f args
 | 
				
			||||||
 | 
					let set_reduce_app_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_reduce_app\" apply_reduce_app;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.reduce_app <- cb;
 | 
				
			||||||
 | 
					    set_reduce_app_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_reduce_eq (th:theory_callbacks) a b = th.reduce_eq a b
 | 
				
			||||||
 | 
					let set_reduce_eq_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_reduce_eq\" apply_reduce_eq;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.reduce_eq <- cb;
 | 
				
			||||||
 | 
					    set_reduce_eq_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_reduce_distinct (th:theory_callbacks) args = th.reduce_distinct args
 | 
				
			||||||
 | 
					let set_reduce_distinct_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_reduce_distinct\" apply_reduce_distinct;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.reduce_distinct <- cb;
 | 
				
			||||||
 | 
					    set_reduce_distinct_callback_register th
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_app (th:theory_callbacks) a = th.new_app a
 | 
				
			||||||
 | 
					let set_new_app_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_app\" apply_new_app;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_app <- cb;
 | 
				
			||||||
 | 
					    set_new_app_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_elem (th:theory_callbacks) a = th.new_elem a
 | 
				
			||||||
 | 
					let set_new_elem_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_elem\" apply_new_elem;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_elem <- cb;
 | 
				
			||||||
 | 
					    set_new_elem_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_init_search (th:theory_callbacks) = th.init_search()
 | 
				
			||||||
 | 
					let set_init_search_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_init_search\" apply_init_search;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.init_search <- cb;
 | 
				
			||||||
 | 
					    set_init_search_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_push (th:theory_callbacks) = th.push()
 | 
				
			||||||
 | 
					let set_push_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_push\" apply_push;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.push <- cb;
 | 
				
			||||||
 | 
					    set_push_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_pop (th:theory_callbacks) = th.pop()
 | 
				
			||||||
 | 
					let set_pop_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_pop\" apply_pop;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.pop <- cb;
 | 
				
			||||||
 | 
					    set_pop_callback_register th
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_restart (th:theory_callbacks) = th.restart()
 | 
				
			||||||
 | 
					let set_restart_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_restart\" apply_restart;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.restart <- cb;
 | 
				
			||||||
 | 
					    set_restart_callback_register th
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_reset (th:theory_callbacks) = th.reset()
 | 
				
			||||||
 | 
					let set_reset_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_reset\" apply_reset;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.reset <- cb;
 | 
				
			||||||
 | 
					    set_reset_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_final_check (th:theory_callbacks) = th.final_check()
 | 
				
			||||||
 | 
					let set_final_check_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_final_check\" apply_final_check;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.final_check <- cb;
 | 
				
			||||||
 | 
					    set_final_check_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_eq (th:theory_callbacks) a b = th.new_eq a b
 | 
				
			||||||
 | 
					let set_new_eq_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_eq\" apply_new_eq;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_eq <- cb;
 | 
				
			||||||
 | 
					    set_new_eq_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_diseq (th:theory_callbacks) a b = th.new_diseq a b
 | 
				
			||||||
 | 
					let set_new_diseq_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_diseq\" apply_new_diseq;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_diseq <- cb;
 | 
				
			||||||
 | 
					    set_new_diseq_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_assignment (th:theory_callbacks) a b = th.new_assignment a b
 | 
				
			||||||
 | 
					let set_new_assignment_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_assignment\" apply_new_assignment;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_assignment <- cb;
 | 
				
			||||||
 | 
					    set_new_assignment_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let apply_new_relevant (th:theory_callbacks) a = th.new_relevant a
 | 
				
			||||||
 | 
					let set_new_relevant_callback th cb = 
 | 
				
			||||||
 | 
					    Callback.register \"apply_new_relevant\" apply_new_relevant;
 | 
				
			||||||
 | 
					    let cbs = get_theory_callbacks th in
 | 
				
			||||||
 | 
					    cbs.new_relevant <- cb;
 | 
				
			||||||
 | 
					    set_new_relevant_callback_register th
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										361
									
								
								ml/x3V3.mli
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										361
									
								
								ml/x3V3.mli
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,361 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote (mli,"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** {2 {L ML Extensions}} *)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ mk_context_x configs] \] is a shorthand for the context with configurations in [configs].
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val mk_context_x: (string * string) array -> context;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_app_args c a ] \] is the array of arguments of an application. If [t] is a constant, then the array is empty.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_app_num_args}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_app_arg}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_app_args:  context -> app -> ast array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_app_args c d ] \] is the array of parameters of [d].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_domain_size}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_domain}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_domains: context -> func_decl -> sort array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_array_sort c t ] \] is the domain and the range of [t].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_array_sort_domain}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_array_sort_range}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_array_sort: context -> sort -> sort * sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_tuple_sort c ty ] \] is the pair [(mk_decl, fields)] where [mk_decl] is the constructor declaration of [ty], and [fields] is the array of fields in [ty].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_tuple_sort_mk_decl}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_tuple_sort_num_fields}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_tuple_sort_field_decl}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_tuple_sort: context -> sort -> (func_decl * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ datatype_constructor_refined ] \] is the refinement of a datatype constructor.
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  It contains the constructor declaration, recognizer, and list of accessor functions.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type datatype_constructor_refined = { 
 | 
				
			||||||
 | 
					   constructor : func_decl; 
 | 
				
			||||||
 | 
					   recognizer : func_decl; 
 | 
				
			||||||
 | 
					   accessors : func_decl array 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_datatype_sort c ty ] \] is the array of triples [(constructor, recognizer, fields)] where [constructor] is the constructor declaration of [ty], [recognizer] is the recognizer for the [constructor], and [fields] is the array of fields in [ty].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_datatype_sort_num_constructors}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_datatype_sort_constructor}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_datatype_sort_recognizer}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_datatype_sort_constructor_accessor}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val get_datatype_sort: context -> sort -> datatype_constructor_refined array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_model_constants c m ] \] is the array of constants in the model [m].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_num_constants}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_constant}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_model_constants: context -> model -> func_decl array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_model_func_entry c m i j ] \] is the [j]'th entry in the [i]'th function in the model [m].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_entry_num_args}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_entry_arg}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_entry_value}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_model_func_entry: context -> model -> int -> int -> (ast array * ast);;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_model_func_entries c m i ] \] is the array of entries in the [i]'th function in the model [m].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_num_entries}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_entry}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_model_func_entries: context -> model -> int -> (ast array * ast) array;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_model_funcs c m ] \] is the array of functions in the model [m]. Each function is represented by the triple [(decl, entries, else)], where [decl] is the declaration name for the function, [entries] is the array of entries in the function, and [else] is the default (else) value for the function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_num_funcs}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_decl}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_entries}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_model_func_else}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_model_funcs: context -> model -> 
 | 
				
			||||||
 | 
					  (symbol *
 | 
				
			||||||
 | 
					   (ast array * ast) array * 
 | 
				
			||||||
 | 
					   ast) array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_smtlib_formulas c ] \] is the array of formulas created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_num_formulas}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_formula}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_smtlib_formulas: context -> ast array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [get_smtlib_assumptions c] \] is the array of assumptions created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_num_assumptions}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_assumption}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_smtlib_assumptions: context -> ast array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_smtlib_decls c ] \] is the array of declarations created by a preceding call to {!Z3.parse_smtlib_string} or {!Z3.parse_smtlib_file}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_num_decls}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_decl}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_smtlib_decls: context -> func_decl array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ get_smtlib_parse_results c ] \] is the triple [(get_smtlib_formulas c, get_smtlib_assumptions c, get_smtlib_decls c)].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommend use {!Z3.parse_smtlib_string_x} or {!Z3.parse_smtlib_file_x} for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_formulas}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_assumptions}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_decls}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val get_smtlib_parse_results: context -> (ast array * ast array * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ parse_smtlib_string_formula c ... ] \] calls [(parse_smtlib_string c ...)] and returns the single formula produced. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommended for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_formula}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_string_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ parse_smtlib_file_formula c ... ] \] calls [(parse_smtlib_file c ...)] and returns the single formula produced. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommended for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_formula}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_file_formula: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> ast
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ parse_smtlib_string_x c ... ] \] is [(parse_smtlib_string c ...; get_smtlib_parse_results c)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommended for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_parse_results}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_string_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ parse_smtlib_file_x c ... ] \] is [(parse_smtlib_file c ...; get_smtlib_parse_results c)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Recommended for functional style interface to the SMT-LIB parser.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_string_x}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.parse_smtlib_file}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_smtlib_parse_results}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val parse_smtlib_file_x: context -> string -> symbol array -> sort array -> symbol array -> func_decl array -> (ast array * ast array * func_decl array)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ symbol_refined ] \] is the refinement of a {!Z3.symbol} .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.symbol_refine}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_symbol_kind}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type symbol_refined =
 | 
				
			||||||
 | 
					  | Symbol_int of int
 | 
				
			||||||
 | 
					  | Symbol_string of string
 | 
				
			||||||
 | 
					  | Symbol_unknown;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ symbol_refine c s ] \] is the refined symbol of [s].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}:  {!Z3.symbol_refined}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_symbol_kind}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val symbol_refine: context -> symbol -> symbol_refined;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ sort_refined ] \] is the refinement of a {!Z3.sort} .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.sort_refine}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_sort_kind}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type sort_refined =
 | 
				
			||||||
 | 
					  | Sort_uninterpreted of symbol
 | 
				
			||||||
 | 
					  | Sort_bool
 | 
				
			||||||
 | 
					  | Sort_int
 | 
				
			||||||
 | 
					  | Sort_real
 | 
				
			||||||
 | 
					  | Sort_bv of int
 | 
				
			||||||
 | 
					  | Sort_array of (sort * sort)
 | 
				
			||||||
 | 
					  | Sort_datatype of datatype_constructor_refined array
 | 
				
			||||||
 | 
					  | Sort_relation
 | 
				
			||||||
 | 
					  | Sort_finite_domain
 | 
				
			||||||
 | 
					  | Sort_unknown of symbol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ sort_refine c t ] \] is the refined sort of [t].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}:  {!Z3.sort_refined}
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.get_sort_kind}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val sort_refine: context -> sort -> sort_refined;;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ binder_type ] \] is a universal or existential quantifier.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.term_refined}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type binder_type = | Forall | Exists 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ numeral_refined ] \] is the refinement of a numeral .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Numerals whose fractional representation can be fit with
 | 
				
			||||||
 | 
					  64 bit integers are treated as small.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type numeral_refined = 
 | 
				
			||||||
 | 
					  | Numeral_small  of int64 * int64
 | 
				
			||||||
 | 
					  | Numeral_large  of string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ term_refined ] \] is the refinement of a {!Z3.ast} .
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: {!Z3.term_refine}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					type term_refined = 
 | 
				
			||||||
 | 
					  | Term_app        of decl_kind * func_decl * ast array
 | 
				
			||||||
 | 
					  | Term_quantifier of binder_type * int * ast array array * (symbol * sort) array * ast
 | 
				
			||||||
 | 
					  | Term_numeral    of numeral_refined * sort
 | 
				
			||||||
 | 
					  | Term_var        of int * sort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [ term_refine c a ] \] is the refined term of [a].
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}:  {!Z3.term_refined}
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val term_refine : context -> ast -> term_refined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(** 
 | 
				
			||||||
 | 
					  \[ [mk_theory c name ] \] create a custom theory.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val mk_theory : context -> string -> theory
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_delete_callback th cb] \] set callback when theory gets deleted.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_delete_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_reduce_app_callback th cb] \] set callback for simplifying theory terms.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_reduce_app_callback : theory -> (func_decl -> ast array -> ast option) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_reduce_eq_callback th cb] \] set callback for simplifying equalities over theory terms.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_reduce_eq_callback : theory -> (ast -> ast -> ast option) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_reduce_distinct_callback th cb] \] set callback for simplifying disequalities over theory terms.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_reduce_distinct_callback : theory -> (ast array -> ast option) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_new_app_callback th cb] \] set callback for registering new application.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_new_app_callback : theory -> (ast -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_new_elem_callback th cb] \] set callback for registering new element.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - {b See also}: the help for the corresponding C API function.  
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_new_elem_callback : theory -> (ast -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_init_search_callback th cb] \] set callback when Z3 starts searching for a satisfying assignment.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_init_search_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_push_callback th cb] \] set callback for a logical context push.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_push_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_pop_callback th cb] \] set callback for a logical context pop.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_pop_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(**
 | 
				
			||||||
 | 
					  \[ [set_restart_callback th cb] \] set callback for search restart.
 | 
				
			||||||
 | 
					*)
 | 
				
			||||||
 | 
					val set_restart_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_reset_callback : theory -> (unit -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_final_check_callback : theory -> (unit -> bool) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_new_eq_callback : theory -> (ast -> ast -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_new_diseq_callback : theory -> (ast -> ast -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_new_assignment_callback : theory -> (ast -> bool -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					val set_new_relevant_callback : theory -> (ast -> unit) -> unit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
							
								
								
									
										607
									
								
								ml/z3.idl
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										607
									
								
								ml/z3.idl
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,607 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Z3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OCaml API for Z3.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    The following design is used for the treatment of reference counting:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - The conversion of Z3_context from ML to C remembers the Z3 context, and
 | 
				
			||||||
 | 
					      registers a finalizer using Gc.finalize that calls Z3_del_context.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - The conversion of Z3_ast and other reference counted types from C to ML:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      + stores the last translated context with the Z3_ast in the wrapper
 | 
				
			||||||
 | 
					        object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      + registers a finalizer using Gc.finalize that decrements the reference
 | 
				
			||||||
 | 
					        counter of the Z3_ast;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      + increments the reference count of the Z3_ast.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      The finalizers are registered using (the C interface to) Gc.finalize,
 | 
				
			||||||
 | 
					      not attaching a finalizer to a custom block.  The finalizers registered
 | 
				
			||||||
 | 
					      by Gc.finalize are guaranteed to be called in reverse
 | 
				
			||||||
 | 
					      registration-order, which is necessary to ensure that Z3_context's are
 | 
				
			||||||
 | 
					      finalized only after all the Z3_ast's within them.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - ML Z3.ast (and subtypes) are given generic hash and comparison
 | 
				
			||||||
 | 
					      operations using Z3_get_ast_hash and Z3_get_ast_id.  Other types could
 | 
				
			||||||
 | 
					      be handled similarly if analogous hash and id operations were exported
 | 
				
			||||||
 | 
					      by the C API.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - The wrapper for Z3_mk_context is customized (using quote(call,...) in
 | 
				
			||||||
 | 
					      z3_api.patched.h) to call Z3_mk_context_rc, and the ML API does not
 | 
				
			||||||
 | 
					      include mk_context_rc.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    This scheme relies on the property that all reference counted values
 | 
				
			||||||
 | 
					    returned from C to ML are in the Z3_context that was last sent from ML to
 | 
				
			||||||
 | 
					    C.  This is normally straightforward, but note that it depends on the
 | 
				
			||||||
 | 
					    argument order of e.g. the Z3_*translate functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Non-reference counted Z3 types that have delete operations have finalizers
 | 
				
			||||||
 | 
					    that call the delete operations.  The exposed delete operations are
 | 
				
			||||||
 | 
					    shadowed by nop functions.  The types whose delete operation accepts a
 | 
				
			||||||
 | 
					    context use Gc.finalize while those that do not use custom block
 | 
				
			||||||
 | 
					    finalizers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Custom c2ml functions check the Z3 error code prior to allocating ML
 | 
				
			||||||
 | 
					    values or registering finalizers.  Other functions check the Z3 error code
 | 
				
			||||||
 | 
					    after making a Z3 library call.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Some operations return NULL pointers when operations fail, or accept NULL
 | 
				
			||||||
 | 
					    pointers.  To handle these cases Z3_{ast,func_interp,sort}_opt types are
 | 
				
			||||||
 | 
					    introduced.  These are synonyms of Z3_{ast,func_interp,sort} but are
 | 
				
			||||||
 | 
					    translated into OCaml option types.  If the NULL pointers were passed to
 | 
				
			||||||
 | 
					    ML, even if the user does not access them, they will have finalizers
 | 
				
			||||||
 | 
					    registered, so when they die the OCaml GC will crash trying to call
 | 
				
			||||||
 | 
					    dec_ref on NULL.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    There is an alternate implementation, enabled by setting LEAK_CONTEXTS,
 | 
				
			||||||
 | 
					    that avoids the overhead of Gc.finalize finalizers, but at the price of
 | 
				
			||||||
 | 
					    leaking Z3_context objects.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Notes:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OCaml does not support unsigned types, so CamlIDL conflates signed and
 | 
				
			||||||
 | 
					    unsigned types of the same size.  Therefore, functions in the C API
 | 
				
			||||||
 | 
					    operating on unsigned values that become redundant after this conflation
 | 
				
			||||||
 | 
					    are excluded from the ML API using [#ifndef CAMLIDL] in z3_api.h.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CamlIDL does not support function pointers, so functions in the C API with
 | 
				
			||||||
 | 
					    function pointer arguments are handled manually.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Jakob Lichtenberg (JakobL) 2007-08-08
 | 
				
			||||||
 | 
					    Josh Berdine (jjb) 2012-03-21
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cpp trick to include expanded macro arguments in string literals
 | 
				
			||||||
 | 
					#define xstr(s) str(s)
 | 
				
			||||||
 | 
					#define str(s) #s
 | 
				
			||||||
 | 
					quote(c,"#define xstr(s) str(s)");
 | 
				
			||||||
 | 
					quote(c,"#define str(s) #s");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CamlIDL (1.05) has a bug where it does not accept [unsigned] as a type,
 | 
				
			||||||
 | 
					// only as a specifier, so unsigned is defined to be unsigned int.
 | 
				
			||||||
 | 
					#define unsigned unsigned int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Suppress "warning C4090: 'function' : different 'const' qualifiers" as
 | 
				
			||||||
 | 
					// CamlIDL does not seem to get this right.
 | 
				
			||||||
 | 
					quote(c,"#pragma warning(disable:4090)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef MLAPIV3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFINE_TYPE(T) typedef [abstract] void* T
 | 
				
			||||||
 | 
					#define DEFINE_VOID(T) typedef [abstract] void* T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BEGIN_MLAPI_EXCLUDE quote(mli,"(*");
 | 
				
			||||||
 | 
					#define END_MLAPI_EXCLUDE quote(mli,"*)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef LEAK_CONTEXTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Declare pointer type with custom conversion functions.
 | 
				
			||||||
 | 
					  #define DEFINE_CUST_TYPE(T) \
 | 
				
			||||||
 | 
					    typedef [abstract, ml2c(ml2c_Z3_ ## T), c2ml(c2ml_Z3_ ## T)] void* Z3_ ## T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // Declare pointer type with custom conversion functions.
 | 
				
			||||||
 | 
					  // Register an OCaml closure that just calls a C finalization function.
 | 
				
			||||||
 | 
					  #define DEFINE_CUST_TYPE(T) \
 | 
				
			||||||
 | 
					    quote(ml,xstr(\
 | 
				
			||||||
 | 
					      external finalize_Z3_ ## T : T -> unit = xstr(finalize_Z3_ ## T);; \
 | 
				
			||||||
 | 
					      let _ = Callback.register xstr(finalize_Z3_ ## T) finalize_Z3_ ## T \
 | 
				
			||||||
 | 
					    )); \
 | 
				
			||||||
 | 
					    typedef [abstract, ml2c(ml2c_Z3_ ## T), c2ml(c2ml_Z3_ ## T)] void* Z3_ ## T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Z3_context
 | 
				
			||||||
 | 
					quote(c,"
 | 
				
			||||||
 | 
					void check_error_code (Z3_context c);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Z3_context last_ctx;
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef LEAK_CONTEXTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"
 | 
				
			||||||
 | 
					  value c2ml_Z3_context(Z3_context* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    value v;
 | 
				
			||||||
 | 
					    v = caml_alloc_small(1, Abstract_tag);
 | 
				
			||||||
 | 
					    *((Z3_context *) Bp_val(v)) = *c;
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void ml2c_Z3_context(value v, Z3_context* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *c = *((Z3_context *) Bp_val(v));
 | 
				
			||||||
 | 
					    last_ctx = *c;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"
 | 
				
			||||||
 | 
					  // caml_final_register is the implementation of Gc.finalize
 | 
				
			||||||
 | 
					  value caml_final_register (value f, value v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void register_finalizer(value** closure, char* name, Z3_context ctx, value v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    if (*closure == NULL) {
 | 
				
			||||||
 | 
					      *closure = caml_named_value(name);
 | 
				
			||||||
 | 
					      if (*closure == NULL) {
 | 
				
			||||||
 | 
					        Z3_set_error(ctx, Z3_INTERNAL_FATAL);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    caml_final_register(**closure, v);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  value c2ml_Z3_context (Z3_context* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    static value* finalize_Z3_context_closure = NULL;
 | 
				
			||||||
 | 
					    value v;
 | 
				
			||||||
 | 
					    v = caml_alloc_small(1, Abstract_tag);
 | 
				
			||||||
 | 
					    Field(v, 0) = (value) *c;
 | 
				
			||||||
 | 
					    register_finalizer(&finalize_Z3_context_closure, \"finalize_Z3_context\",
 | 
				
			||||||
 | 
					                       (Z3_context) *c, v);
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  void ml2c_Z3_context (value v, Z3_context* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    *c = (Z3_context) Field(v, 0);
 | 
				
			||||||
 | 
					    last_ctx = *c;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  value finalize_Z3_context (value v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Z3_context c;
 | 
				
			||||||
 | 
					    c = (Z3_context) Field(v, 0);
 | 
				
			||||||
 | 
					    Z3_del_context(c);
 | 
				
			||||||
 | 
					    return Val_unit;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFINE_CUST_TYPE(context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Z3_symbol
 | 
				
			||||||
 | 
					typedef [abstract] void* Z3_symbol;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Z3_ast: reference counted type with hashing and comparison
 | 
				
			||||||
 | 
					quote(c,"
 | 
				
			||||||
 | 
					typedef struct _Z3_ast_context {
 | 
				
			||||||
 | 
					  Z3_ast ast;
 | 
				
			||||||
 | 
					  Z3_context ctx;
 | 
				
			||||||
 | 
					} Z3_ast_context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ml2c_Z3_ast (value v, Z3_ast* c)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  *c = ((Z3_ast_context*) Data_custom_val(v))->ast;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int compare_Z3_ast (value v1, value v2)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Z3_ast_context* ac1;
 | 
				
			||||||
 | 
					  Z3_ast_context* ac2;
 | 
				
			||||||
 | 
					  unsigned id1, id2;
 | 
				
			||||||
 | 
					  ac1 = Data_custom_val(v1);
 | 
				
			||||||
 | 
					  ac2 = Data_custom_val(v2);
 | 
				
			||||||
 | 
					  id1 = Z3_get_ast_id(ac1->ctx, ac1->ast);
 | 
				
			||||||
 | 
					  check_error_code(ac1->ctx);
 | 
				
			||||||
 | 
					  id2 = Z3_get_ast_id(ac2->ctx, ac2->ast);
 | 
				
			||||||
 | 
					  check_error_code(ac2->ctx);
 | 
				
			||||||
 | 
					  return id2 - id1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static intnat hash_Z3_ast (value v)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Z3_ast_context* ac;
 | 
				
			||||||
 | 
					  unsigned hash;
 | 
				
			||||||
 | 
					  ac = Data_custom_val(v);
 | 
				
			||||||
 | 
					  hash = Z3_get_ast_hash(ac->ctx, ac->ast);
 | 
				
			||||||
 | 
					  check_error_code(ac->ctx);
 | 
				
			||||||
 | 
					  return hash;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef LEAK_CONTEXTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"
 | 
				
			||||||
 | 
					  static void finalize_Z3_ast (value v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Z3_ast_context* ac;
 | 
				
			||||||
 | 
					    ac = Data_custom_val(v);
 | 
				
			||||||
 | 
					    Z3_dec_ref(ac->ctx, ac->ast);
 | 
				
			||||||
 | 
					    check_error_code(ac->ctx);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static struct custom_operations cops_Z3_ast = {
 | 
				
			||||||
 | 
					    NULL,
 | 
				
			||||||
 | 
					    finalize_Z3_ast,
 | 
				
			||||||
 | 
					    compare_Z3_ast,
 | 
				
			||||||
 | 
					    hash_Z3_ast,
 | 
				
			||||||
 | 
					    custom_serialize_default,
 | 
				
			||||||
 | 
					    custom_deserialize_default
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  value c2ml_Z3_ast (Z3_ast* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    value v;
 | 
				
			||||||
 | 
					    Z3_ast_context* ac;
 | 
				
			||||||
 | 
					    check_error_code(last_ctx);
 | 
				
			||||||
 | 
					    v = alloc_custom(&cops_Z3_ast, sizeof(Z3_ast_context), 0, 1);
 | 
				
			||||||
 | 
					    ac = Data_custom_val(v);
 | 
				
			||||||
 | 
					    ac->ctx = last_ctx;
 | 
				
			||||||
 | 
					    ac->ast = *c;
 | 
				
			||||||
 | 
					    Z3_inc_ref(ac->ctx, ac->ast);
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"
 | 
				
			||||||
 | 
					  value finalize_Z3_ast (value v)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    Z3_ast_context* ac;
 | 
				
			||||||
 | 
					    ac = Data_custom_val(v);
 | 
				
			||||||
 | 
					    Z3_dec_ref(ac->ctx, ac->ast);
 | 
				
			||||||
 | 
					    check_error_code(ac->ctx);
 | 
				
			||||||
 | 
					    return Val_unit;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  static struct custom_operations cops_Z3_ast = {
 | 
				
			||||||
 | 
					    NULL,
 | 
				
			||||||
 | 
					    custom_finalize_default,
 | 
				
			||||||
 | 
					    compare_Z3_ast,
 | 
				
			||||||
 | 
					    hash_Z3_ast,
 | 
				
			||||||
 | 
					    custom_serialize_default,
 | 
				
			||||||
 | 
					    custom_deserialize_default
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  value c2ml_Z3_ast (Z3_ast* c)
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    static value* finalize_Z3_ast_closure = NULL;
 | 
				
			||||||
 | 
					    value v;
 | 
				
			||||||
 | 
					    Z3_ast_context* ac;
 | 
				
			||||||
 | 
					    check_error_code(last_ctx);
 | 
				
			||||||
 | 
					    v = caml_alloc_custom(&cops_Z3_ast, sizeof(Z3_ast_context), 0, 1);
 | 
				
			||||||
 | 
					    ac = Data_custom_val(v);
 | 
				
			||||||
 | 
					    ac->ast = *c;
 | 
				
			||||||
 | 
					    ac->ctx = last_ctx;
 | 
				
			||||||
 | 
					    register_finalizer(&finalize_Z3_ast_closure, \"finalize_Z3_ast\",
 | 
				
			||||||
 | 
					                       (Z3_context) *c, v);
 | 
				
			||||||
 | 
					    Z3_inc_ref(last_ctx, *c);
 | 
				
			||||||
 | 
					    return v;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DEFINE_CUST_TYPE(ast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// subtypes of Z3_ast
 | 
				
			||||||
 | 
					quote(c,"\
 | 
				
			||||||
 | 
					#define DEFINE_SUBAST_OPS(T) \
 | 
				
			||||||
 | 
					  void ml2c_ ## T (value v, T * a) \
 | 
				
			||||||
 | 
					  { \
 | 
				
			||||||
 | 
					    ml2c_Z3_ast(v, (Z3_ast*) a); \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					 \
 | 
				
			||||||
 | 
					  value c2ml_ ## T (T * a) \
 | 
				
			||||||
 | 
					  { \
 | 
				
			||||||
 | 
					    return c2ml_Z3_ast((Z3_ast*) a); \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFINE_SUBAST(T) \
 | 
				
			||||||
 | 
					  typedef [mltype("private ast"), ml2c(ml2c_ ## T), c2ml(c2ml_ ## T)] Z3_ast T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"DEFINE_SUBAST_OPS(Z3_sort)");		DEFINE_SUBAST(Z3_sort);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_SUBAST_OPS(Z3_func_decl)");	DEFINE_SUBAST(Z3_func_decl);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_SUBAST_OPS(Z3_app)");		DEFINE_SUBAST(Z3_app);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_SUBAST_OPS(Z3_pattern)");	DEFINE_SUBAST(Z3_pattern);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// reference counted types without hashing and comparison
 | 
				
			||||||
 | 
					#ifdef LEAK_CONTEXTS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"\
 | 
				
			||||||
 | 
					  #define DEFINE_RC_OPS(T) \
 | 
				
			||||||
 | 
					    typedef struct _ ## T ## _context { \
 | 
				
			||||||
 | 
					      T dat; \
 | 
				
			||||||
 | 
					      Z3_context ctx; \
 | 
				
			||||||
 | 
					    } T ## _context; \
 | 
				
			||||||
 | 
					   \
 | 
				
			||||||
 | 
					    static void finalize_ ## T (value v) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      T ## _context* ac; \
 | 
				
			||||||
 | 
					      ac = Data_custom_val(v); \
 | 
				
			||||||
 | 
					      T ## _dec_ref(ac->ctx, ac->dat); \
 | 
				
			||||||
 | 
					      check_error_code(ac->ctx); \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					 \
 | 
				
			||||||
 | 
					    static struct custom_operations cops_ ## T = { \
 | 
				
			||||||
 | 
					      NULL, \
 | 
				
			||||||
 | 
					      finalize_ ## T, \
 | 
				
			||||||
 | 
					      custom_compare_default, \
 | 
				
			||||||
 | 
					      custom_hash_default, \
 | 
				
			||||||
 | 
					      custom_serialize_default, \
 | 
				
			||||||
 | 
					      custom_deserialize_default \
 | 
				
			||||||
 | 
					    }; \
 | 
				
			||||||
 | 
					 \
 | 
				
			||||||
 | 
					    value c2ml_ ## T (T * c) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      value v; \
 | 
				
			||||||
 | 
					      T ## _context* ac; \
 | 
				
			||||||
 | 
					      check_error_code(last_ctx); \
 | 
				
			||||||
 | 
					      v = alloc_custom(&cops_ ## T, sizeof(T ## _context), 0, 1); \
 | 
				
			||||||
 | 
					      ac = Data_custom_val(v); \
 | 
				
			||||||
 | 
					      ac->dat = *c; \
 | 
				
			||||||
 | 
					      ac->ctx = last_ctx; \
 | 
				
			||||||
 | 
					      T ## _inc_ref(ac->ctx, ac->dat); \
 | 
				
			||||||
 | 
					      return v; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					 \
 | 
				
			||||||
 | 
					    void ml2c_ ## T (value v, T * c) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      *c = ((T ## _context*) Data_custom_val(v))->dat; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  quote(c,"\
 | 
				
			||||||
 | 
					  #define DEFINE_RC_OPS(T) \
 | 
				
			||||||
 | 
					    value c2ml_ ## T (T * c) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      static value* finalize_ ## T ## _closure = NULL; \
 | 
				
			||||||
 | 
					      value v; \
 | 
				
			||||||
 | 
					      check_error_code(last_ctx); \
 | 
				
			||||||
 | 
					      v = caml_alloc_small(2, Abstract_tag); \
 | 
				
			||||||
 | 
					      Field(v, 0) = (value) *c; \
 | 
				
			||||||
 | 
					      Field(v, 1) = (value) last_ctx; \
 | 
				
			||||||
 | 
					      register_finalizer(&finalize_ ## T ## _closure, xstr(finalize_ ## T), \
 | 
				
			||||||
 | 
					                         (Z3_context) *c, v); \
 | 
				
			||||||
 | 
					      T ## _inc_ref(last_ctx, *c); \
 | 
				
			||||||
 | 
					      return v; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					   \
 | 
				
			||||||
 | 
					    void ml2c_ ## T (value v, T * c) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      *c = (T) Field(v, 0); \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					   \
 | 
				
			||||||
 | 
					    value finalize_ ## T (value v) \
 | 
				
			||||||
 | 
					    { \
 | 
				
			||||||
 | 
					      Z3_context c; \
 | 
				
			||||||
 | 
					      c = (Z3_context) Field(v, 1); \
 | 
				
			||||||
 | 
					      T ## _dec_ref(c, (T) Field(v, 0)); \
 | 
				
			||||||
 | 
					      check_error_code(c); \
 | 
				
			||||||
 | 
					      return Val_unit; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_params)");	   DEFINE_CUST_TYPE(params);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_param_descrs)");	   DEFINE_CUST_TYPE(param_descrs);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_model)");	   DEFINE_CUST_TYPE(model);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_func_interp)");  DEFINE_CUST_TYPE(func_interp);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_func_entry)");   DEFINE_CUST_TYPE(func_entry);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_fixedpoint)");   DEFINE_CUST_TYPE(fixedpoint);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_ast_vector)");   DEFINE_CUST_TYPE(ast_vector);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_ast_map)");	   DEFINE_CUST_TYPE(ast_map);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_goal)");	   DEFINE_CUST_TYPE(goal);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_tactic)");	   DEFINE_CUST_TYPE(tactic);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_probe)");	   DEFINE_CUST_TYPE(probe);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_apply_result)"); DEFINE_CUST_TYPE(apply_result);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_solver)");	   DEFINE_CUST_TYPE(solver);
 | 
				
			||||||
 | 
					quote(c,"DEFINE_RC_OPS(Z3_stats)");	   DEFINE_CUST_TYPE(stats);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// possibly-NULL pointer types, translated to OCaml option types
 | 
				
			||||||
 | 
					quote(c,"\
 | 
				
			||||||
 | 
					#define DEFINE_OPT_OPS(T) \
 | 
				
			||||||
 | 
					  void ml2c_ ## T ## _opt (value v, T* c) \
 | 
				
			||||||
 | 
					  { \
 | 
				
			||||||
 | 
					    struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; \
 | 
				
			||||||
 | 
					    camlidl_ctx _ctx = &_ctxs; \
 | 
				
			||||||
 | 
					    if (v != Val_int(0)) { \
 | 
				
			||||||
 | 
					      camlidl_ml2c_z3_ ## T(Field(v, 0), c, _ctx); \
 | 
				
			||||||
 | 
					    } else { \
 | 
				
			||||||
 | 
					      *c = NULL; \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					  } \
 | 
				
			||||||
 | 
					 \
 | 
				
			||||||
 | 
					  value c2ml_ ## T ## _opt (T* c) \
 | 
				
			||||||
 | 
					  { \
 | 
				
			||||||
 | 
					    struct camlidl_ctx_struct _ctxs = { CAMLIDL_TRANSIENT, NULL }; \
 | 
				
			||||||
 | 
					    camlidl_ctx _ctx = &_ctxs; \
 | 
				
			||||||
 | 
					    value v; \
 | 
				
			||||||
 | 
					    value a; \
 | 
				
			||||||
 | 
					    if (*c) { \
 | 
				
			||||||
 | 
					      a = camlidl_c2ml_z3_ ## T(c, _ctx); \
 | 
				
			||||||
 | 
					      Begin_root(a) \
 | 
				
			||||||
 | 
					        v = caml_alloc_small(1, 0); \
 | 
				
			||||||
 | 
					        Field(v, 0) = a; \
 | 
				
			||||||
 | 
					      End_roots(); \
 | 
				
			||||||
 | 
					    } else { \
 | 
				
			||||||
 | 
					      v = Val_int(0); \
 | 
				
			||||||
 | 
					    } \
 | 
				
			||||||
 | 
					    return v; \
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFINE_OPT_TYPE(T) \
 | 
				
			||||||
 | 
					  typedef [mltype(xstr(T option)), \
 | 
				
			||||||
 | 
					           ml2c(ml2c_Z3_ ## T ## _opt), \
 | 
				
			||||||
 | 
					           c2ml(c2ml_Z3_ ## T ## _opt) \
 | 
				
			||||||
 | 
					          ] Z3_ ## T Z3_ ## T ## _opt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"DEFINE_OPT_OPS(Z3_ast)");
 | 
				
			||||||
 | 
					DEFINE_OPT_TYPE(ast);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"DEFINE_OPT_OPS(Z3_sort)");
 | 
				
			||||||
 | 
					DEFINE_OPT_TYPE(sort);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(c,"DEFINE_OPT_OPS(Z3_func_interp)");
 | 
				
			||||||
 | 
					DEFINE_OPT_TYPE(func_interp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ToDo: these unnecessarily appear in the API documentation
 | 
				
			||||||
 | 
					DEFINE_TYPE(Z3_constructor);
 | 
				
			||||||
 | 
					DEFINE_TYPE(Z3_constructor_list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// shadow delete operations with nops
 | 
				
			||||||
 | 
					quote(ml,"
 | 
				
			||||||
 | 
					let del_constructor _ _ = ()
 | 
				
			||||||
 | 
					let del_constructor_list _ _ = ()
 | 
				
			||||||
 | 
					let del_model _ _ = ()
 | 
				
			||||||
 | 
					let del_context _ = ()
 | 
				
			||||||
 | 
					let reset_memory () = ()
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else // MLAPIV3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Provide custom error handler:
 | 
				
			||||||
 | 
					quote (c,"Z3_error_handler caml_z3_error_handler;");
 | 
				
			||||||
 | 
					quote (c,"void caml_z3_error_handler(Z3_context c, Z3_error_code e) { static char buffer[128]; char * msg = Z3_get_error_msg_ex(c, e); if (strlen(msg) > 100) { failwith(\"Z3: error message is too big to fit in buffer\"); } else { sprintf(buffer, \"Z3: %s\", msg); failwith(buffer); } }");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DEFINE_TYPE(T) typedef [abstract] void* T
 | 
				
			||||||
 | 
					#define DEFINE_VOID(T) typedef [abstract] void* T
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define BEGIN_MLAPI_EXCLUDE
 | 
				
			||||||
 | 
					#define END_MLAPI_EXCLUDE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // MLAPIV3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __in
 | 
				
			||||||
 | 
					#define __in [in]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __out
 | 
				
			||||||
 | 
					#define __out [out]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __out_opt
 | 
				
			||||||
 | 
					#define __out_opt [out,unique]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __ecount
 | 
				
			||||||
 | 
					#define __ecount(num_args) [NOT_SUPPORTED]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __in_ecount
 | 
				
			||||||
 | 
					#define __in_ecount(num_args) [in, size_is(num_args), length_is(num_args)]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __out_ecount
 | 
				
			||||||
 | 
					#define __out_ecount(num_args) [out, size_is(num_args), length_is(num_args)]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __inout_ecount
 | 
				
			||||||
 | 
					#define __inout_ecount(num_args) [in, out, size_is(num_args), length_is(num_args)]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef __inout
 | 
				
			||||||
 | 
					#define __inout [in, out]
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifndef Z3_bool_opt
 | 
				
			||||||
 | 
					#define Z3_bool_opt void
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define Z3_API
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef MLAPIV3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "z3V3_api.idl"
 | 
				
			||||||
 | 
					#include "x3V3.mli"
 | 
				
			||||||
 | 
					#include "x3V3.ml"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "z3_api.idl"
 | 
				
			||||||
 | 
					#include "x3.ml"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(ml,"
 | 
				
			||||||
 | 
					let _ =
 | 
				
			||||||
 | 
					  Printexc.register_printer (function
 | 
				
			||||||
 | 
					    | Error(c,e) -> Some (\"Z3 \"^(get_error_msg c e))
 | 
				
			||||||
 | 
					    | _ -> None
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mli,"
 | 
				
			||||||
 | 
					(** 
 | 
				
			||||||
 | 
					   {2 {L Legacy V3 API}} 
 | 
				
			||||||
 | 
					*) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module V3 : sig
 | 
				
			||||||
 | 
					(** 
 | 
				
			||||||
 | 
					   {2 {L Legacy V3 API}} 
 | 
				
			||||||
 | 
					*) 
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(ml,"
 | 
				
			||||||
 | 
					module V3 = struct
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef MLAPIV3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					quote(mlmli,"
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
							
								
								
									
										11
									
								
								ml/z3.proj
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								ml/z3.proj
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <MLLibs Include="$(SLAMSRC)\slam\engine\slam2\z3\z3.cmxa"/>
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <MLFlags>$(MLFlags) -I $(SLAMSRC)\slam\engine\slam2\z3</MLFlags>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										18966
									
								
								ml/z3_stubs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										18966
									
								
								ml/z3_stubs.c
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										339
									
								
								ml/z3_theory_stubs.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										339
									
								
								ml/z3_theory_stubs.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,339 @@
 | 
				
			||||||
 | 
					/*++
 | 
				
			||||||
 | 
					Copyright (c) 2010 Microsoft Corporation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Module Name:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    z3_theory_stubs.c
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Abstract:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OCaml C bindings for callbacks between OCaml and C for
 | 
				
			||||||
 | 
					    theory plugins. 
 | 
				
			||||||
 | 
					    The API for theory plugins require associating a set of
 | 
				
			||||||
 | 
					    callbacks as C function pointers.  
 | 
				
			||||||
 | 
					    We use the following strategy:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - store in the user_ext_data blob that theory constructors allow
 | 
				
			||||||
 | 
					      a record of callback functions.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    - define catch-all static callback functions that access the 
 | 
				
			||||||
 | 
					      ML record with the callbacks. It then invokes these through user-registered
 | 
				
			||||||
 | 
					      application functions that apply the callback stored in the record to the
 | 
				
			||||||
 | 
					      actual parameters.
 | 
				
			||||||
 | 
					      It is tempting to avoid this user-registered callback and directly access 
 | 
				
			||||||
 | 
					      the record of callback functions and apply the proper field. 
 | 
				
			||||||
 | 
					      However, the layout of records appears to be opaque, or at least we assume it is
 | 
				
			||||||
 | 
					      so, from the C runtime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Author:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Revision History:
 | 
				
			||||||
 | 
					--*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <stddef.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <caml/mlvalues.h>
 | 
				
			||||||
 | 
					#include <caml/memory.h>
 | 
				
			||||||
 | 
					#include <caml/alloc.h>
 | 
				
			||||||
 | 
					#include <caml/fail.h>
 | 
				
			||||||
 | 
					#include <caml/callback.h>
 | 
				
			||||||
 | 
					#ifdef Custom_tag
 | 
				
			||||||
 | 
					#include <caml/custom.h>
 | 
				
			||||||
 | 
					#include <caml/bigarray.h>
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "z3.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define ML_SIZE(_ty) ((sizeof(_ty) + sizeof(value) - 1)/ sizeof(value))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static value mk_func_decl(Z3_func_decl f) {
 | 
				
			||||||
 | 
					    value _f = alloc(ML_SIZE(Z3_func_decl), Abstract_tag);
 | 
				
			||||||
 | 
					    *((Z3_func_decl*) Bp_val(_f)) = f;
 | 
				
			||||||
 | 
					    return _f;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static value Val_ast(Z3_ast a) {
 | 
				
			||||||
 | 
					    value _a = alloc(ML_SIZE(Z3_ast), Abstract_tag);
 | 
				
			||||||
 | 
					    *((Z3_ast*) Bp_val(_a)) = a;
 | 
				
			||||||
 | 
					    return _a;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static value Val_ast_array(unsigned int sz, Z3_ast const args[]) {
 | 
				
			||||||
 | 
					    value res;
 | 
				
			||||||
 | 
					    Z3_ast* args1;
 | 
				
			||||||
 | 
					    unsigned int i;
 | 
				
			||||||
 | 
					    args1 = malloc((sz+1)*sizeof(Z3_ast));
 | 
				
			||||||
 | 
					    for (i = 0; i < sz; ++i) {
 | 
				
			||||||
 | 
					        args1[i] = args[i];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    args1[sz] = 0;
 | 
				
			||||||
 | 
					    res = alloc_array((value (*)(char const*))Val_ast, (const char**)args1);
 | 
				
			||||||
 | 
					    free(args1);
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ------------------
 | 
				
			||||||
 | 
					// get_theory_callbacks
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					value get_theory_callbacks(value th) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    Z3_theory _th = *((Z3_theory*) Bp_val(th));
 | 
				
			||||||
 | 
					    return (value) Z3_theory_get_ext_data(_th);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ------------------
 | 
				
			||||||
 | 
					// delete_theory
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					static void delete_callback_static(Z3_theory th) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CAMLparam0();
 | 
				
			||||||
 | 
					    CAMLlocal1(f);  
 | 
				
			||||||
 | 
					    value user_data = (value) Z3_theory_get_ext_data(th);
 | 
				
			||||||
 | 
					    f = *(caml_named_value("apply_delete")) ;
 | 
				
			||||||
 | 
					    callback(f, user_data);
 | 
				
			||||||
 | 
					    remove_global_root(&user_data);
 | 
				
			||||||
 | 
					    CAMLreturn0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define SET_CALLBACK(_cb_name)                     \
 | 
				
			||||||
 | 
					    value set_ ## _cb_name ## _callback_register(value th)  \
 | 
				
			||||||
 | 
					    {                                              \
 | 
				
			||||||
 | 
					        CAMLparam1(th);                                         \
 | 
				
			||||||
 | 
					        Z3_theory _th = *((Z3_theory*) Bp_val(th));                     \
 | 
				
			||||||
 | 
					        Z3_set_ ## _cb_name ## _callback(_th, _cb_name ## _callback_static);   \
 | 
				
			||||||
 | 
					        CAMLreturn(Val_unit);                                           \
 | 
				
			||||||
 | 
					    }                                                                   \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SET_CALLBACK(delete);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ------------------
 | 
				
			||||||
 | 
					// mk_theory
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					value mk_theory_register(value context, value name, value user_data) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CAMLparam3(context, name, user_data);
 | 
				
			||||||
 | 
					    Z3_context _context = *((Z3_context *) Bp_val(context));
 | 
				
			||||||
 | 
					    value _th;
 | 
				
			||||||
 | 
					    Z3_theory th;
 | 
				
			||||||
 | 
					    register_global_root(&user_data);
 | 
				
			||||||
 | 
					    th = Z3_mk_theory(_context, String_val(name), (void*)user_data);
 | 
				
			||||||
 | 
					    // jjb: test th == NULL ?
 | 
				
			||||||
 | 
					    Z3_set_delete_callback(th, delete_callback_static);
 | 
				
			||||||
 | 
					    _th = alloc(ML_SIZE(Z3_context), Abstract_tag);
 | 
				
			||||||
 | 
					    *((Z3_theory*) Bp_val(_th)) = th;
 | 
				
			||||||
 | 
					    CAMLreturn(_th);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// reduce_app_callback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Z3_bool reduce_app_callback_static(Z3_theory th, Z3_func_decl f, unsigned num_args, Z3_ast const args[], Z3_ast* r) {
 | 
				
			||||||
 | 
					    CAMLparam0();
 | 
				
			||||||
 | 
					    CAMLlocal4(cb, _r, _v, _args);
 | 
				
			||||||
 | 
					    value user_data;
 | 
				
			||||||
 | 
					    Z3_bool result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _args = Val_ast_array(num_args, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_reduce_app"));
 | 
				
			||||||
 | 
					    _r = callback3(cb, user_data, mk_func_decl(f), _args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("is_some"));
 | 
				
			||||||
 | 
					    _v = callback(cb, _r);
 | 
				
			||||||
 | 
					    result = 0 != Bool_val(_v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result && r) {
 | 
				
			||||||
 | 
					        cb = *(caml_named_value("get_some"));
 | 
				
			||||||
 | 
					        _v = callback(cb, _r);
 | 
				
			||||||
 | 
					        *r = *((Z3_ast*) Bp_val(_v));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CAMLreturn (result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SET_CALLBACK(reduce_app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// reduce_eq_callback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Z3_bool reduce_eq_callback_static(Z3_theory th, Z3_ast a, Z3_ast b, Z3_ast * r) 
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CAMLparam0();
 | 
				
			||||||
 | 
					    CAMLlocal5(cb, _r, _a, _b, _v);
 | 
				
			||||||
 | 
					    value user_data;
 | 
				
			||||||
 | 
					    Z3_bool result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _a = Val_ast(a);
 | 
				
			||||||
 | 
					    _b = Val_ast(b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_reduce_eq"));
 | 
				
			||||||
 | 
					    _r = callback3(cb, user_data, _a, _b);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("is_some"));
 | 
				
			||||||
 | 
					    _v = callback(cb, _r);
 | 
				
			||||||
 | 
					    result = 0 != Bool_val(_v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result && r) {
 | 
				
			||||||
 | 
					        cb = *(caml_named_value("get_some"));
 | 
				
			||||||
 | 
					        _v = callback(cb, _r);
 | 
				
			||||||
 | 
					        *r = *((Z3_ast*) Bp_val(_v));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CAMLreturn (result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SET_CALLBACK(reduce_eq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// reduce_distinct
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Z3_bool reduce_distinct_callback_static(Z3_theory th, unsigned n, Z3_ast const args[], Z3_ast * r)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    CAMLparam0();
 | 
				
			||||||
 | 
					    CAMLlocal4(cb, _r, _args, _v);
 | 
				
			||||||
 | 
					    value user_data;
 | 
				
			||||||
 | 
					    Z3_bool result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _args = Val_ast_array(n, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_reduce_distinct"));
 | 
				
			||||||
 | 
					    _r = callback2(cb, user_data, _args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("is_some"));
 | 
				
			||||||
 | 
					    _v = callback(cb, _r);
 | 
				
			||||||
 | 
					    result = 0 != Bool_val(_v);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (result && r) {
 | 
				
			||||||
 | 
					        cb = *(caml_named_value("get_some"));
 | 
				
			||||||
 | 
					        _v = callback(cb, _r);
 | 
				
			||||||
 | 
					        *r = *((Z3_ast*) Bp_val(_v));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CAMLreturn (result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SET_CALLBACK(reduce_distinct);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// new_app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AST_CALLBACK(_cb_name) \
 | 
				
			||||||
 | 
					static void _cb_name##_callback_static(Z3_theory th, Z3_ast a)        \
 | 
				
			||||||
 | 
					{                                                           \
 | 
				
			||||||
 | 
					    CAMLparam0();                                           \
 | 
				
			||||||
 | 
					    CAMLlocal3(cb, _a, user_data);                          \
 | 
				
			||||||
 | 
					    _a = Val_ast(a);                                         \
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);         \
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_" #_cb_name));           \
 | 
				
			||||||
 | 
					    callback2(cb, user_data, _a);                           \
 | 
				
			||||||
 | 
					    CAMLreturn0;                                            \
 | 
				
			||||||
 | 
					}                                                           \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST_CALLBACK(new_app);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// new_elem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST_CALLBACK(new_elem);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_elem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// init_search
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define TH_CALLBACK(_cb_name) \
 | 
				
			||||||
 | 
					static void _cb_name##_callback_static(Z3_theory th)        \
 | 
				
			||||||
 | 
					{                                                           \
 | 
				
			||||||
 | 
					    CAMLparam0();                                           \
 | 
				
			||||||
 | 
					    CAMLlocal2(cb, user_data);                              \
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);         \
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_" #_cb_name));           \
 | 
				
			||||||
 | 
					    callback(cb, user_data);                                \
 | 
				
			||||||
 | 
					    CAMLreturn0;                                            \
 | 
				
			||||||
 | 
					}                                                           \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TH_CALLBACK(init_search);
 | 
				
			||||||
 | 
					SET_CALLBACK(init_search);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// -------------------
 | 
				
			||||||
 | 
					// push
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TH_CALLBACK(push);
 | 
				
			||||||
 | 
					SET_CALLBACK(push);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TH_CALLBACK(pop);
 | 
				
			||||||
 | 
					SET_CALLBACK(pop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TH_CALLBACK(restart);
 | 
				
			||||||
 | 
					SET_CALLBACK(restart);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TH_CALLBACK(reset);
 | 
				
			||||||
 | 
					SET_CALLBACK(reset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					#define FC_CALLBACK(_cb_name) \
 | 
				
			||||||
 | 
					    static Z3_bool _cb_name##_callback_static(Z3_theory th)             \
 | 
				
			||||||
 | 
					    {                                                                   \
 | 
				
			||||||
 | 
					    CAMLparam0();                                                       \
 | 
				
			||||||
 | 
					    CAMLlocal3(cb, r, user_data);                                       \
 | 
				
			||||||
 | 
					    user_data = (value) Z3_theory_get_ext_data(th);                     \
 | 
				
			||||||
 | 
					    cb = *(caml_named_value("apply_" #_cb_name));                       \
 | 
				
			||||||
 | 
					    r = callback(cb, user_data);                                        \
 | 
				
			||||||
 | 
					    CAMLreturn (Bool_val(r) != 0);                                      \
 | 
				
			||||||
 | 
					    }                                                                   \
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					FC_CALLBACK(final_check);
 | 
				
			||||||
 | 
					SET_CALLBACK(final_check);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AST_AST_CALLBACK(_cb_name) \
 | 
				
			||||||
 | 
					    static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_ast b)     \
 | 
				
			||||||
 | 
					    {                                                                   \
 | 
				
			||||||
 | 
					        CAMLparam0();                                                   \
 | 
				
			||||||
 | 
					        CAMLlocal4(cb, _a, _b, user_data);                              \
 | 
				
			||||||
 | 
					        _a = Val_ast(a);                                                \
 | 
				
			||||||
 | 
					        _b = Val_ast(b);                                                \
 | 
				
			||||||
 | 
					        user_data = (value) Z3_theory_get_ext_data(th);                 \
 | 
				
			||||||
 | 
					        cb = *(caml_named_value("apply_" #_cb_name));                   \
 | 
				
			||||||
 | 
					        callback3(cb, user_data, _a, _b);                               \
 | 
				
			||||||
 | 
					        CAMLreturn0;                                                    \
 | 
				
			||||||
 | 
					    }                                                                   \
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					AST_AST_CALLBACK(new_eq);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_eq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST_AST_CALLBACK(new_diseq);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_diseq);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define AST_BOOL_CALLBACK(_cb_name) \
 | 
				
			||||||
 | 
					    static void _cb_name##_callback_static(Z3_theory th, Z3_ast a, Z3_bool b)     \
 | 
				
			||||||
 | 
					    {                                                                   \
 | 
				
			||||||
 | 
					        CAMLparam0();                                                   \
 | 
				
			||||||
 | 
					        CAMLlocal4(cb, _a, _b, user_data);                              \
 | 
				
			||||||
 | 
					        _a = Val_ast(a);                                                \
 | 
				
			||||||
 | 
					        _b = Val_bool(b);                                               \
 | 
				
			||||||
 | 
					        user_data = (value) Z3_theory_get_ext_data(th);                 \
 | 
				
			||||||
 | 
					        cb = *(caml_named_value("apply_" #_cb_name));                   \
 | 
				
			||||||
 | 
					        callback3(cb, user_data, _a, _b);                               \
 | 
				
			||||||
 | 
					        CAMLreturn0;                                                    \
 | 
				
			||||||
 | 
					    }                                                                   \
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					AST_BOOL_CALLBACK(new_assignment);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_assignment);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AST_CALLBACK(new_relevant);
 | 
				
			||||||
 | 
					SET_CALLBACK(new_relevant);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										73
									
								
								python/mk_z3consts.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								python/mk_z3consts.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,73 @@
 | 
				
			||||||
 | 
					############################################
 | 
				
			||||||
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
 | 
					# 
 | 
				
			||||||
 | 
					# Extract enumeration types from z3_api.h
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author: Leonardo de Moura (leonardo)
 | 
				
			||||||
 | 
					############################################
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					blank_pat      = re.compile("^ *$")
 | 
				
			||||||
 | 
					comment_pat    = re.compile("^ *//.*$")
 | 
				
			||||||
 | 
					typedef_pat    = re.compile("typedef enum *")
 | 
				
			||||||
 | 
					typedef2_pat   = re.compile("typedef enum { *")
 | 
				
			||||||
 | 
					openbrace_pat  = re.compile("{ *")
 | 
				
			||||||
 | 
					closebrace_pat = re.compile("}.*;")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					api = open('..\\lib\\z3_api.h', 'r')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					z3consts  = open('z3consts.py', 'w')
 | 
				
			||||||
 | 
					z3consts.write('# Automatically generated file, generator: mk_z3consts.py\n\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEARCHING  = 0
 | 
				
			||||||
 | 
					FOUND_ENUM = 1
 | 
				
			||||||
 | 
					IN_ENUM    = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mode    = SEARCHING
 | 
				
			||||||
 | 
					decls   = {}
 | 
				
			||||||
 | 
					idx     = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					linenum = 1
 | 
				
			||||||
 | 
					for line in api:
 | 
				
			||||||
 | 
					    m1 = blank_pat.match(line)
 | 
				
			||||||
 | 
					    m2 = comment_pat.match(line)
 | 
				
			||||||
 | 
					    if m1 or m2:
 | 
				
			||||||
 | 
					        # skip blank lines and comments
 | 
				
			||||||
 | 
					        linenum = linenum + 1 
 | 
				
			||||||
 | 
					    elif mode == SEARCHING:
 | 
				
			||||||
 | 
					        m = typedef_pat.match(line)
 | 
				
			||||||
 | 
					        if m:
 | 
				
			||||||
 | 
					            mode = FOUND_ENUM
 | 
				
			||||||
 | 
					        m = typedef2_pat.match(line)
 | 
				
			||||||
 | 
					        if m:
 | 
				
			||||||
 | 
					            mode = IN_ENUM
 | 
				
			||||||
 | 
					            decls = {}
 | 
				
			||||||
 | 
					            idx   = 0
 | 
				
			||||||
 | 
					    elif mode == FOUND_ENUM:
 | 
				
			||||||
 | 
					        m = openbrace_pat.match(line)
 | 
				
			||||||
 | 
					        if m:
 | 
				
			||||||
 | 
					            mode  = IN_ENUM
 | 
				
			||||||
 | 
					            decls = {}
 | 
				
			||||||
 | 
					            idx   = 0
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            assert False, "Invalid z3_api.h, line: %s" % linenum
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        assert mode == IN_ENUM
 | 
				
			||||||
 | 
					        words = re.split('[^\-a-zA-Z0-9_]+', line)
 | 
				
			||||||
 | 
					        m = closebrace_pat.match(line)
 | 
				
			||||||
 | 
					        if m:
 | 
				
			||||||
 | 
					            name = words[1]
 | 
				
			||||||
 | 
					            z3consts.write('# enum %s\n' % name)
 | 
				
			||||||
 | 
					            for k, i in decls.iteritems():
 | 
				
			||||||
 | 
					                z3consts.write('%s = %s\n' % (k, i))
 | 
				
			||||||
 | 
					            z3consts.write('\n')
 | 
				
			||||||
 | 
					            mode = SEARCHING
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if words[2] != '':
 | 
				
			||||||
 | 
					                if len(words[2]) > 1 and words[2][1] == 'x':
 | 
				
			||||||
 | 
					                    idx = int(words[2], 16)
 | 
				
			||||||
 | 
					                else:
 | 
				
			||||||
 | 
					                    idx = int(words[2])
 | 
				
			||||||
 | 
					            decls[words[1]] = idx
 | 
				
			||||||
 | 
					            idx = idx + 1
 | 
				
			||||||
 | 
					    linenum = linenum + 1
 | 
				
			||||||
							
								
								
									
										38
									
								
								python/mk_z3tactics.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								python/mk_z3tactics.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					############################################
 | 
				
			||||||
 | 
					# Copyright (c) 2012 Microsoft Corporation
 | 
				
			||||||
 | 
					# 
 | 
				
			||||||
 | 
					# Extract tactics and probes from install_tactics.cpp
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Author: Leonardo de Moura (leonardo)
 | 
				
			||||||
 | 
					############################################
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					tactic_pat  = re.compile("^[ \t]*ADD_TACTIC_CMD")
 | 
				
			||||||
 | 
					probe_pat   = re.compile("^[ \t]*ADD_PROBE")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cppfile = open('..\\lib\\install_tactics.cpp', 'r')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					z3tactics  = open('z3tactics.py', 'w')
 | 
				
			||||||
 | 
					z3tactics.write('# Automatically generated file, generator: mk_z3tactics.py\n')
 | 
				
			||||||
 | 
					z3tactics.write('import z3core\n')
 | 
				
			||||||
 | 
					z3tactics.write('import z3\n\n')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for line in cppfile:
 | 
				
			||||||
 | 
					    m1 = tactic_pat.match(line)
 | 
				
			||||||
 | 
					    m2 = probe_pat.match(line)
 | 
				
			||||||
 | 
					    if m1:
 | 
				
			||||||
 | 
					        words     = re.split('[^\-a-zA-Z0-9_]+', line)
 | 
				
			||||||
 | 
					        tactic    = words[2]
 | 
				
			||||||
 | 
					        py_tactic = tactic.replace('-', '_')
 | 
				
			||||||
 | 
					        z3tactics.write('def %s_tactic(ctx=None):\n' % py_tactic)
 | 
				
			||||||
 | 
					        z3tactics.write('  ctx = z3._get_ctx(ctx)\n')
 | 
				
			||||||
 | 
					        z3tactics.write('  return z3.Tactic(z3core.Z3_mk_tactic(ctx.ref(), \'%s\'), ctx)\n\n' % tactic)
 | 
				
			||||||
 | 
					    elif m2:
 | 
				
			||||||
 | 
					        words = re.split('[^\-a-zA-Z0-9_]+', line)
 | 
				
			||||||
 | 
					        probe     = words[2]
 | 
				
			||||||
 | 
					        py_probe  = probe.replace('-', '_')
 | 
				
			||||||
 | 
					        z3tactics.write('def %s_probe(ctx=None):\n' % py_probe)
 | 
				
			||||||
 | 
					        z3tactics.write('  ctx = z3._get_ctx(ctx)\n')
 | 
				
			||||||
 | 
					        z3tactics.write('  return z3.Probe(z3core.Z3_mk_probe(ctx.ref(), \'%s\'), ctx)\n\n' % probe)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,6 @@
 | 
				
			||||||
sd edit dll\z3.def
 | 
					pushd dll
 | 
				
			||||||
sd edit dll\z3_dbg.def
 | 
					 | 
				
			||||||
cd dll
 | 
					 | 
				
			||||||
python mk_def.py
 | 
					python mk_def.py
 | 
				
			||||||
cd ..
 | 
					popd
 | 
				
			||||||
sd edit Microsoft.Z3\native.cs
 | 
					 | 
				
			||||||
sd edit Microsoft.Z3\enumerations.cs
 | 
					 | 
				
			||||||
sd edit lib\api_log_macros.h
 | 
					 | 
				
			||||||
sd edit lib\api_log_macros.cpp
 | 
					 | 
				
			||||||
sd edit lib\api_commands.cpp
 | 
					 | 
				
			||||||
sd edit python\z3core.py
 | 
					 | 
				
			||||||
sd edit ml\z3.mli
 | 
					 | 
				
			||||||
sd edit ml\z3.ml
 | 
					 | 
				
			||||||
sd edit ml\z3_stubs.c
 | 
					 | 
				
			||||||
pushd lib
 | 
					pushd lib
 | 
				
			||||||
python api.py
 | 
					python api.py
 | 
				
			||||||
popd
 | 
					popd
 | 
				
			||||||
| 
						 | 
					@ -19,12 +8,9 @@ pushd Microsoft.Z3
 | 
				
			||||||
python mk_z3consts.py
 | 
					python mk_z3consts.py
 | 
				
			||||||
popd
 | 
					popd
 | 
				
			||||||
pushd python
 | 
					pushd python
 | 
				
			||||||
sd edit z3consts.py
 | 
					 | 
				
			||||||
python mk_z3consts.py
 | 
					python mk_z3consts.py
 | 
				
			||||||
sd edit z3tactics.py
 | 
					 | 
				
			||||||
python mk_z3tactics.py
 | 
					python mk_z3tactics.py
 | 
				
			||||||
popd
 | 
					popd
 | 
				
			||||||
pushd ml 
 | 
					pushd ml 
 | 
				
			||||||
call build.cmd 32
 | 
					call build.cmd 32
 | 
				
			||||||
popd
 | 
					popd
 | 
				
			||||||
sd revert -a ...
 | 
					 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue