Repository: thomasjball/PyExZ3 Branch: master Commit: 7dac957d57bd Files: 140 Total size: 1.2 MB Directory structure: gitextract_nf65lu9d/ ├── .gitattributes ├── .gitignore ├── README.md ├── TODO.md ├── Vagrantfile ├── copyright.txt ├── fail/ │ ├── arrayindex.py │ ├── dictbool.py │ ├── divzero.py │ ├── git.py │ ├── pow.py │ └── sqrttest.py ├── marktoberdorf_paper/ │ ├── DSE/ │ │ ├── CodeReview.pptx │ │ ├── DSE.mdk │ │ ├── IOS-Book-Article.cls │ │ ├── cpp2.json │ │ ├── dse.bib │ │ ├── ignores.dic │ │ └── out/ │ │ └── DSE.tex │ ├── DSE.html │ └── forPublisher/ │ ├── IOS-Book-Article.cls │ ├── css.sty │ ├── dse.tex │ └── madoko.sty ├── marktoberdorf_slides/ │ ├── CodeReview.pptx │ ├── Marktoberdorf2014_1.pptx │ ├── Marktoberdorf2014_2.pptx │ ├── Marktoberdorf2014_3.pptx │ ├── Marktoberdorf2014_4.pptx │ ├── collatz.py │ └── examples/ │ ├── adder.py │ ├── automata.py │ ├── check_adder.py │ ├── check_mult.py │ ├── first.py │ ├── hats.py │ ├── mult.py │ └── mult2.py ├── pyexz3.py ├── run_tests.py ├── setup.bat ├── setup.sh ├── symbolic/ │ ├── __init__.py │ ├── args.py │ ├── constraint.py │ ├── cvc_expr/ │ │ ├── __init__.py │ │ ├── exprbuilder.py │ │ ├── expression.py │ │ ├── integer.py │ │ └── string.py │ ├── cvc_wrap.py │ ├── explore.py │ ├── invocation.py │ ├── loader.py │ ├── path_to_constraint.py │ ├── predicate.py │ ├── symbolic_types/ │ │ ├── __init__.py │ │ ├── symbolic_dict.py │ │ ├── symbolic_int.py │ │ ├── symbolic_str.py │ │ └── symbolic_type.py │ ├── z3_expr/ │ │ ├── __init__.py │ │ ├── bitvector.py │ │ ├── expression.py │ │ └── integer.py │ └── z3_wrap.py ├── test/ │ ├── abs_test.py │ ├── andor.py │ ├── arrayindex2.py │ ├── bad_eq.py │ ├── bignum.py │ ├── binary_search.py │ ├── bitwidth.py │ ├── complex.py │ ├── cseppento1.py │ ├── cseppento2.py │ ├── cseppento3.py │ ├── cvc/ │ │ ├── effectivebool.py │ │ ├── emptystr.py │ │ ├── escape.py │ │ ├── none.py │ │ ├── strcontains.py │ │ ├── strcount.py │ │ ├── strfind.py │ │ ├── strfindbeg.py │ │ ├── strindex.py │ │ ├── stringadd.py │ │ ├── stringtest.py │ │ ├── strmiddle.py │ │ ├── strreplace.py │ │ ├── strslice.py │ │ ├── strsplit.py │ │ ├── strstartswith.py │ │ ├── strstrip.py │ │ └── strsubstring.py │ ├── decorator.py │ ├── decorator_dict.py │ ├── diamond.py │ ├── dict.py │ ├── dictionary.py │ ├── elseif.py │ ├── expand.py │ ├── expressions.py │ ├── filesys.py │ ├── fp.py │ ├── gcd.py │ ├── hashval.py │ ├── len_test.py │ ├── lib/ │ │ ├── __init__.py │ │ ├── bsearch.py │ │ └── se_dict.py │ ├── list.py │ ├── logical_op.py │ ├── loop.py │ ├── many_branches.py │ ├── maxtest.py │ ├── mod.py │ ├── modulo.py │ ├── modulo2.py │ ├── mult_assmt.py │ ├── polyspace.py │ ├── power.py │ ├── power2.py │ ├── powtest.py │ ├── reverse.py │ ├── set.py │ ├── shallow_branches.py │ ├── simple.py │ ├── swap.py │ ├── tmp │ ├── tuplecmp.py │ ├── unnecessary_condition.py │ ├── unnecessary_condition2.py │ ├── unnecessary_condition3.py │ ├── unnecessary_condition4.py │ ├── weird.py │ └── whileloop.py ├── tools/ │ └── symbolic_int_subtype.py ├── utils.py └── vagrant.sh ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # Auto detect text files and perform LF normalization * text=auto # Custom for Visual Studio *.cs diff=csharp *.sln merge=union *.csproj merge=union *.vbproj merge=union *.fsproj merge=union *.dbproj merge=union # Standard to msysgit *.doc diff=astextplain *.DOC diff=astextplain *.docx diff=astextplain *.DOCX diff=astextplain *.dot diff=astextplain *.DOT diff=astextplain *.pdf diff=astextplain *.PDF diff=astextplain *.rtf diff=astextplain *.RTF diff=astextplain ================================================ FILE: .gitignore ================================================ ################# ## Eclipse ################# *.pydevproject .project .metadata bin/ tmp/ *.tmp *.bak *.swp *~.nib local.properties .classpath .settings/ .loadpath # External tool builders .externalToolBuilders/ # Locally stored "Eclipse launch configurations" *.launch # CDT-specific .cproject # PDT-specific .buildpath ################# ## Visual Studio ################# ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.sln.docstates # Build results [Dd]ebug/ [Rr]elease/ x64/ build/ [Bb]in/ [Oo]bj/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* *_i.c *_p.c *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.log *.scc # Visual C++ cache files ipch/ *.aps *.ncb *.opensdf *.sdf *.cachefile # Visual Studio profiler *.psess *.vsp *.vspx # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch *.ncrunch* .*crunch*.local.xml # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.Publish.xml *.pubxml # NuGet Packages Directory ## TODO: If you have NuGet Package Restore enabled, uncomment the next line #packages/ # Windows Azure Build Output csx *.build.csdef # Windows Store app package directory AppPackages/ # Others sql/ *.Cache ClientBin/ [Ss]tyle[Cc]op.* ~$* *~ *.dbmdl *.[Pp]ublish.xml *.pfx *.publishsettings # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file to a newer # Visual Studio version. Backup files are not needed, because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files App_Data/*.mdf App_Data/*.ldf ############# ## Windows detritus ############# # Windows image file caches Thumbs.db ehthumbs.db # Folder config file Desktop.ini # Recycle Bin used on file shares $RECYCLE.BIN/ # Mac crap .DS_Store ############# ## Python ############# *.py[co] # Packages *.egg *.egg-info dist/ build/ eggs/ parts/ var/ sdist/ develop-eggs/ .installed.cfg # Installer logs pip-log.txt # Unit test / coverage reports .coverage .tox #Translations *.mo #Mr Developer .mr.developer.cfg # PyEx stuff se_normalized/ logfile stdout *.out *.py# #stdout# #stdout.old# #tmp# *.dot tmp.txt ############# ## Vagrant ############# .vagrant ############# ## PyCharm ############# .idea ================================================ FILE: README.md ================================================ PyExZ3 ====== ### Python Exploration with Z3 This code is a substantial rewrite of the NICE project's (http://code.google.com/p/nice-of/) symbolic execution engine for Python, now using the Z3 theorem prover (http://z3.codeplex.com). We have removed the NICE-specific dependences, platform-specific code, and made various improvements, documented below, so it can be used by anyone wanting to experiment with dynamic symbolic execution. The paper [Deconstructing Dynamic Symbolic Execution](http://research.microsoft.com/apps/pubs/?id=233035) explains the basic ideas behind dynamic symbolic execution and the architecture of the PyExZ3 tool (as of git tag v1.0). Bruni, Disney and Flanagan wrote about encoding symbolic execution for Python in Python in the same way in their 2008 paper [A Peer Architecture for Lightweight Symbolic Execution](http://hoheinzollern.files.wordpress.com/2008/04/seer1.pdf) - they use proxies rather than multiple inheritance for representing symbolic versions of Python types. In the limit, **PyExZ3** attempts to *explore* all the feasible paths in a Python function by: - executing the function on a concrete input to trace a path through the control flow of the function; - symbolic executing the path to determine how its conditions depend on the function's input parameters; - generating new values for the parameters to drive the function to yet uncovered paths, using Z3. For small programs without loops or recursion, **PyExZ3** may be able to explore all feasible paths. A novel aspect of the rewrite is to rely solely on Python's operator overloading to accomplish all the interception needed for symbolic execution; no AST rewriting or bytecode instrumentation is required, This significantly improves the robustness and portability of **PyExZ3**, as well as reducing its size. ### Setup instructions: - Make sure that you use Python 32-bit (64-bit) if-and-only-if you use the Z3 32-bit (64-bit) binaries. Testing so far has been on Python 3.2.3 and 32-bit. - Install Python 3.2.3 (https://www.python.org/download/releases/3.2.3/) - Install the latest "unstable" release of Z3 to directory Z3HOME from http://z3.codeplex.com/releases (click on the "Planned" link on the right to get the latest binaries for all platforms) - Add Z3HOME\bin to PATH and PYTHONPATH - MacOS: setup.sh for Homebrew default locations for Python and Z3; see end for MacOS specific instructions - Optional: -- install GraphViz utilities (http://graphviz.org/) ### Check that everything works: - `python run_tests.py test` should pass all tests - `python pyexz3.py test\FILE.py` to run a single test from the test directory ### Usage of PyExZ3 - **Basic usage**: give a Python file `FILE.py` as input. By default, `pyexz3` expects `FILE.py` to contain a function named `FILE` where symbolic execution will start: - `pyexz3 FILE.py` - **Starting function**: You can override the default starting function with `--start MAIN`, where `MAIN` is the name of a function in `FILE`: - pyexz3 `--start=MAIN` FILE.py - **Bounding the number of iterations** of the path exploration is essential when analyzing functions with loops and/or recursion. Specify a bound using the `max-iters` flag: - pyexz3 `--max-iters=42` FILE.py - **Arguments to starting function**: by default, pyexz3 associates a symbolic integer (with initial value 0) for each parameter of the starting function. Import from `symbolic.args` to get the `@concrete` and `@symbolic` decorators that let you override the defaults on the starting function: ``` from symbolic.args import * @concrete(a=1,b=2) @symbolic(c=3) def startingfun(a,b,c,d): ... ``` The `@concrete` decorator declares that a parameter will not be treated symbolically and provides an initial value for the parameter. The `@symbolic` decorator declares that a parameter will be treated symbolically - the type of the associated initial value for the argument will be used to determine the proper symbolic type (if one exists). In the above example, parameters `a` and `b` are treated concretely and will have initial values `1` and `2` (for all paths explored), and parameter `c` will be treated as a symbolic integer input with the initial value `3` (its value can change after first path has been explored). Since parameter `d` is not specified, it will be treated as a symbolic integer input with the initial value 0: - **Output**: `pyexz3` prints the list of generated inputs and corresponding observed return values to standard out; the lists of generated inputs and the corresponding return values are returned by the exploration engine to `pyexz3` where they can be used for other purposes, as described below. - **Expected result functions** are used for testing of `pyexz3`. If the `FILE.py` contains a function named `expected_result` then after path exploration is complete, the list of return values will be compared against the list returned by `expected_result`. More precisely, the two lists are converted into bags and the bags compared for equality. If a function named `expected_result_set` is present instead, the list are converted into sets and the sets are compared for equality. List equality is too strong a criteria for testing, since small changes to programs can lead to paths being explored in different orders. - **Import behavior**: the location of the `FILE.py` is added to the import path so that all imports in `FILE.py` relative to that file will work. - **Other options** - `--graph=DOTFILE` - `--log=LOGFILE` ### MacOS specific 1. Grab yourself a Brew at http://brew.sh/ 2. Get the newest python or python3 version: `brew install python` 3. Have the system prefer brew python over system python: `echo export PATH='/usr/local/bin:$PATH' >> ~/.bash_profile` - 4. Get z3: `brew install homebrew/science/z3` 5. Clone this repository: `git clone https://github.com/thomasjball/PyExZ3.git` 6. Set the PATH: `. PyExZ3/setup.sh` (do not run the setup script in a subshell `./ PyExZ3/`) ### Vagrant specific [Vagrant](http://www.vagrantup.com/) is a cross-platform tool to manage virtualized development environments. Vagrant runs on Windows, OS X, and Linux and can manage virtual machines running on VirtualBox, VMware, Docker, and Hyper-V. 1. [Download Vagrant](http://www.vagrantup.com/downloads.html). 2. Install [VirtualBox](https://www.virtualbox.org/) or configure an [alternative provider](http://docs.vagrantup.com/v2/providers/index.html). 3. Run `vagrant up` from the PyExZ3 directory. The Vagrantfile in the repository tells Vagrant to download a Debian base image, launch it with the default provider (VirtualBox), and run the script `vagrant.sh` to provision the machine. 4. Once the provisioning is done you can SSH into the machine using `vagrant ssh` and PyExZ3 is ready to run. Please note that the provisioning takes a while as Git is compiled from source as Debian's Git is incompatible with [CodePlex](http://www.codeplex.com/) where Z3 is hosted. ### CVC SMT Solver By default PyExZ3 uses the Z3 to solve path predicates. Optionally, the [CVC SMT](http://cvc4.cs.nyu.edu/web/) solver can be enabled with the `--cvc` argument. While the two solvers offer a similar feature set, the integration of CVC differs from Z3 in a number of ways. Most predominately, the CVC integration uses an unbounded rational number representation for Python numbers, converting to bit vectors only for bitwise operations. The Z3 integration uses bounded bit vectors for all numbers. For programs that use any significant number of bitwise operations, the default Z3-based configuration is strongly recommended. Additionally, CVC does not support generating models for non-linear relationships causing a few of the included PyExZ3 test cases to fail with a `LogicException`. ================================================ FILE: TODO.md ================================================ TODO List ========= - add basic support for SymbolicDictionary - - need to capture exceptions thrown by code under test as test results - interesting question arises about re-initialization of input arguments by ExplorationEngine and re-import of module under test in the face of mutable initial objects - we want the re-import to be done before the re-initialization, but that's not how it currently works. Easiest thing to do is only allow empty dictionary to be specified in @symbolic - check input/output behavior separately from sym_exe - use consist case on names (Caml or C, choose one) ================================================ FILE: Vagrantfile ================================================ # -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.define "linux", primary: true do |v| v.vm.provision "shell", path: "vagrant.sh" v.vm.box = "chef/debian-7.4" end config.vm.provider "virtualbox" do |v| v.memory = 1024 end end ================================================ FILE: copyright.txt ================================================ # Files that mention copyright.txt were derived from the NICE project # # Copyright (c) 2011, EPFL (Ecole Politechnique Federale de Lausanne) # All rights reserved. # # Created by Marco Canini, Daniele Venzano, Dejan Kostic, Jennifer Rexford # # Updated by Thonas Ball (2014) # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # - Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # - Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # - Neither the names of the contributors, nor their associated universities or # organizations may be used to endorse or promote products derived from this # software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES # OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT # SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ================================================ FILE: fail/arrayindex.py ================================================ A = [0, 1] # the index operation A[i] uses the underlying runtime representation # of the Python int, so we have no way of capturing this "conditional # through lookup" operation via inheritance from int, as done with # SymbolicInteger # see test\arrayindex2.py for the rewriting we would need to do # to make the lookup explicit (greatly expanding the search space) def arrayindex(i): if A[i]: return A[i] else: return "OTHER" def expected_result(): return [ 1, "OTHER" ] ================================================ FILE: fail/dictbool.py ================================================ from symbolic.args import * @symbolic(d={}) def dictbool(d): x = d or {} if x == {}: return 0 return 1 def expected_result(): return [0, 1] ================================================ FILE: fail/divzero.py ================================================ # this one fails because we always start with zero for SymbolicIntegers # we should have a few seed values to avoid this. def divzero(in1,in2): try: if in1 / in2 >= 0: return 1 elif in1 / in2 < 0: return 2 return 0 except: return "DIVZERO" def expected_result(): return [0,1,2,"DIVZERO"] ================================================ FILE: fail/git.py ================================================ from symbolic.args import * @symbolic(a=0xdeaddeaddeaddead,b=0xbeefbeefbeefbeef) def git(a,b): i=0; passkeyn=[a,b] expandedkey=[] while i<6: # while i<2: # WORKS expandedkey=expandedkey+passkeyn i=i+1 v1=passkeyn[0] v2=passkeyn[1] v3=(v1>>0x30)|(((v1>>0x20)&0xffff)<<0x10)|(((v1>>0x10)&0xffff)<<0x20)|((v1&0xffff)<<0x30) v4=(v2>>0x30)|(((v2>>0x20)&0xffff)<<0x10)|(((v2>>0x10)&0xffff)<<0x20)|((v2&0xffff)<<0x30) v5 = ((v4 & 0xFFFFFF8000000000) >> 39) | ((v3 << 25)&0xffffffffffffffff); v6 = ((v3 & 0xFFFFFF8000000000) >> 39) | ((v4 << 25)&0xffffffffffffffff); v1=(v5>>0x30)|(((v5>>0x20)&0xffff)<<0x10)|(((v5>>0x10)&0xffff)<<0x20)|(((v4 & 0xFFFFFF8000000000) >> 39)<<0x30) v2=(v6>>0x30)|(((v6>>32)&0xffff)<<0x10)|(((v6>>0x10)&0xffff)<<0x20)|(((v3 & 0xFFFFFF8000000000) >> 39)<<0x30) passkeyn=[v1,v2] expandedkey=expandedkey+passkeyn print(expandedkey) if expandedkey==[16045725885737590445, 13758425323549998831, 7044313620519854103485, 8215411798635391606653, 8245388070021240879798, 3384596836810669685695, 9287860625795901259255, 4527376222128629444341, 4093654381503457390331, 4647353382867023162077, 8665057901351565392853, 8816957627389395711965, 6783497306152038280055, 9291067819851303074799]: # WORKS # if expandedkey==[16045725885737590445, 13758425323549998831, 7044313620519854103485, 8215411798635391606653, 8245388070021240879798, 3384596836810669685695]: print("HERE") return 1 else: print("THERE") return 2 if __name__ == "__main__": git(0xdeaddeaddeaddead,0xbeefbeefbeefbeef) ================================================ FILE: fail/pow.py ================================================ # this one fails because we treat the operator ** concretely rather than symbolically # so that the concrete value 0**2 is substituted in place of x**2. # As a result, we never get to calling the theorem prover def pow(x): if 4 == x**2: return "POW" else: return "OTHER" def expected_result(): return [ "OTHER", "POW" ] ================================================ FILE: fail/sqrttest.py ================================================ from math import sqrt # sqrt is handled concretely, just as with pow (**) def sqrttest(in1): if sqrt(in1) == 0: return 1 elif sqrt(in1) > 0: return 2 return 0 def expected_result(): return [1,2] ================================================ FILE: marktoberdorf_paper/DSE/DSE.mdk ================================================ Title : Deconstructing Dynamic Symbolic Execution Author : Thomas Ball, Jakub Daniel Affiliation : Microsoft Research, Charles University Email : tball@microsoft.com, jakub.daniel@d3s.mff.cuni.cz Doc Class : IOS-Book-Article.cls Colorizer : javascript Colorizer : cpp Colorizer : cpp2 Bib style : plainnat Bibliography: dse Heading base: 2 .rulename : replace=/(.*)/(\1)/ font-variant=small-caps ~MathPre,.math-inline,.math-display: replace=/=\^=/{~\buildrel\triangle\over=~}/g ~MathPre,.math-inline,.math-display,~Equation: replace=/\bSt\b/\sigma/g ~Pre,~Code: language=python .code2 : language=cpp2 .language-cpp2 : replace="/\b([TR])(')?(_.)?/\(T|$\1\2\3$\)/g" ~ HtmlOnly [TITLE] ~ ~ TexRaw \begin{frontmatter} % The preamble begins here. %\pretitle{Pretitle} \title{Deconstructing Dynamic Symbolic Execution} %\runningtitle{IOS Press Style Sample} %\subtitle{Subtitle} \author[A]{\fnms{Thomas} \snm{Ball}} and \author[B]{\fnms{Jakub} \snm{Daniel}} \runningauthor{Thomas Ball et al.} \address[A]{Microsoft Research} \address[B]{Charles University} ~ ~ Abstract Dynamic symbolic execution (DSE) is a well-known technique for automatically generating tests to achieve higher levels of coverage in a program. Two keys ideas of DSE are to: (1) seed symbolic execution by executing a program on an initial input; (2) use concrete values from the program execution in place of symbolic expressions whenever symbolic reasoning is hard or not desired. We describe DSE for a simple core language and then present a minimalist implementation of DSE for Python (in Python) that follows this basic recipe. The code is available at https://www.github.com/thomasjball/PyExZ3/ (tagged "v1.0") and has been designed to make it easy to experiment with and extend. ~ ~ TexRaw \begin{keyword} Symbolic Execution, Automatic Test Generation, White-box Testing, Automated Theorem Provers \end{keyword} \end{frontmatter} \thispagestyle{empty} \pagestyle{empty} ~ [PyExZ3]: https://github.com/thomasjball/PyExZ3/ [Z3]: http://z3.codeplex.org/ [MRO]: https://www.python.org/download/releases/2.3/mro/ # Introduction { #sec-intro } ~ MathDefs \defcommand{\mathkw}[1]{\textbf{#1}} ~ Static, path-based symbolic execution explores one control-flow path at a time through a (sequential) program $P$, using an automated theorem prover (ATP) to determine if the current path $p$ is feasible [@King76;@Clarke76]. Ideally, symbolic execution of a path $p$ through program $P$ yields a logic formula $\phi_p$ that describes the set of inputs $I$ (possibly empty) to program $P$ such that for any $i \in I$, the execution $P(i)$ follows path $p$. If the formula $\phi_p$ is unsatisfiable then $I$ is empty and so path $p$ is not feasible; if the formula is satisfiable then $I$ is not empty and so path $p$ is feasible. In this case, a model of $\phi_p$ provides a witness $i \in I$. Thus, a model-generating ATP can be used in conjunction with symbolic execution to automatically generate tests to cover paths in a program. Combined with a search strategy, one gets, in the limit, an exhaustive white-box testing procedure, for which there are many applications [@CadarGPDE06; @GodefroidLM12; @CadarS13]. The formula $\phi_p$ is called a *path-condition* of the path $p$. We will see that a given path $p$ can induce many different path-conditions. A path-condition $\psi_p$ for path $p$ is *sound* if every input assignment satisfying $\psi_p$ defines an execution of program $P$ that follows path $p$ [@Godefroid11]. By its definition, the formula $\phi_p$ is sound and the best representation of $p$ (as for all sound path-conditions $\psi_p$, we have that $\psi_p \implies \phi_p$). In practice, we attempt to compute sound under-approximations of $\phi_p$ such as $\psi_p$. However, we also find it necessary (and useful) to compute unsound path-conditions. A path-condition can be translated into the input language of an ATP, such as [Z3][Z3][@deMouraB08], which provides an answer of "unsatisfiable", "satisfiable" or "unknown", due to theoretical or practical limitations in automatically deciding satisfiability of various logics. In the case that the ATP is able to prove "satisfiable" we can query it for satisfying model in order to generate test inputs. A path-condition for $p$ can be thought of as function from a program's primary inputs to a Boolean output representing whether or not $p$ is executed under a given input. Thus, we are asking the ATP to invert a function when we ask it to decide the satisfiability/unsatisfiability of a path-condition. The static translation of a path $p$ through a program $P$ into the most precise path-condition $\phi_p$ is not a simple task, as programming languages and their semantics are very complex. Completely characterizing the set of inputs $I$ that follow path $p$ means providing a symbolic interpretation of every operation in the language so that the ATP can reason about it. For example, consider a method call in Python. Python's algorithm for method resolution order (see [MRO]) depends on the inheritance hierarchy of the program, a directed, acyclic graph that can evolve during program execution. Symbolically encoding Python's method resolution order is possible but non-trivial. There are other reasons it is hard or undesirable to symbolically execute various operations, as will be explained in detail later. ## Dynamic symbolic execution *Dynamic* symbolic execution (DSE) is a form of path-based symbolic execution based on two insights. First, the approach starts by executing program $P$ on some input $i$, seeding the symbolic execution process with a feasible path [@Korel90;@Korel92;@Gupta00]. Second, DSE uses concrete values from the execution $P(i)$ in place of symbolic expressions whenever symbolic reasoning is not possible or desired [@GodefroidKS05;@CadarE05]. The major benefit of DSE is to simplify the construction of a symbolic execution tool by leveraging concrete execution behavior (given by actually running the program). As DSE combines both concrete and symbolic reasoning, it also has been called "concolic" execution [@SenACAV06]. ~ Figure { #fig-DSE caption="Pseudo-code for dynamic symbolic execution" } ``` i = an input to program P while defined(i): p = path covered by execution P(i) cond = pathCondition(p) s = ATP(Not(cond)) i = s.model() ``` ~ The pseudo-code of Figure [#fig-DSE] shows the high level process of DSE. The variable `i` represents an input to program `P`. Execution of program `P` on the input `i` traces a path `p`, from which a logical formula `pathCondition(p)` is constructed. Finally, the ATP is called with the negation of the path-condition to find a new input (that hopefully will cover a new path). This pseudo-code elides a number of details that we will deal with later. ~ Figure { #fig-easy-DSE caption="Easy example: computing the maximum of four numbers in Python."} ``` def max2(s,t): if (s < t): return t else: return s def max4(a,b,c,d): return max2(max2(a,b),max2(c,d)) ``` ~ Consider the Python function `max4` in Figure [#fig-easy-DSE], which computes the maximum of four numbers via three calls to the function `max2`. Suppose we execute `max4` with values of zero for all four arguments. In this case, the execution path $p$ contains three comparisons (in the order `(a < b)`, `(c < d)`, `(a < c)`), all of which evaluate false. Thus, the path-condition for path $p$ is `(not(a 0 and y > 0 and z > 0): if (x*x*x + y*y*y == z*z*z): return "Fermat and Wiles were wrong!?!" return 0 ``` ~ Fermat's Last Theorem, proved by Andrew Wiles in the late 20th century, states that no three positive integers $x$, $y$, and $z$ can satisfy the equation $x^n + y^n = z^n$ for any integer value of $n$ greater than two. The function `fermat3` encodes this statement for $n=3$. It is not reasonable to have a computer waste time trying to find a solution that would cause `fermat3` to print the string `"Fermat and Wiles were wrong!?!"`. In cases of complex (non-linear) arithmetic operations, such as `x*x*x`, we might choose to handle the operation concretely. There are a number of ways to deal with the above issue: one is to recognize all non-linear terms in a symbolic expression and replace them with their concrete counterparts during execution. For the `fermat3` example, this would mean that during DSE the symbolic expression `(x*x*x + y*y*y == z*z*z)` would be reduced to the constant `False` by evaluation on the concrete values of variables `x`, `y` and `z`. Besides difficult operations (such as non-linear arithmetic), other examples of code that we might treat concretely instead of symbolically include functions that are hard to invert, such as cryptographic hash functions, or low-level functions that we do not wish to test (such as operating system functions). Consider the code in Figure [#fig-hash], which applies the function `unknown` to argument `x` and compares it to argument `y`. By using the name `unknown` we simply mean to say that we wish to model this function as a black box, with no knowledge of how it operates internally. ~ Figure { #fig-hash caption="Another hard example for symbolic execution"} ``` def dart(x,y): if (unknown(x) == y): return 1 return 0 ``` ~ In such a case, we can use DSE to execute the function `unknown` on a specific input (say `5013`) and observe its output (say `42`). That is, rather than execute `unknown` symbolically and invoke an ATP to invert the function's path-condition, we simply treat the call to `unknown` concretely, substituting its return value (in this case `42`) for the specialized expression `unknown(5013) == y` to get the predicate `(42 == y)`. Adding the constraint `(x == 5013)` yields the sound but rather specific path-condition `(x == 5013) and (42 == y)`. Note that the path-condition `(42 == y)` is not sound, as it admits any value for the variable `x`, which likely includes many values for which `(unknown(x) == y)` is false. ## Overview This introduction elides many important issues that arise in implementing DSE for a real language, which we will focus on in the remainder of the paper. These include how to: * Identify the code under test $P$ and the symbolic inputs to $P$; * Trace the control flow path $p$ taken by execution $P(i)$; * Reinterpret program operations to compute symbolic expressions; * Generate a path-condition from $p$ and the symbolic expressions; * Generate a new input $i'$ by negating (part of) the path-condition, translating the path-condition to the input language of an ATP, invoking the ATP, and lifting a satisfying model (if any) back up to the source level; * Guide the search to expose new paths. The rest of this paper is organized as follows. Section [#sec-semantics] describes an instrumented typing discipline where we lift each type (representing a set of concrete values) to a symbolic type (representing a set of pairs of concrete and symbolic values). Section [#sec-sp2dse] shows how strongest postconditions defines a symbolic semantics for a small programming language and how strongest postconditions can be refined to model DSE. Section [#sec-impl] describes an implementation of DSE for the Python language in the Python language that follows the instrumented semantics pattern closely (full implementation and tests available at [PyExZ3], tagged "v1.0"). Section [#sec-int2z3] describes the symbolic encoding of Python integer operations using two decision procedures of Z3: linear arithmetic with uninterpreted functions in place of non-linear operations; fixed-width bit-vectors with precise encodings of most operations. Section [#sec-extensions] offers a number of ideas for projects to extend the capabilities of [PyExZ3]. # Instrumented Types { #sec-semantics } We are given a universe of classes/types $U$; a type $T \in U$ carries along a set of operations that apply to values of type $T$, where an operation $o \in T$ takes an argument list of typed values as input (the first being of type $T$) and produces a single typed value as output. Nullary (static) operations of type $T$ can be used to create values of type $T$ (such as constants, objects, etc.) A program $P$ has typed input variables $v_1 : T_1 \ldots v_k : T_k$ and a body from the language of statements $S$: ~MathPre S \rightarrow & v := E | & @skip | & S_1 ; S_2 | & @if E @then S_1 @else S_2 @end | & @while E @do S @end ~ The language of expressions ($E$) is defined by the application of operations to values, where constants (nullary operations) and program variables form the leaves of the expression tree and non-nullary operators form the interior nodes of the tree. For now, we will consider all values to be immutable. That is, the only source of mutation in the language is the assignment statement. To introduce symbolic execution into the picture, we can imagine that a type $T \in U$ has (one or more) counterparts in a symbolic universe $U'$. A type $T' \in U'$ is a subtype of $T \in U$ with two purposes: * First, a value of type $T'$ represents a pair of values: a concrete value $c$ of (super)type $T$ and a symbolic expression $e$. A symbolic expression is a tree whose leaves are either nullary operators (i.e., constants) of a type in $U$ or are Skolem constants representing the (symbolic) inputs ($v_1 \ldots v_k$) to the program $P$, and whose interior nodes represent operations from types in $U$. We refer to Skolem constants as "symbolic constants" from this point on. Note that symbolic expressions do not contain references to program variables. * Second, the type $T'$ redefines some of the operations $o \in T$, namely those for which we wish to compute symbolic expressions. An operation $o \in T'$ has the same parameter list as $o \in T$, allowing it to take inputs with types from both $U$ and $U'$. The return type of $o \in T'$ generally is from $U'$ (though it can be from $U$). Thus, $o \in T'$ is a proper function subtype of $o \in T$. The purpose of $o \in T'$ is to: (1) perform operation $o \in T$ on the concrete values associated with its inputs; (2) build a symbolic expression tree rooted at operation $o$ whose children are the trees associated with the inputs to $o$. Figure [#fig-subtype] presents pseudo code for the instrumentation of a type $T$ via a type $T'$. The class ``Symbolic`` is used to hold an expression tree (``Expr``). Given a class $T \in U$, a symbolic type $T' \in U'$ is defined by inheriting from both $T$ and ``Symbolic``. This ensures that a $T'$ can be used wherever a $T$ is expected. ~ Figure { #fig-subtype caption="Type instrumentation to carry both concrete values and symbolic expressions." } ``` cpp2 class T' : T, Symbolic { T'(c:T, e:Expr) : T(c), Symbolic(e) {} override o(this:T, f1:T_1, ... , fk:T_k) : R' { var c := T.o(this, f1, ... ,fk) var e := new Expr(T.o, expr(self), expr(f1), ..., expr(fk)) return new R'(c,e) } ... } class R' : R, Symbolic { ... } function expr(v) = v instanceof Symbolic ? v.getExpr() : v ``` ~ A type such as $T'$ only can be constructed by providing a concrete value $c$ of type $T$ and a symbolic expression $e$ to the constructor for $T'$. This will be done in exactly two places: * by the creation of symbolic constants associated with the primary inputs ($v_1 \ldots v_k$) to the program; * by the instrumented operations as shown in Figure [#fig-subtype]. An instrumented operation $o$ on arguments (``this``, `f1`, ..., `fk`) first invokes its corresponding underlying operator $T.o$ on arguments (``this``, `f1`, ..., `fk`) to get concrete value `c`. It then constructs a new expression tree `e` rooted at operator $T.o$, whose children are the result of mapping the function `expr` over (``this``, `f1`, ..., `fk`). The helper function `expr(v)` evaluates to an expression tree in the case that `v` is of ``Symbolic`` type (representing a type in $U'$) and evaluates to `v` itself, a concrete value of some type in $U$, otherwise. Finally, having computed the values `c` and `e`, the instrumented operator returns ``\($R'$\)(c,e)``, where $R$ is the return type of operator $T.o$, and $R'$ is a subtype of $R$ from universe $U'$. Looked at another way, the universe $U'$ represents the "tainting" of types from $U$. Tainted values flow from program inputs to the operands of operators. If an operator has been redefined (as above) then the taint propagates from its inputs to its outputs. On the other hand, if the operator has not been redefined, then it will not propagate the taint. In the context of DSE, "taint" means that the instrumented semantics carries along a symbolic expression tree $e$ along with a concrete value $c$. The choice of types from the universe $U'$ determines how symbolic expressions are constructed. For each $T \in U$, the "most symbolic" (least concrete) choice is the $T'$ that redefines every operator of $T$ (as shown in Figure [#fig-subtype]). The "least symbolic" (most concrete) choice is $T' = T$ which redefines no operators. Let $symbolic(T)$ be the set of types in $U'$ that are subtypes of $T$. The types in $symbolic(T)$ are partially ordered by subset inclusion on the set of operators from $T$ they redefine. # From Strongest Postconditions to DSE {#sec-sp2dse} The previous section showed how symbolic expressions can be computed via a set of instrumented types, where the expressions are computed as a side-effect of the execution of program operations. This section shows how these symbolic expressions can be used to form a *path-condition* (which then can be compiled into a logic formula and passed to an automated theorem prover to find new inputs to drive a program's execution along new paths). We derive a *path-condition* directly from the _strongest postcondition_ (symbolic) semantics of our programming language, refining it to model the basic operations of an interpreter. ## Strongest Postconditions The strongest postcondition transformer $SP$ [@Dijkstra76] is defined over a predicate $P$ representing a set of pre-states and a statement $S$ from our language. The transformer $SP(P,S)$ yields a predicate $Q$ such that for any state $s$ satisfying predicate $P$, the execution of statement $S$ from state $s$, if it does not go wrong or diverge, yields a state $s'$ satisfying predicate $Q$. The strongest postcondition for the statements in our language is defined by the following five rules: ~ MathPre 1. & SP(P, x := E) =^= \exists y . (x = E [ x \rightarrow y ]) \wedge P [ x \rightarrow y ] 2. & SP(P, @skip) =^= P 3. & SP(P,S1;S2) =^= SP(SP(P,S1), S2) 4. & SP(P,@if E @then S_1 @else S_2 @end) =^= & SP(P\wedge E,S_1) \vee SP(P \wedge \neg E,S_2) 5. & SP(P,@while E @do S @end) =^= & SP(P,@if E @then S; @while E @do S @end @else @skip @end) ~ Rule (1) defines the strongest postcondition for the assignment statement. The assignment is modeled logically by the equality $x = E$ where any free occurrence of $x$ in $E$ is replaced by the existentially quantified variable $y$, which represents the value of $x$ in the pre-state. The same substitution ($[x \rightarrow y ]$) is applied to the pre-state predicate $P$. Rules (2)-(5) define the strongest postcondition for the four control-flow statements. The rules for the **skip** statement and sequencing (;) are straightforward. Of particular interest, note that the rule for the **if-then-else** statement splits cases on the expression $E$. It is here that DSE will choose one of the cases for us, as the concrete execution will evaluate $E$ either to be true or false. This gives rise to the path-condition (either $P \wedge E$ or $P \wedge \neg E$). The recursive rule for the **while** loop unfolds as many times as the expression $E$ evaluates true, adding to the path-condition. ## From $SP$ to DSE {#sp-refined} Assume that an execution begins with the assignment of initial values $c_1 \ldots c_k$ to the program $P$'s inputs $V = \{ v_1 : T_1 \ldots v_k : T_k \}$. To seed symbolic execution, some of the types $T_i$ are replaced by symbolic counterparts $T'_i$, in which case $v_i$ is initialized to the value $sc_i = T'_i (c_i,SC(v_i))$ instead of the value $c_i$, where $SC(v_i)$ is the symbolic constant representing the initial value of variable $v_i$. The symbolic constant $SC(v_i)$ can be thought of as representing any value of type $T_i$, which includes the value $c_i$. Let $V_s$ and $V_c$ partition the variables of $V$ into those variables that are treated symbolically ($V_s$) and those that are treated concretely ($V_c$). The initial state of the program is characterized by the formula ~ Equation Init = (\bigwedge_{v_i \in V_s} v_i = sc_i) ~\wedge~ (~\bigwedge_{v_i \in V_c} v_i = c_i) ~ Thus, we see that the initial value of every input variable is characterized by a symbolic constant $sc_i$ or constant $c_i$. We assume that every non-input variable in the program is initialized before being used. The strongest postcondition is formulated to deal with open programs, programs in which some variables are used before being assigned to. This surfaces in Rule (1) for assignment, which uses existential quantification to refer to the value of variable $x$ in the pre-state. By construction, we have that every variable is defined before being used. This means that the precondition $P$ can be reformulated as a pair $$, where $St$ is a store mapping variables to values and $P_c$ is the path-condition, a list of symbolic expressions (predicates) corresponding to the expressions $E$ evaluated in the context of an **if-then-else** statement. Initially, we have that : ~ Equation St = \{ (v_i,sc_i) | v_i \in V_s \} \cup \{ (v_i,c_i) | v_i \in V_c \} ~ representing the initial condition $Init$, and $P_c = []$, the empty list. We use $St'$ to refer to the formula that the store $St$ induces: ~ Equation St ' = \bigwedge_{(v,V) \in St} (v = V) ~ Thus, the pair $$ represents the predicate $P = St' \wedge (\bigwedge_{c \in P_c} c)$. A store $St$ supports two operations: $St[x]$ which denotes the value that $x$ maps to under $St$; $St[x \mapsto V]$, which produces a new store in which $x$ maps to value $V$ and is everywhere else the same as $St$. Now, we can redefine strongest postcondition for assignment to eliminate the use of existential quantification and model the operation of an interpreter, by separating out the notion of the store: ~MathPre 1. & SP(, x := E) =^= \\ ~ where $eval(St,E)$ evaluates expression $E$ under the store $St$ (where every occurrence of a free variable $v$ in $E$ is replaced by the value $St[v]$). This is the standard substitution rule of a standard operational semantics. We also redefine the rule for the **if-then-else** statement so that it chooses which branch to take and appends the appropriate symbolic expression (predicate) to the path-condition $P_c$: ~MathPre 4. & SP(, @if E @then S_1 @else S_2 @end) =^= & @let choice = eval(St,E) @in & @if choice @then SP(,S_1) & @else SP(,S_2) ~ The other strongest postcondition rules remain unchanged. ## Summing it up We have shown how the symbolic predicate transformer $SP$ can be refined into a symbolic interpreter operating over the symbolic types defined in the previous section. In the case when every input variable is symbolic and every operator is redefined, the path-condition is equivalent to the _strongest postcondition_ of the execution path $p$. This guarantees that the path-condition for $p$ is *sound*. In the case where a subset of the input variables are symbolic and/or not all operators are redefined, the path-condition of $p$ is not guaranteed to be sound. We leave it as an exercise to the reader to establish sufficient conditions under which the use of concrete values in place of symbolic expressions is guaranteed to result in sound path-conditions. This section does not address the compilation of a symbolic expression to the (logic) language of an underlying ATP, nor the lifting of a satisfying assignment to a formula back to the level of the source language. This is best done for a particular source language and ATP, as detailed in the next section. # Architecture of PyExZ3 { #sec-impl } In this section we present the high-level architecture of a simple DSE tool for the Python language, written in Python, called [PyExZ3]. Figure [#fig-arch] shows the class diagram (dashed edges are "has-a" relationships; solid edges are "is-a" relationships) of the tool. ~ Figure { #fig-arch caption="Classes in PyExZ3" page-align=here } ![arch] ~ [arch]: arch.png "arch" { width=100% } ## Loading the code under test The `Loader` class takes as input the name of a Python file (e.g., `foo.py`) to import. The loader expects to find a function named `foo` inside the file `foo.py`, which will serve as the starting point for symbolic execution. The `FunctionInvocation` class wraps this starting point. By default, each parameter to `foo` is a `SymbolicInteger` unless there is decorator `@symbolic` specifying the type to use for a particular argument. The loader provides the capability to reload the module `foo.py` so that the function `foo` can be reexecuted within the same process from the same initial state with different inputs (see the class `ExplorationEngine`) via the `FunctionInvocation` class. Finally, the loader looks for specially named functions `expected_result` (`expected_result_set`) in file `foo.py` to use as a test oracle after the path exploration (by `ExplorationEngine`) has completed. These functions are expected to return a list of values to check against the list of return values collected from the executions of the `foo` function. The presence of the function `expected_result` (`expected_result_set`) yields a comparison of the two lists as bags (sets). We use such weaker tests, rather than list equality, because the order in which paths are explored by the `ExplorationEngine` can easily change due to small differences in the input programs. ## Symbolic types Python supports multiple inheritance and, more importantly, allows user-defined classes to inherit from its built-in types (such as `object` and `int`). We use these two features two implement symbolic versions of Python objects and integers, following the instrumented type approach defined in Section [#sec-semantics]. The abstract class `SymbolicType` contains the symbolic expression tree and provides basic functions for constructing and accessing the tree. This class does double duty, as it is used to represent the (typed) symbolic constants associated with the parameters to the function, as well as the expression trees (per Section [#sec-semantics]). Recall that the symbolic constants only appear as leaves of expression trees. This means that the expression tree stored in a `SymbolicType` will have instances of a `SymbolicType` as some of its leaves, namely those leaves representing the symbolic constants. The abstract class provides an `unwrap` method which returns the pair of concrete value and expression tree associated with the `SymbolicType`, as well as a `wrap` method that takes a pair of concrete value and expression tree and creates a `SymbolicType` encapsulating them. The class `SymbolicObject` inherits from both `object` and `SymbolicType` and overrides the basic comparison operations (`__eq__`, `__neq__`, `__lt__`, `__le__`, `__gt__`, and `__ge__`). The class `SymbolicInteger` inherits from both `int` and `SymbolicObject` and overrides a number of `int`'s arithmetic methods (`__add__`, `__sub__`, `__mul__`, `__mod__`, `__floordiv_`) and bitwise methods (`__and__`, `__or__`, `__xor__`, `__lshift__`, `__rshift__`). ## Tracing control-flow As Python interprets a program, it will evaluate expressions, substituting the value of a variable in its place in an expression, applying operators (methods) to parameter values and assigning the return values of methods to variables. Value of type `SymbolicInteger` will simply flow through this interpretation, without necessitating any change to the program or the interpreter. This takes care of the case of the strongest-postcondition rule for assignment, as elaborated in Section [#sp-refined]. The strong-postcondition rule for a conditional test requires a little more work. In Python, any object can be tested in an `if` or `while` condition or as the operand of a Boolean operation (`and`, `or`, `not`) The Python base class `object` provides a method named `__bool__` that the Python runtime calls whenever it needs to perform such a conditional test. This hook provides us what we need to trace the conditional control-flow of a Python execution. We override this method in the class `SymbolicObject` in order to inform the `PathToConstraint` object (defined later) of the symbolic expression for the conditional (as captured by the `SymbolicInteger` subclass). Note that the use of this hook in combination with the tainted types will only trace those conditionals in a Python execution whose values inherit from `SymbolicObject`; by definition, "untainted" conditionals do not depend on symbolic inputs so there is no value in adding them to the path-condition. ## Recording path-conditions A `Predicate` records a conditional (more precisely the symbolic expression found in `SymbolicInteger`) and which way it evaluated in an execution. A `Constraint` has a `Predicate`, a parent `Constraint` and a set of `Constraint` children. `Constraints` form a tree, where each path starting from the root of the tree represents a path-condition. The tree represents all path-conditions that have been explored so far. The class `PathToConstraint` has a reference to the root of the tree of `Constraint`s and is responsible for installing a new `Constraint` in the tree when notified by the overridden `__bool__` method of `SymbolicObject`. `PathToConstraint` also tracks whether or not the current execution is following an existing path in the tree and grows the tree as needed. In fact, it actually tracks whether or not the current execution follows a particular *expected path* in the tree. The expected path is the result of the `ExplorationEngine` picking a constraint $c$ in the tree, and asking the ATP if the path-condition consisting of the prefix of predicates up to but not including $c$ in the tree, followed by the negation of $c$'s predicate is satisfiable. If the ATP returns "satisfiable" (with a new input $i$), then the assumption is that path-condition prefix is sound (that is, the execution of the program on input $i$ will follow the prefix). However, it is possible for the path-condition to be unsound and for the executed path to diverge early from the expected path, due to the fact that not every operation has a symbolic encoding. The tool simply reports the divergence and continues to process the execution as usual (as a diverging path may lead to some other interesting part of the code). ## From symbolic types to Z3 As we have explained DSE, the symbolic expressions are represented at the level of the source language. As detailed later in Section [#sec-int2z3], we must translate from the source language to the input language of an automated theorem prover (ATP), in this case [Z3]. This separation of languages is quite useful, as we may have the need to translate a given symbolic expression to the ATP's language multiple times, to make use of different features of the underlying ATP. Furthermore, this separation of concerns allows us to easily retarget the DSE tool to a different ATP. The base class `Z3Expression` represents a Z3 formula. The two subclasses `Z3Integer` and `Z3BitVector` represent different ways to model arithmetic reasoning about integers in Z3. We will describe the details of these encodings in Section [#sec-int2z3]. The class `Z3Wrapper` is responsible for performing the translation from the source language (Python) to Z3's input language, invoking Z3, and lifting a Z3 answer back to the level of Python. The `findCounterexample` method does all the work, taking as input a list of `Predicate`s (called `assertions`) as well as a single `Predicate` (called the `query`). The `assertions` represent a path-condition prefix derived from the `Constraint` tree that we wish the next execution to follow, while `query` represents the predicate following the prefix in the tree that we will negate. The method constructs the formula ~Equation (\bigwedge_{a \in asserts} a) \wedge \neg query ~ and asks Z3 if it is satisfiable. The method performs a standard syntactic "cone of influence" (CIF) reduction on the `asserts` with respect to the `query` to shrink the size of the formula. For example, if `asserts` is the set of predicates $\{ (x0) \}$ and the query is $(x=0)$, then the CIF yields the set $\{ (x0)$, as the variable $y$ is not in the set of variables (transitively) related to variable $x$. If the formula is satisfiable a model is requested from Z3 and lifted back to Python's type universe. Note that because of the CIF reduction, the model may not mention certain input variables, in which case we simply keep their values from the execution from which the `asserts` and `query` were derived. ## Putting it all together The class `ExplorationEngine` ties everything together. It kicks off an execution of the Python code under test using `FunctionInvocation`. As the Python code executes, building symbolic expressions via `SymbolicType` and its subclasses, callbacks to `PathToConstraint` create a path-condition, represented by `Constraint` and `Predicate`. Newly discovered `Constraints` are added to the end of a deque maintained by `ExplorationEngine`. Given the first seed execution, `ExplorationEngine` starts the work of exploring paths in a breadth-first fashion. It removes a `Constraint` $c$ from the front of its deque and, if $c$ has not been already "processed", uses `Z3Wrapper` to find a new input (as discussed in the previous section) where $c$ is the query (to be negated) and the path to $c$ in the `Constraint` tree forms the assertions. A `Constraint` $c$ in the tree is considered "processed" if an execution has covered $c'$, a sibling of $c$ in the tree that represents the negation of the predicate associated with $c$, or if constraint $c$ has been removed from the deque. # From Python Integers to Z3 Arithmetic { #sec-int2z3 } In languages such as C and Java, integers are finite-precision, generally limited to the size of a machine word (32 or 64 bits, for example). For such languages, satisfiability of finite-precision integer arithmetic is decidable and can be reduced to Z3's theory of bit-vectors, where each arithmetic operation is encoded by a circuit. This translation permits reasoning about non-linear arithmetic problems, such as $\exists x,y,z : x*z + y \leq (z/y)+5$. Python (3.0) integers, however, are not finite-precision. They are only limited by the size of machine memory. This means, for example, that Python integers don't overflow or underflow. It also means that we can't hope to decide algorithmically whether or not a given equation over integer variables has a solution in general. Hilbert's famous 10th problem and its solution by Matiyasevich tells us that it is undecidable whether or not a polynomial equation of the form $p(x_1, \ldots, x_n) = 0$ with integer coefficients has an solution in the integers. This means that we will resort to heuristic approaches in our use of the [Z3] ATP. The special case of linear integer arithmetic (LIA) is decidable and supported by Z3. In order to deal with non-linear operations, we use uninterpreted functions (UF). Thus, if Z3 returns "unsatisfiable" we know that there is no solution, but if the Z3 "satisfiable", we must treat the answer as a "don't know". The class `Z3Integer` is used to translate a symbolic expression into the theory LIA+UF and check for unsatisfiability. We leave it as an implementation exercise to check if a symbolic expression can be converted to LIA (without the use of UF) in order to make use of "satisfiable" answers from the LIA solver. If the translation to `Z3Integer` does not return "unsatisfiable", we use Z3's bit-vector decision procedure (via the class `Z3BitVector`) to heuristically try to find satisfiable answers, even in the presence of non-linear arithmetic. We start with bit-vectors of size $N=32$ and *bound* the values of the symbolic constants to fit within 8 bits in order to find satisfiable solutions with small values. Also, because Python integers do not overflow/underflow, the bound helps us reserve space in the bit-vector to allow the results of operations to exceed the bound while not overflowing the bit-vector. As long as Z3 returns "unsatisfiable" we increase the bound. If the bound reaches $N$, we increase $N$ by 8 bits, leaving the bound where it is and continue. If Z3 returns "satisfiable", it may be the case that Z3 found a solution that involved overflow in the bit-vector world of arithmetic (modulo $2^N-1$). Therefore, the solution is validated back in the Python world by evaluating the formula under that solution using Python semantics. If the formula does not evaluate to the same value in both worlds, then we increase $N$ by 8 bits (to create a gap between the bound and $N$) and continue to search for a solution. The process terminates when we find a valid satisfying solution or $N=64$ and the bound reaches 64 (in which case, we return "don't know"). # Extensions {#sec-extensions} We have presented the basics of dynamic symbolic execution (for Python). A more thorough treatment would deal with other data types besides integers, such as Python dictionaries, strings and lists, each of which presents their own challenges for symbolic reasoning. There are many other interesting challenges in DSE, such as dealing with user-defined classes (rather than built-in types as done here) and multi-threaded execution. # Acknowledgements Many thanks to the students of the 2014 Marktoberdorf Summer School on Dependable Software Systems Engineering for their questions and feedback about the first author's lectures on dynamic symbolic execution. The following students of the summer school helpfully provided tests for the [PyExZ3] tool: Daniel Darvas, Damien Rusinek, Christian Dehnert and Thomas Pani. Thanks also to Peter Chapman for his contributions. # References {-} [BIB] ================================================ FILE: marktoberdorf_paper/DSE/IOS-Book-Article.cls ================================================ %% This is file `IOSarticle.cls' %% %% Generic LaTeX 2e class file for the IOS Press publications %% %% Macros written by Vytas Statulevicius, VTeX, Lithuania %% for IOS Press, The Netherlands %% Please submit bugs or your comments to vytas@vtex.lt %% %% You are free to use this class file as you see fit, provided %% that you do not make changes to the file. %% If you DO make changes, you are required to rename this file. %% %% It may be distributed under the terms of the LaTeX Project Public %% License, as described in lppl.txt in the base LaTeX distribution. %% Either version 1.0 or, at your option, any later version. %% %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %% %% %% Bug fixes and changes: %% 2004.05.19 - small change o layout %% 2004.09.14 - \parindent changed %% 2006.03.27 - centering on A4, no running heads, \snm makes uppercase %% 2006.04.20 - changed: \thebibliography size, indent, \parindent \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesClass{IOS-Book-Article} [2006/04/20 v1.0, IOS Press] \newif\if@restonecol \@restonecolfalse \newif\if@openright \newif\if@mainmatter \@mainmattertrue \DeclareOption{draft}{\setlength\overfullrule{5pt}} \DeclareOption{final}{\setlength\overfullrule{0pt}} \DeclareOption{openright}{\@openrighttrue} \DeclareOption{openany}{\@openrightfalse} \DeclareOption{onecolumn}{\@twocolumnfalse\@restonecoltrue} \DeclareOption{twocolumn}{\@twocolumntrue} \DeclareOption{leqno}{\input{leqno.clo}} \DeclareOption{fleqn}{\input{fleqn.clo}}% % % Numbering switches: \newif\if@seceqn \@seceqnfalse \DeclareOption{seceqn}{\@seceqntrue} \newif\if@secfloat \@secfloatfalse \DeclareOption{secfloat}{\@secfloattrue} \newif\if@secthm \DeclareOption{secthm}{\@secthmtrue} % % % Selection of font size and page dimensions % If 12pt option is used, page will be reduced by 80% at printing time \newif\if@ten@point \@ten@pointfalse \DeclareOption{10pt}{\@ten@pointtrue} \DeclareOption{12pt}{\@ten@pointfalse} % Information about the publication \def\booktitle#1{\gdef\book@title{#1}} \def\bookeditors#1{\gdef\book@editors{#1}} \def\publisher#1{\gdef\@publisher{#1}} \booktitle{Book Title} \bookeditors{Book Editors} \publisher{IOS Press} \ExecuteOptions{10pt,onecolumn,twoside,final,openright,fleqn} \ProcessOptions % %************************* FONTS %\def\@xivpt{14} %\def\@xviipt{17} %\def\@xviiipt{18} %\def\@xxpt{20} %\def\@xxivpt{24} % Fonts: \typeout{Ten point} % \renewcommand\normalsize{% \@setfontsize\normalsize\@xpt{12pt plus .5\p@ minus .1\p@}% \abovedisplayskip 12\p@ \@plus3pt \@minus3pt% \abovedisplayshortskip\abovedisplayskip% \belowdisplayshortskip\abovedisplayskip% \belowdisplayskip \abovedisplayskip% \let\@listi\@listI} \newcommand\small{% \@setfontsize\small\@ixpt\@xipt% \abovedisplayskip 5.5\p@ \@plus3pt% \abovedisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \belowdisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \def\@listi{\leftmargin\leftmargini \topsep 5\p@ \@plus2\p@ \@minus2\p@ \parsep \z@ \itemsep \parsep}% \belowdisplayskip \abovedisplayskip% } \newcommand\footnotesize{% \@setfontsize\footnotesize\@viiipt\@xpt% \abovedisplayskip 5.5\p@ \@plus3pt% \abovedisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \belowdisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \def\@listi{\leftmargin\leftmargini \topsep 4\p@ \@plus2\p@ \@minus2\p@ \parsep \z@ \itemsep \parsep}% \belowdisplayskip \abovedisplayskip% } \newcommand\scriptsize{\@setfontsize\scriptsize\@viiipt{9.5}} \newcommand\tiny{\@setfontsize\tiny\@vipt\@viipt} \newcommand\large{\@setfontsize\large\@xiipt{14}} \newcommand\Large{\@setfontsize\Large\@xivpt{18}} \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}} \newcommand\huge{\@setfontsize\huge\@xxpt{25}} \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} \normalsize % Customization of fonts \renewcommand\sldefault{it} \renewcommand\bfdefault{b} \let\slshape\itshape % % ********************* DIMENSIONS: % TEXT DIMENSIONS \setlength\parindent{18\p@} \@settopoint\parindent \setlength\textwidth{124mm} \@settopoint\textwidth \setlength\textheight{200mm} \@settopoint\textheight \setlength\columnsep{10mm} \@settopoint\columnsep \setlength\columnwidth{95mm} \@settopoint\columnwidth \setlength\columnseprule{0\p@} \hoffset -0.5cm \voffset -1cm % HEADS: \setlength\headheight{12\p@} \setlength\headsep {15\p@} \setlength\topskip {10\p@} \setlength\footskip {25\p@} \setlength\maxdepth {.5\topskip} % SIDE MARGINS \setlength\oddsidemargin {0mm} \setlength\evensidemargin {0mm} \setlength\topmargin {10mm} \@settopoint\topmargin % TEXT PARAMETERS \setlength\lineskip{1\p@} \setlength\normallineskip{1\p@} \renewcommand\baselinestretch{} \setlength\parskip{0\p@} % Center on A4: \def\paper@width {210mm} \def\paper@height{297mm} \hoffset=-1in \voffset=-1in \@tempdima=\paper@width \advance\@tempdima by-\textwidth \divide\@tempdima by2 \setlength\evensidemargin {\@tempdima}% \setlength\oddsidemargin {\@tempdima}% \@tempdima=\paper@height \advance\@tempdima by-\textheight \advance\@tempdima by-\headsep \advance\@tempdima by-\headheight \divide\@tempdima by2 \setlength\topmargin {\@tempdima}% % BREAKS \setlength\smallskipamount{6\p@ \@plus 1\p@ \@minus 1\p@} \setlength\medskipamount{12\p@ \@plus 3\p@ \@minus 3\p@} \setlength\bigskipamount{24pt \@plus 3\p@ \@minus 3\p@} % PAGE-BREAKING PENALTIES \clubpenalty=4000 \widowpenalty=4000 \displaywidowpenalty=50 \predisplaypenalty=0 % Breaking before a math display. % \postdisplaypenalty % Breaking after a math display. % \interlinepenalty % Breaking at a line within a paragraph. % \brokenpenalty % Breaking after a hyphenated line. \pretolerance=100 % Badness tolerance for the first pass (before hyphenation) \tolerance=800 % Badness tolerance after hyphenation \hbadness=800 % Badness above which bad hboxes will be shown \emergencystretch=3\p@ \hfuzz=1\p@ % do not be to critical about boxes % \doublehyphendemerits=0 \adjdemerits=0 \brokenpenalty=0 \interlinepenalty=0 % \if@twocolumn \setlength\marginparsep {10\p@} \else \setlength\marginparsep{7\p@} \fi \setlength\marginparpush{5\p@} % FOOTNOTES \setlength\footnotesep{6.65\p@} \setlength{\skip\footins}{12\p@ \@plus 6\p@} % FLOATS \setlength\floatsep {15\p@ \@plus 10\p@ \@minus 4\p@} \setlength\textfloatsep{12\p@ \@plus 6\p@ \@minus 4\p@} \setlength\intextsep {12\p@ \@plus 6\p@ \@minus 4\p@} \setlength\dblfloatsep {15\p@ \@plus 10\p@ \@minus 4\p@} \setlength\dbltextfloatsep{12\p@ \@plus 12\p@ \@minus 4\p@} % For floats on a separate float page or column: \setlength\@fptop{0\p@ \@plus 1fil} \setlength\@fpsep{8\p@ \@plus 1000fil} \setlength\@fpbot{0\p@ \@plus 1fil} \setlength\@dblfptop{0\p@ \@plus 1fil} \setlength\@dblfpsep{8\p@ \@plus 1000fil} \setlength\@dblfpbot{0\p@ \@plus 1fil} % \setcounter{topnumber}{5} \renewcommand\topfraction{.90} \setcounter{bottomnumber}{5} \renewcommand\bottomfraction{.90} \setcounter{totalnumber}{10} \renewcommand\textfraction{.10} \renewcommand\floatpagefraction{.9} \setcounter{dbltopnumber}{5} \renewcommand\dbltopfraction{.99} \renewcommand\dblfloatpagefraction{.8} % % PENALTIES \@lowpenalty 51 \@medpenalty 151 \@highpenalty 301 \@beginparpenalty -\@lowpenalty \@endparpenalty -\@lowpenalty \@itempenalty -\@lowpenalty % LISTS \setlength\partopsep{0\p@} \def\@listI{\leftmargin\leftmargini \parsep 0\p@ \@plus2\p@ \@minus\p@ \topsep 9\p@ \@plus2\p@ \@minus2\p@ \partopsep\p@ \itemsep 1\p@ \@plus.5\p@ \@minus1\p@} \let\@listi\@listI \@listi \def\@listii {\leftmargin\leftmarginii \labelwidth\leftmarginii \advance\labelwidth-\labelsep \topsep 4\p@ \@plus2\p@ \@minus\p@ \parsep 0\p@ \@plus1\p@ \@minus\p@ \itemsep \parsep} \def\@listiii{\leftmargin\leftmarginiii \labelwidth\leftmarginiii \advance\labelwidth-\labelsep \topsep 2\p@ \@plus\p@\@minus\p@ \parsep \z@ \partopsep \p@ \@plus\z@ \@minus\p@ \itemsep \topsep} \def\@listiv {\leftmargin\leftmarginiv \labelwidth\leftmarginiv \advance\labelwidth-\labelsep} \def\@listv {\leftmargin\leftmarginv \labelwidth\leftmarginv \advance\labelwidth-\labelsep} \def\@listvi {\leftmargin\leftmarginvi \labelwidth\leftmarginvi \advance\labelwidth-\labelsep} % \DeclareMathSizes{\@xivpt}{\@xivpt}{\@xpt}{\@viiipt} \DeclareMathSizes{12}{12}{\@viiipt}{\@viipt} % % ******************** HEADINGS % % normal heading \def\ps@headings{% \let\@oddfoot\@empty\let\@evenfoot\@empty \def\@evenhead{\footnotesize\rlap{\thepage}\hfill\textit{\leftmark}\hfill}% \def\@oddhead{\footnotesize\hfill\textit{\rightmark}\hfill\llap{\thepage}}% }% % empty RH \def\ps@empty{\let\@mkboth\@gobbletwo \def\@oddhead{\hfill}\def\@oddfoot{} \let\@evenhead\@oddhead\let\@evenfoot\@oddfoot} % % RH with pagenumber at bottom \def\ps@plain{\let\@mkboth\@gobbletwo \def\@oddhead{\hfill}\def\@oddfoot{} \let\@evenhead\@oddhead \def\@oddfoot{\hfill\footnotesize\thepage\hfill} \let\@evenfoot\@oddfoot } % First page RH \def\ps@copyright{\let\@mkboth\@gobbletwo \def\@evenhead{\parbox[t]{.75\textwidth}{\footnotesize\raggedright\itshape\titleheadline}\hfill\footnotesize\thepage}% \def\@oddhead {\parbox[t]{.75\textwidth}{\footnotesize\raggedright\itshape\titleheadline}\hfill\footnotesize\thepage}% \let\@oddfoot\relax% \let\@evenfoot\@oddfoot% } % % HEADLINE: Book Title % Book Editors % IOS Press, 0000 % \def\titleheadline{% \book@title\\ \book@editors\\ \@publisher, \the\@pubyear} % \def\@copyright{\@issn/\the@copyear/\$\@price\ \copyright@sign\ \the\@pubyear\@copyrightowner}% % % ************************ FOOTNOTE % \newcommand\@makefntext[1]{% \parindent1em\@makefnmark #1} \def\@makefnmark{\@textsuperscript{\normalfont\@thefnmark}}% % % ************************ Counters \setcounter{secnumdepth}{3} \newcounter {section} \newcounter {subsection}[section] \newcounter {subsubsection}[subsection] \newcounter {paragraph}[subsubsection] \newcounter {subparagraph}[paragraph] \renewcommand \thesection {\@arabic\c@section} \renewcommand\thesubsection {\thesection.\@arabic\c@subsection} \renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection} \renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph} \renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph} % % ******************** Sectioning commands \def\no@harm{\let\thanks=\@gobble \let\\=\@empty} %**************** Section commands \def\nohyphen{\pretolerance=10000 \tolerance=10000 \hyphenpenalty=10000 \exhyphenpenalty=10000} \newcommand\section{\@startsection {section}{1}{\z@}% {-\bigskipamount}% {\medskipamount}% {\normalsize\bfseries\nohyphen\raggedright}} \newcommand\subsection{\@startsection {subsection}{2}{\z@}% {-\medskipamount}% {\medskipamount}% {\normalsize\itshape\nohyphen\raggedright}} \newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-\medskipamount}% {\smallskipamount}% {\normalsize\itshape\nohyphen\raggedright}} \newcommand\paragraph{\@startsection{paragraph}{4}{\z@}% {\smallskipamount}% {-1em}% {\normalsize\itshape}} \newcommand\subparagraph{\@startsection{subparagraph}{5}{\z@}% {0.1pt}% {-1em}% {\normalsize\itshape}} % Format for the counter: \def\@seccntformat#1{\csname the#1\endcsname.\enspace} % \def\appendix{\par \setcounter{section}{0}% \setcounter{subsection}{0}% \gdef\thesection{\Alph{section}}} % \def\acknowledgements{\section*{\acknowledgementsname}% \typeout{\acknowledgementsname}} % \def\notes{\section*{Notes}\footnotesize} \def\endnotes{\par \vskip 6pt plus12pt minus2pt\relax} %****************** LISTS \if@twocolumn \setlength\leftmargini {2em} \else \setlength\leftmargini {2.5em} \fi \leftmargin \leftmargini \setlength\leftmarginii {2.2em} \setlength\leftmarginiii {1.87em} \setlength\leftmarginiv {1.7em} \if@twocolumn \setlength\leftmarginv {.5em} \setlength\leftmarginvi {.5em} \else \setlength\leftmarginv {1em} \setlength\leftmarginvi {1em} \fi \setlength \labelsep {.4em} \setlength \labelwidth{\leftmargini} \addtolength\labelwidth{-\labelsep} % \renewcommand\theenumi{\@arabic\c@enumi} \renewcommand\theenumii{\@alph\c@enumii} \renewcommand\theenumiii{\@roman\c@enumiii} \renewcommand\theenumiv{\@Alph\c@enumiv} \newcommand\labelenumi{\theenumi.} \newcommand\labelenumii{(\theenumii)} \newcommand\labelenumiii{\theenumiii.} \newcommand\labelenumiv{\theenumiv.} \renewcommand\p@enumii{\theenumi} \renewcommand\p@enumiii{\theenumi(\theenumii)} \renewcommand\p@enumiv{\p@enumiii\theenumiii} % \def\setenumlabel#1{\gdef\max@enumlabel{#1}} \setenumlabel{1.} % \def\enumerate{\@ifnextchar[{\enumerate@}{\enumerate@[\max@enumlabel]}} % \def\enumerate@[#1]{\ifnum \@enumdepth >4 \@toodeep\else \advance\@enumdepth \@ne \edef\@enumctr{enum\romannumeral\the\@enumdepth}% \list {\csname label\@enumctr\endcsname}% {\usecounter{\@enumctr}\def\makelabel##1{{\hfill\rm ##1}} \settowidth{\labelwidth}{#1} \advance\labelwidth by\parindent \labelsep=0.5em \leftmargin\z@ \rightmargin\z@ \itemindent=\labelwidth \advance\itemindent\labelsep \leftmargin=\the\itemindent\itemindent=\z@ \partopsep\z@ \topsep\smallskipamount \parsep\z@ \itemsep\z@ %\@rightskip\z@ plus 1fil \listparindent\z@}\fi\setenumlabel{1.}} %%%%%%%%%%%%%%%%%%%%%% ITEMIZE \newcommand\labelitemi{\normalfont\bfseries \textbullet} \newcommand\labelitemii{\textasteriskcentered} \newcommand\labelitemiii{\textasteriskcentered} \newcommand\labelitemiv{\textperiodcentered} \let\@itemize@indent\parindent % \def\itemize{\@ifnextchar[{\itemize@}{\itemize@[]}} \def\itemize@[#1]{\ifnum \@itemdepth >4 \@toodeep\else \advance\@itemdepth \@ne \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% \if.#1. \else\def\@@tempa{#1}\edef\@itemitem{@@tempa}\fi\list {\csname\@itemitem\endcsname}{\settowidth{\labelwidth} {\csname\@itemitem\endcsname} \def\makelabel##1{##1}\labelsep=0.5em%ST \itemindent=\labelwidth \advance\itemindent\labelsep \advance\itemindent\@itemize@indent \leftmargin\the\itemindent \itemindent=\z@ \partopsep\z@ \topsep\smallskipamount \parsep\z@ %\@rightskip\z@ plus 1fil \itemsep\z@ \listparindent\z@} \fi} % \newenvironment{description} {\list{}{\labelwidth\z@ \itemindent-\leftmargin \let\makelabel\descriptionlabel}} {\endlist} \newcommand*\descriptionlabel[1]{\hspace\labelsep \normalfont\bfseries #1} \newenvironment{verse} {\let\\\@centercr \list{}{\itemsep \z@ \itemindent -1.5em% \listparindent\itemindent \rightmargin \leftmargin \advance\leftmargin 1.5em}% \item\relax} {\endlist} \newenvironment{quotation} {\list{}{\small\listparindent2mm% \itemindent\z@ % \rightmargin\z@ \leftmargin\parindent% \partopsep\z@ \topsep\smallskipamount \parsep\z@% }% \item[\Q@strut]\relax} {\endlist} \def\Q@strut{\leavevmode\hbox{\vrule height9pt depth1pt width0pt}} \newenvironment{quote} {\list{}{\listparindent\z@% \itemindent \listparindent% \rightmargin\z@ \leftmargin 1.5em% \partopsep\z@ \topsep6pt \parsep\z@% }% \item[\Q@strut]\relax} {\endlist} % %************************** TABULAR \let\savehline\hline \def\thline{\noalign{\vskip3pt}\savehline\noalign{\vskip3pt}}% \def\fhline{\noalign{\vskip1pt}\savehline\noalign{\vskip7pt}}% \def\bhline{\noalign{\vskip3pt}\noalign{\global\arrayrulewidth=1\p@}\savehline\noalign{\global\arrayrulewidth=.5\p@}\noalign{\vskip3pt}}% \def\lhline{\noalign{\vskip3pt}\noalign{\global\arrayrulewidth=.3\p@}\savehline\noalign{\global\arrayrulewidth=.5\p@}\noalign{\vskip3pt}} % %************************** MATH SETTINGS \setlength\mathindent{2em} \setlength\arraycolsep{1.2\p@} \setlength\tabcolsep{6\p@} \setlength\arrayrulewidth{.4\p@} \setlength\doublerulesep{2\p@} \setlength\tabbingsep{\labelsep} \setlength\jot{6\p@} \skip\@mpfootins = \skip\footins \setlength\fboxsep{3\p@} \setlength\fboxrule{.4\p@} \if@seceqn \@addtoreset {equation}{section} \renewcommand\theequation{\thesection.\@arabic\c@equation} \else \renewcommand\theequation{\@arabic\c@equation} \fi %******* TABLES, FIGURES, ALGORITHM \newcounter{figure} \if@secfloat \@addtoreset{figure}{section} \renewcommand \thefigure {\thesection.\@arabic\c@figure} \else \renewcommand \thefigure {\@arabic\c@figure} \fi \def\fps@figure{tbp} \def\ftype@figure{1} \def\ext@figure{lof} \def\fnum@figure{\figurename~\thefigure.} \newenvironment{figure} {\let\@makecaption\@makefigurecaption\let\@floatboxreset\@figureboxreset\@float{figure}} {\end@float} \newenvironment{figure*} {\let\@makecaption\@makefigurecaption\let\@floatboxreset\@figureboxreset\@dblfloat{figure}} {\end@dblfloat} \def\@figureboxreset{% \reset@font% \centering% \@setnobreak% \@setminipage% } \long\def\@makefigurecaption#1#2{\footnotesize% \vskip\abovecaptionskip \setbox\@tempboxa\hbox{\textbf{#1}\enspace #2}% \ifdim \wd\@tempboxa >\hsize \unhbox\@tempboxa\par \else \hbox to\hsize{\hfil\box\@tempboxa\hfil}% \fi} % % TABLE \newcounter{table} \if@secfloat \@addtoreset{table}{section} \renewcommand \thetable{\thesection.\@arabic\c@table} \else \renewcommand \thetable{\@arabic\c@table} \fi \def\fps@table{tbp} \def\ftype@table{2} \def\ext@table{lot} \def\fnum@table{\tablename~\thetable.} % \newenvironment{table} {\let\@makecaption\@maketablecaption% \let\@floatboxreset\@tableboxreset\@float{table}} {\end@float} \newenvironment{table*} {\let\@makecaption\@maketablecaption% \let\@floatboxreset\@tableboxreset\@dblfloat{table}} {\end@dblfloat} % \def\@tableboxreset{% \reset@font% \centering\footnotesize% \def\arraystretch{1.2} \@setnobreak% \@setminipage% } \newlength\abovecaptionskip \newlength\belowcaptionskip \setlength\abovecaptionskip{8\p@} \setlength\belowcaptionskip{3\p@} % \newdimen\tablewidth \tablewidth\textwidth \newdimen\saved@tablewidth \saved@tablewidth\textwidth % \long\def\@maketablecaption#1#2{% \begingroup% \footnotesize% \global\setbox\@tempboxa\hbox{\textbf{#1}\enspace #2}% \endgroup% \centering% \ifdim \wd\@tempboxa>\tablewidth % \parbox[t]{\tablewidth}{\footnotesize\textbf{#1}\enspace #2\vphantom{Ay}\par}% \else \hbox to\hsize{\hfill\box\@tempboxa\vphantom{Ay}\hfill}% \fi% \global\saved@tablewidth\tablewidth% \global\tablewidth\hsize\vskip\belowcaptionskip} % % %%****************** Algorithm \newcounter{algorithm} \if@secfloat \@addtoreset{algorithm}{section} \renewcommand \thealgorithm{\thesection.\@arabic\c@algorithm} \else \renewcommand \thealgorithm{\@arabic\c@algorithm} \fi \def\fps@algorithm{tbp} \def\ftype@algorithm{4} \def\ext@algorithm{loa} \def\fnum@algorithm{\algorithmname~\thealgorithm.} % \newenvironment{algorithm} {\let\@makecaption\@makealgorithmcaption% \let\@floatboxreset\@algorithmboxreset\@float{algorithm}} {\end@float} \newenvironment{algorithm*} {\let\@makecaption\@makealgorithmcaption% \let\@floatboxreset\@algorithmboxreset\@dblfloat{algorithm}} {\end@dblfloat} \def\@algorithmboxreset{% \reset@font% \centering \@setnobreak% \@setminipage% } \long\def\@makealgorithmcaption#1#2{\vskip 2ex \small \hbox to \hsize{\parbox[t]{\hsize}{{\bf #1} #2}}} % %%%% Program Code: \def\programcode{% \let\@makealgorithmcaption\@makefigurecaption \def\algorithmname{Program Code}} %********************* COMPATIBILITY WITH OLD LATEX: \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} \DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} \DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} \DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} \DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} \let\sl\it \DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} \DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} \DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} % % *********** MATH % \if@secthm \@addtoreset{thm}{section} \def\thethm{\thesection.\arabic{thm}} \else \def\thethm{\arabic{thm}} \fi % %***************************** BIBLIOGRAPHY \newenvironment{thebibliography}[1] {\section*{\refname}\footnotesize\rmfamily\upshape% \list{\@biblabel{\@arabic\c@enumiv}}% {\settowidth\labelwidth{\@biblabel{#1}}% \leftmargin\labelwidth \setlength\labelsep{8\p@} \advance\leftmargin\labelsep \usecounter{enumiv}% \let\p@enumiv\@empty \renewcommand\theenumiv{\@arabic\c@enumiv}}% \sloppy \clubpenalty4000 \@clubpenalty \clubpenalty \widowpenalty4000% \sfcode`\.\@m} {\def\@noitemerr {\@latex@warning{Empty `thebibliography' environment}}% \endlist} % \newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} % \def\@citex[#1]#2{% \let\@citea\@empty \@cite{\@for\@citeb:=#2\do {\@citea\def\@citea{,\penalty\@m\hskip.1pt}% \edef\@citeb{\expandafter\@firstofone\@citeb}% \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% \G@refundefinedtrue \@latex@warning {Citation `\@citeb' on page \thepage \space undefined}}% {\hbox{\csname b@\@citeb\endcsname}}}}{#1}} %****************************** FRONTMATTER * % \newtoks\t@glob@notes \newtoks\t@loc@notes \newcount\note@cnt \newcounter{author} \newcount\n@author \def\n@author@{} \newcounter{address} % \newcount\sv@hyphenpenalty % \newcount\prev@elem \prev@elem=0 \newcount\cur@elem \cur@elem=0 \chardef\e@pretitle=1 \chardef\e@title=1 \chardef\e@subtitle=1 \chardef\e@author=2 \chardef\e@address=3 % \newif\if@newelem \newif\if@firstauthor \newif\if@preface \newif\if@hasabstract \newif\if@haskeywords % \newbox\fm@box \newdimen\fm@size \newbox\t@abstract \newbox\t@keywords % \def\add@tok#1#2{\global#1\expandafter{\the#1#2}} \def\add@xtok#1#2{\begingroup \no@harm \xdef\@act{\global\noexpand#1{\the#1#2}}\@act \endgroup} % \def\tailthanksref[#1]#2{\noexpand\pthanksref{#1}} \def\pthanksref#1{\global\advance\note@cnt\@ne\ifnum\note@cnt>\@ne \global\t@loc@notes\expandafter{\the\t@loc@notes\note@sep}\fi \global\t@loc@notes\expandafter{\the\t@loc@notes#1}} % \def\beg@elem{\global\t@loc@notes={}\global\note@cnt\z@} \def\@xnamedef#1{\expandafter\xdef\csname #1\endcsname} \def\no@harm{% \let\\=\relax \let\rm\relax \let\ss=\relax \let\ae=\relax \let\oe=\relax \let\AE=\relax \let\OE=\relax \let\o=\relax \let\O=\relax \let\i=\relax \let\j=\relax \let\aa=\relax \let\AA=\relax \let\l=\relax \let\L=\relax \let\d=\relax \let\b=\relax \let\c=\relax \let\bar=\relax \def\protect{\noexpand\protect\noexpand}} % \def\proc@elem#1#2{\begingroup \no@harm \def\thanks##1##{\@gobble}% \def\thanksref##1##{\@gobble}% \@xnamedef{@#1}{#2}% \endgroup \prev@elem=\cur@elem \cur@elem=\csname e@#1\endcsname \expandafter\elem@nothanksref#2\thanksref\relax% \expandafter\elem@nothanks#2\thanks\relax} % \def\elem@nothanksref#1\thanksref{\futurelet\@peektok\elem@thanksref} \def\elem@thanksref{\ifx\@peektok\relax \else \expandafter\elem@morethanksref \fi} \def\elem@morethanksref[#1]#2{\add@thanks{#1}\elem@nothanksref} % \def\elem@nothanks#1\thanks{\futurelet\@peektok\elem@thanks} \def\elem@thanks{\ifx\@peektok\relax \else \ifx\@peektok[ \expandafter\expandafter\expandafter\elem@morethankse \else \expandafter\expandafter\expandafter\elem@morethanks \fi\fi} % \def\elem@morethankse[#1]#2{\thanks@optarg[#1]{#2}\add@thanks{#1}\elem@nothanks} \def\elem@morethanks#1{\thanks@optarg[]{#1}\add@thanks{}\elem@nothanks} % \def\add@thanks#1{% \global\advance\note@cnt\@ne \ifnum\note@cnt>\@ne \add@xtok\t@loc@notes{\note@sep}\fi \ifx.#1.\add@xtok\t@loc@notes{\thefootnote}\else \add@xtok\t@loc@notes{#1}\fi% } \def\add@addressref#1{% \global\advance\note@cnt\@ne \ifnum\note@cnt>\@ne \add@xtok\t@loc@notes{\note@sep}\fi \add@tok\t@loc@notes{\ref{#1}}% } \def\note@sep{,} % \def\thanks@optarg[#1]#2{% \ifx.#1.\add@tok\t@glob@notes{\footnotetext}% \else\add@tok\t@glob@notes{\freefootnotetext}\fi% \refstepcounter{footnote}% \ifx.#1.\add@xtok\t@glob@notes{[\the\c@footnote]}% \else\add@xtok\t@glob@notes{[#1]}\fi% \add@tok\t@glob@notes{{#2}}% \ignorespaces}% % % FRONTMATTER % \def\artty#1{} % \newdimen\a@title@skip \a@title@skip=12\p@ \newskip\b@section@skip \b@section@skip=12\p@ plus6\p@ minus6\p@% \newskip\b@pretitle@skip \b@pretitle@skip=6\p@ % \def\frontmatter{% \let\@corresp@note\relax \global\t@glob@notes={}\global\c@author\z@ \global\c@address\z@ \global\n@author=0\n@author@\relax \global\advance\n@author\m@ne \global\@firstauthortrue \global\@hasabstractfalse \global\@prefacefalse \parindent\z@ \open@fm \ignorespaces} % \def\preface{\@prefacetrue} % % ENDFRONTMATTER % \def\endfrontmatter{% \global\n@author=\c@author \@writecount \global\@topnum\z@ \ifx\@firstpage\@lastpage \gdef\@pagerange{\@firstpage} \else \gdef\@pagerange{\@firstpage--\@lastpage} \fi % \thispagestyle{copyright}% \if@twocolumn\else\output@glob@notes\fi \if@preface \@hasabstractfalse \fi \if@hasabstract \normal@text \vskip 18\p@ \centering \leavevmode\box\t@abstract\par \fi \if@haskeywords \normal@text \if@hasabstract \vskip6pt\else\vskip18pt\fi \centering \leavevmode\box\t@keywords\par \fi \close@fm \if@twocolumn\output@glob@notes\fi \markboth{\@runauthor\@runtitle}{\@runauthor\@runtitle}% \global\@prefacefalse \global\leftskip\z@ \global\@rightskip\z@ \global\rightskip\@rightskip % \global\c@footnote=0 \let\title\relax \let\author\relax \let\address\relax \let\frontmatter\relax \let\endfrontmatter\relax \let\@maketitle\relax \let\@@maketitle\relax \normal@text} % % Dvieju koloneliu zurnale per visa lapo ploti eina % tik pretitle, title ir subtitle. Tam ivedame komanda % \maketitle, kuri uzdaro box'a \def\two@c@maketitle{% \global\let\close@fm\relax% \vskip\b@section@skip% \par \egroup \emergencystretch=1pc \twocolumn[\unvbox\fm@box]} % \if@restonecol \let\maketitle\relax \else \let\maketitle\two@c@maketitle \fi % % \newdimen\t@xtheight \def\init@settings{ \splittopskip=\topskip \splitmaxdepth=\maxdepth \t@xtheight\textheight \advance\t@xtheight-\splittopskip} % \def\open@fm{ \global\setbox\fm@box=\vbox\bgroup \hsize=\textwidth \centering \sv@hyphenpenalty\hyphenpenalty \hyphenpenalty\@M} % \def\close@fm{% \vskip\b@section@skip% \par \egroup \if@twocolumn\else% \fm@size=\dp\fm@box \advance\fm@size by \ht\fm@box \@whiledim\fm@size>\t@xtheight \do{% \global\setbox\@tempboxa=\vsplit\fm@box to \t@xtheight \unvbox\@tempboxa \newpage \fm@size=\dp\fm@box \advance\fm@size by \ht\fm@box} \fi% \if@twocolumn \emergencystretch=1pc \twocolumn[\unvbox\fm@box] \else \unvbox\fm@box \fi} % \def\output@glob@notes{\bgroup \the\t@glob@notes \egroup} % \def\justify@off{\let\\=\@normalcr \leftskip\z@ \@rightskip\@flushglue \rightskip\@rightskip} \def\justify@on{\let\\=\@normalcr \parfillskip\@flushglue% \leftskip\z@ \@rightskip\z@ \rightskip\@rightskip} % \def\normal@text{\global\let\\=\@normalcr \global\leftskip\z@ \global\@rightskip\z@ \global\rightskip\@rightskip \global\parfillskip\@flushglue} % \def\@writecount{\write\@mainaux{\string\global \string\@namedef{n@author@}{\the\n@author}}% } % % TITLE \def\pretitle#1{% \vspace*{\b@pretitle@skip}\pretitle@size#1\par\vskip6\p@\hrule \vskip12\p@} % \def\title#1{% \beg@elem \title@note@fmt \add@tok\t@glob@notes {\title@note@fmt}% \proc@elem{title}{#1}% \def\title@notes{\the\t@loc@notes}% \title@fmt{\@title}{\title@notes}% \ignorespaces} % \newdimen\@@topskip \@@topskip=24\p@ % \def\title@fmt#1#2{% \vspace*{\@@topskip} {\title@size #1\hbox{$^{#2}$}\par}% \vskip\a@title@skip% } % \def\subtitle#1{% \beg@elem \proc@elem{subtitle}{#1}% \def\title@notes{\the\t@loc@notes}% \subtitle@fmt{\@subtitle}{\title@notes}% \ignorespaces} % % \def\subtitle@fmt#1#2{% {\subtitle@size #1\,\hbox{$^{\mathrm{#2}}$}\par}% \vskip\a@title@skip% } % \def\title@note@fmt{\def\thefootnote{\arabic{footnote}}} % % AUTHOR % \newdimen\b@author@skip \b@author@skip 12\p@ % \def\author{\@ifnextchar[{\author@optarg}{\author@optarg[]}} % \def\author@optarg[#1]#2{\stepcounter{author}% \beg@elem\def\degs##1{##1}\def\fnms##1{##1}\def\inits##1{##1}% \def\snm##1{\MakeUppercase{##1}}\def\roles##1{##1}% \if@firstauthor% \first@author \global\@firstauthorfalse \fi% \@for\@tempa:=#1\do{\expandafter\add@addressref\expandafter{\@tempa}}% \proc@elem{author}{#2}% \author@fmt{\the\c@author}{\the\t@loc@notes}{\@author}}% % %\newbox\author@box % \def\author@fmt#1#2#3{\@newelemtrue \ifnum\prev@elem=\e@author \global\@newelemfalse \fi \if@newelem \author@fmt@init \fi \edef\@tempb{#2}\ifx\@tempb\@empty \hbox{#3}\else \hbox{#3\,$^{\mathrm{#2}}$}% \fi} % \def\first@author{\author@note@fmt% \add@tok\t@glob@notes% {\author@note@fmt}}% % \def\author@fmt@init{% \par \vskip \b@author@skip \authors@size\centering \leavevmode} % \def\and{\unskip~and~} % \def\author@note@fmt{% \def\thefootnote{\arabic{footnote}}} % \def\sxarabic#1{% \expandafter\ifcase\value{#1} \or *\or **\or *** \or **** \or *****\fi } % % ADDRESS % \def\email#1{{e-mail:\ #1}} % \def\address{\@ifstar{\address@star}% {\@ifnextchar[{\address@optarg}{\address@noptarg}}} % \def\address@optarg[#1]#2{\refstepcounter{address}% \beg@elem \proc@elem{address}{#2}% \address@fmt{\the\c@address}{\the\t@loc@notes}{\@address}\label{#1}% \ignorespaces} % \def\address@noptarg#1{\refstepcounter{address}% \beg@elem \proc@elem{address}{#1}% \address@fmt{\z@}{\the\t@loc@notes}{\@address}% \ignorespaces} % \def\address@star#1{% \beg@elem \proc@elem{address}{#1}% \address@fmt{\m@ne}{\the\t@loc@notes}{\@address}% \ignorespaces} % \def\theaddress{\alph{address}} % \def\address@fmt#1#2#3{\@newelemtrue \ifnum\prev@elem=\e@address \@newelemfalse \fi \if@newelem \address@fmt@init \fi \bgroup\parskip\z@\noindent\centering \address@size \ifnum#1=\z@ #3\,$^{\mathrm{#2}}$\space% \else \ifnum#1=\m@ne $^{\phantom{\mathrm{\theaddress}}\,}$#3\,$^{\mathrm{#2}}$% \else $^{\mathrm{\theaddress}\,}$#3\,$^{\mathrm{#2}}$% \fi \fi \par\egroup} % \def\address@fmt@init{% \def\@currentlabel{\theaddress} \par \vskip 2\p@ plus 1\p@ minus 1\p@} % % ABSTRACT % \def\abstract{\@ifnextchar[{\@abstract}{\@abstract[]}} \def\@abstract[#1]{% \global\@hasabstracttrue \hyphenpenalty\sv@hyphenpenalty \global\setbox\t@abstract=\vbox\bgroup \linewidth\abstract@width \hsize\abstract@width \justify@on\abstract@size\parindent 1em \abstract@indent\textbf{\abstractname}\ignorespaces} \def\endabstract{\par\egroup} % % KEYWORDS \def\sep{\unskip, } \global\@haskeywordsfalse \newdimen\dp@t@keywords \def\keyword{\global\@haskeywordstrue% \global\setbox\t@keywords=\vbox\bgroup% \hsize\abstract@width% \justify@on\abstract@size\parindent 0\p@ \textbf{\keywordsname}\ignorespaces } \def\endkeyword{\par\egroup\global\dp@t@keywords=\dp\t@keywords} \def\keywords#1{\begin{keyword}#1\end{keyword}} % % % % Running title \def\runningtitle#1{\gdef\@runtitle{#1}} \def\@runtitle{} \def\runningauthor#1{{\def\etal{et al.}\gdef\@runauthor{#1\@runsep}}} \def\@runauthor{} \def\runningsep#1{\gdef\@runsep{#1}} \def\@runsep{\ /\ } % \def\journal#1{\gdef\@journal{#1}} \@ifundefined{@journal}{\gdef\@journal{Journal not defined}}{} \def\volume#1{\gdef\@volume{#1}} \def\@volume{0} \def\issue#1{\gdef\@issue{#1}} \def\@issue{0} % % \newcount\@pubyear \newcount\@copyear \@pubyear=\number\year \@copyear\@pubyear \advance\@copyear-2000 \def\pubyear#1{\global\@pubyear#1 \global\@copyear\@pubyear \global\advance\@copyear-2000% \ignorespaces} % \def\the@copyear{\ifnum\@copyear<10 0\fi\the\@copyear} % \pubyear{2003} % \def\firstpage#1{\def\@tempa{#1}\ifx\@tempa\@empty\else \gdef\@firstpage{#1}\gdef\@lastpage{#1}% \global\c@page=#1 \ignorespaces\fi } \def\@firstpage{1} \def\lastpage#1{\def\@tempa{#1}\ifx\@tempa\@empty\else \gdef\@lastpage{#1}\ignorespaces\fi} \def\@lastpage{0} \def\@pagerange{1--0} % Write the last page: \def\write@last@page{% \write\@mainaux{\string\global\string\@namedef{@lastpage}{\the\c@page}}} \AtEndDocument{\write@last@page} % SGML \long\def\convertas#1#2{#2} \def\sday#1{#1}\def\smonth#1{#1}\def\syear#1{#1} \def\aid#1{\gdef\@aid{#1}} % \def\SSDI#1{\gdef\@ssdi{#1}} \def\@ssdi{000000-00} \def\issn#1{\gdef\@issn{#1}} \def\price#1{\gdef\@price{#1}} % \def\date#1{\gdef\@date{#1}} \def\@date{\today} % \def\empty@data{\@nil} % %***************** BACKMATTER \newcommand\backmatter{\goodbreak} %**************** INICIALIZATION \newcommand\refname{References} \newcommand\figurename{Figure} \newcommand\tablename{Table} \newcommand\algorithmname{Algorithm} \newcommand\appendixname{Appendix} \newcommand\abstractname{Abstract. } \newcommand\keywordsname{Keywords. } \def\acknowledgementsname{Acknowledgements} % \def\copyright@sign{\copyright} % % DIMENSIONS \def\@articletypesize{\large} \def\pretitle@size{\LARGE} \def\title@size{\huge} \def\subtitle@size{\large\itshape} \def\authors@size{\normalsize} \def\abstract@size{\footnotesize} \def\abstract@width{22pc} \def\abstract@indent{\noindent} \def\address@size{\normalsize\itshape} % Block preparation of contents: \def\addcontentsline#1#2#3{} \long\def\addtocontents#1#2{} % \newcommand\today{} \edef\today{\ifcase\month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi \space\number\day, \number\year} % \@twosidetrue \pagenumbering{arabic} \frenchspacing \init@settings \if@twocolumn\setlength\tablewidth{\columnwidth} \else\setlength\tablewidth{\textwidth}\fi %\pagestyle{headings} \pagestyle{empty} \endinput %% %% End of file `IOS-Book-Article.cls'. ================================================ FILE: marktoberdorf_paper/DSE/cpp2.json ================================================ { "name": "cpp2", "extend": "cpp", "extraKeywords": ["function","override","var","instanceof"] } ================================================ FILE: marktoberdorf_paper/DSE/dse.bib ================================================ @article{King76, author = {James C. King}, title = {Symbolic Execution and Program Testing}, journal = {Communications of the ACM}, volume = {19}, number = {7}, pages = {385–394}, year = {1976} } @article{Clarke76, author = {Lori A. Clarke}, title = {A System to Generate Test Data and Symbolically Execute Programs}, journal = {{IEEE} Transactions on Software Engineering}, volume = {2}, number = {3}, pages = {215--222}, year = {1976} } @book{Dijkstra76, author = {Edsger W. Dijkstra}, title = {A Discipline of Programming}, publisher = {Prentice-Hall}, year = {1976} } @article{Korel90, author = {Bogdan Korel}, title = {Automated Software Test Data Generation}, journal = {{IEEE} Transactions on Software Engineering}, volume = {16}, number = {8}, pages = {870--879}, year = {1990} } @article{Korel92, author = {Bogdan Korel}, title = {Dynamic Method of Software Test Data Generation}, journal = {Journal of Software Testing, Verification and Reliability}, volume = {2}, number = {4}, pages = {203--213}, year = {1992} } @inproceedings{Gupta00, author = {Neelam Gupta and Aditya P. Mathur and Mary Lou Soffa}, title = {Generating Test Data for Branch Coverage}, booktitle = {Proceedings of the Automate Software Engineering Conference}, pages = {219--228}, year = {2000} } @inproceedings{GodefroidKS05, author = {Patrice Godefroid and Nils Klarlund and Koushik Sen}, title = {{DART:} directed automated random testing}, booktitle = {Proceedings of the {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation}, pages = {213--223}, year = {2005} } @inproceedings{SenACAV06, author = {Koushik Sen and Gul Agha}, title = {{CUTE} and jCUTE: Concolic Unit Testing and Explicit Path Model-Checking Tools}, booktitle = {Proceedings of 18th Computer Aided Verification Conference}, pages = {419--423}, year = {2006} } @inproceedings{CadarE05, author = {Cristian Cadar and Dawson R. Engler}, title = {Execution Generated Test Cases: How to Make Systems Code Crash Itself}, booktitle = {Proceedings of 12th International {SPIN} Workshop}, pages = {2--23}, year = {2005} } @inproceedings{CadarGPDE06, author = {Cristian Cadar and Vijay Ganesh and Peter M. Pawlowski and David L. Dill and Dawson R. Engler}, title = {{EXE:} automatically generating inputs of death}, booktitle = {Proceedings of the 13th {ACM} Conference on Computer and Communications Security}, pages = {322--335}, year = {2006} } @inproceedings{CadarDE08, author = {Cristian Cadar and Daniel Dunbar and Dawson R. Engler}, title = {{KLEE:} Unassisted and Automatic Generation of High-Coverage Tests for Complex Systems Programs}, booktitle = {Proceedings of the 8th {USENIX} Symposium on Operating Systems Design and Implementation}, pages = {209--224}, year = {2008} } @inproceedings{deMouraB08, author = {Leonardo Mendon{\c{c}}a de Moura and Nikolaj Bj{\o}rner}, title = {{Z3:} An Efficient {SMT} Solver}, booktitle = {Proceedings of the 14th International Conference of Tools and Algorithms for the Construction and Analysis of Systems}, pages = {337--340}, year = {2008} } @inproceedings{Godefroid11, author = {Patrice Godefroid}, title = {Higher-order test generation}, booktitle = {Proceedings of the {ACM} {SIGPLAN} Conference on Programming Language Design and Implementation}, pages = {258--269}, year = {2011} } @article{GodefroidLM12, author = {Patrice Godefroid and Michael Y. Levin and David A. Molnar}, title = {{SAGE:} whitebox fuzzing for security testing}, journal = {Communications of the {ACM}}, volume = {55}, number = {3}, pages = {40--44}, year = {2012} } @article{CadarS13, author = {Cristian Cadar and Koushik Sen}, title = {Symbolic execution for software testing: three decades later}, journal = {Communications of the {ACM}}, volume = {56}, number = {2}, pages = {82--90}, year = {2013} } ================================================ FILE: marktoberdorf_paper/DSE/ignores.dic ================================================ ================================================ FILE: marktoberdorf_paper/DSE/out/DSE.tex ================================================ \documentclass{IOS-Book-Article} % generated by Madoko, version 0.9.3-beta %mdk-data-line={1} \usepackage[heading-base=2]{madoko} \begin{document} %mdk-begin-texraw %mdk-data-line={25} \begin{frontmatter} % The preamble begins here. %\pretitle{Pretitle} \title{Deconstructing Dynamic Symbolic Execution} %\runningtitle{IOS Press Style Sample} %\subtitle{Subtitle} \author[A]{\fnms{Thomas} \snm{Ball}} and \author[B]{\fnms{Jakub} \snm{Daniel}} \runningauthor{Thomas Ball et al.} \address[A]{Microsoft Research} \address[B]{Charles University} \begin{mdDiv}[class={abstract},elem={abstract},data-line={39}]% \begin{mdP}[data-line={40}]% %mdk-data-line={40} {}Dynamic symbolic execution (DSE) is a well-known technique for automatically generating tests to achieve higher levels of coverage in a program. Two keys ideas of DSE are to: (1) seed symbolic execution by executing a program on an initial input; (2) use concrete values from the program execution in place of symbolic expressions whenever symbolic reasoning is hard or not desired. We describe DSE for a simple core language and then present a minimalist implementation of DSE for Python (in Python) that follows this basic recipe. The code is available at https://www.github.com/thomasjball/PyExZ3/ (tagged %mdk-data-line={50} {}{\textquotedblleft}v1.0{\textquotedblright}%mdk-data-line={50} {}) and has been designed to make it easy to experiment with and extend.% \end{mdP}%% \end{mdDiv}% %mdk-begin-texraw %mdk-data-line={56} \begin{keyword} Symbolic Execution, Automatic Test Generation, White-box Testing, Automated Theorem Provers \end{keyword} \end{frontmatter} \thispagestyle{empty} \pagestyle{empty} \mdHxx[id=sec-intro,label={[1]\{.heading-label\}},toc={},data-line={70},caption={[[1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Introduction},bookmark={1.{\hspace{0.5em}}Introduction}]{%mdk-data-line={70} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1}.{\hspace{0.5em}}}%mdk-data-line={70} {}Introduction}%mdk-data-line={73} \defcommand{\mathkw}[1]{\textbf{#1}} \begin{mdP}[data-line={78}]% %mdk-data-line={78} {}Static, path-based symbolic execution explores one control-flow path at a time through a (sequential) program %mdk-data-line={79} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={79} {}, using an automated theorem prover (ATP) to determine if the current path %mdk-data-line={80} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={80} {} is feasible%mdk-data-line={80} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{clarke76}{}{\mdSpan[class={bibitem-label}]{4}}, \mdA[class={bibref,localref},target-element={bibitem}]{king76}{}{\mdSpan[class={bibitem-label}]{11}}]}%mdk-data-line={80} {}. Ideally, symbolic execution of a path %mdk-data-line={81} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={81} {} through program %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={82} {} yields a logic formula %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={82} {} that describes the set of inputs %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={82} {} (possibly empty) to program %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={83} {} such that for any %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$i \in I$}%mdk-data-line={83} {}, the execution %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={83} {} follows path %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={83} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={85}]% %mdk-data-line={85} {}If the formula %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={85} {} is unsatisfiable then %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={85} {} is empty and so path %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={85} {} is not feasible; if the formula is satisfiable then %mdk-data-line={86} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={86} {} is not empty and so path %mdk-data-line={86} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={86} {} is feasible. In this case, a model of %mdk-data-line={87} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={87} {} provides a witness %mdk-data-line={87} {}\mdSpan[class={math-inline},elem={math-inline}]{$i \in I$}%mdk-data-line={87} {}. Thus, a model-generating ATP can be used in conjunction with symbolic execution to automatically generate tests to cover paths in a program. Combined with a search strategy, one gets, in the limit, an exhaustive white-box testing procedure, for which there are many applications%mdk-data-line={92} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{cadars13}{}{\mdSpan[class={bibitem-label}]{2}}, \mdA[class={bibref,localref},target-element={bibitem}]{cadargpde06}{}{\mdSpan[class={bibitem-label}]{3}}, \mdA[class={bibref,localref},target-element={bibitem}]{godefroidlm12}{}{\mdSpan[class={bibitem-label}]{9}}]}%mdk-data-line={92} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={94}]% %mdk-data-line={94} {}The formula %mdk-data-line={94} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={94} {} is called a %mdk-data-line={94} {}\mdEm{path-condition}%mdk-data-line={94} {} of the path %mdk-data-line={94} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={94} {}. We will see that a given path %mdk-data-line={95} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={95} {} can induce many different path-conditions. A path-condition %mdk-data-line={96} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={96} {} for path %mdk-data-line={96} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={96} {} is %mdk-data-line={96} {}\mdEm{sound}%mdk-data-line={96} {} if every input assignment satisfying %mdk-data-line={97} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={97} {} defines an execution of program %mdk-data-line={98} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={98} {} that follows path %mdk-data-line={98} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={98} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{godefroid11}{}{\mdSpan[class={bibitem-label}]{7}}]}%mdk-data-line={98} {}. By its definition, the formula %mdk-data-line={99} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={99} {} is sound and the best representation of %mdk-data-line={99} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={99} {} (as for all sound path-conditions %mdk-data-line={100} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={100} {}, we have that %mdk-data-line={100} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p \implies \phi_p$}%mdk-data-line={100} {}). In practice, we attempt to compute sound under-approximations of %mdk-data-line={101} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={101} {} such as %mdk-data-line={102} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={102} {}. However, we also find it necessary (and useful) to compute unsound path-conditions.% \end{mdP}% \begin{mdP}[class={indent},data-line={105}]% %mdk-data-line={105} {}A path-condition can be translated into the input language of an ATP, such as%mdk-data-line={106} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={106} {}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{demourab08}{}{\mdSpan[class={bibitem-label}]{5}}]}%mdk-data-line={106} {}, which provides an answer of %mdk-data-line={107} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={107} {}, %mdk-data-line={107} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={107} {} or %mdk-data-line={107} {}{\textquotedblleft}unknown{\textquotedblright}%mdk-data-line={107} {}, due to theoretical or practical limitations in automatically deciding satisfiability of various logics. In the case that the ATP is able to prove %mdk-data-line={109} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={109} {} we can query it for satisfying model in order to generate test inputs. A path-condition for %mdk-data-line={111} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={111} {} can be thought of as function from a program%mdk-data-line={112} {}{'}%mdk-data-line={112} {}s primary inputs to a Boolean output representing whether or not %mdk-data-line={113} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={113} {} is executed under a given input. Thus, we are asking the ATP to invert a function when we ask it to decide the satisfiability/unsatisfiability of a path-condition.% \end{mdP}% \begin{mdP}[class={indent},data-line={117}]% %mdk-data-line={117} {}The static translation of a path %mdk-data-line={117} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={117} {} through a program %mdk-data-line={117} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={117} {} into the most precise path-condition %mdk-data-line={118} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={118} {} is not a simple task, as programming languages and their semantics are very complex. Completely characterizing the set of inputs %mdk-data-line={120} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={120} {} that follow path %mdk-data-line={121} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={121} {} means providing a symbolic interpretation of every operation in the language so that the ATP can reason about it. For example, consider a method call in Python. Python%mdk-data-line={124} {}{'}%mdk-data-line={124} {}s algorithm for method resolution order (see%mdk-data-line={124} {}{\mdNbsp}\mdA[data-linkid={mro}]{https://www.python.org/download/releases/2.3/mro/}{}{MRO}%mdk-data-line={124} {}) depends on the inheritance hierarchy of the program, a directed, acyclic graph that can evolve during program execution. Symbolically encoding Python%mdk-data-line={127} {}{'}%mdk-data-line={127} {}s method resolution order is possible but non-trivial. There are other reasons it is hard or undesirable to symbolically execute various operations, as will be explained in detail later.% \end{mdP}% \mdHxxx[id=sec-dynamic-symbolic-execution,label={[1.1]\{.heading-label\}},toc={},data-line={131},caption={[[1.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Dynamic symbolic execution},bookmark={1.1.{\hspace{0.5em}}Dynamic symbolic execution}]{%mdk-data-line={131} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.1}.{\hspace{0.5em}}}%mdk-data-line={131} {}Dynamic symbolic execution}\begin{mdP}[data-line={133}]% %mdk-data-line={133} {}\mdEm{Dynamic}%mdk-data-line={133} {} symbolic execution (DSE) is a form of path-based symbolic execution based on two insights. First, the approach starts by executing program %mdk-data-line={135} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={135} {} on some input %mdk-data-line={136} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={136} {}, seeding the symbolic execution process with a feasible path%mdk-data-line={137} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{gupta00}{}{\mdSpan[class={bibitem-label}]{10}}, \mdA[class={bibref,localref},target-element={bibitem}]{korel90}{}{\mdSpan[class={bibitem-label}]{12}}, \mdA[class={bibref,localref},target-element={bibitem}]{korel92}{}{\mdSpan[class={bibitem-label}]{13}}]}%mdk-data-line={137} {}. Second, DSE uses concrete values from the execution %mdk-data-line={139} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={139} {} in place of symbolic expressions whenever symbolic reasoning is not possible or desired%mdk-data-line={140} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{cadare05}{}{\mdSpan[class={bibitem-label}]{1}}, \mdA[class={bibref,localref},target-element={bibitem}]{godefroidks05}{}{\mdSpan[class={bibitem-label}]{8}}]}%mdk-data-line={140} {}. The major benefit of DSE is to simplify the construction of a symbolic execution tool by leveraging concrete execution behavior (given by actually running the program). As DSE combines both concrete and symbolic reasoning, it also has been called %mdk-data-line={146} {}{\textquotedblleft}concolic{\textquotedblright}%mdk-data-line={146} {} execution%mdk-data-line={147} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{senacav06}{}{\mdSpan[class={bibitem-label}]{14}}]}%mdk-data-line={147} {}.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-dse,label={[1]\{.figure-label\}},elem={figure},toc-line={[1]\{.figure-label\}. Pseudo-code for dynamic symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Pseudo-code for dynamic symbolic execution},data-line={149}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={150},data-line-code={151}]% \mdPrecode[data-line={151}]{{\preindent{2}}\mdToken{Identifier,Python}{i}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{an}{\prespace{1}}\mdToken{Identifier,Python}{input}{\prespace{1}}\mdToken{Identifier,Python}{to}{\prespace{1}}\mdToken{Identifier,Python}{program}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{P}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{while}{\prespace{1}}\mdToken{Identifier,Python}{defined}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{i}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{p}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{path}{\prespace{1}}\mdToken{Identifier,Python}{covered}{\prespace{1}}\mdToken{Identifier,Python}{by}{\prespace{1}}\mdToken{Identifier,Python}{execution}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{P}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{i}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{cond}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{pathCondition}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{p}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{s}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{ATP}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Namespace,Identifier,Python}{Not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{cond}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{i}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{s}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{model}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={158}]{}\begin{mdDiv}[data-line={159}]% %mdk-data-line={159} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{1}.} }Pseudo-code for dynamic symbolic execution}%mdk-data-line={159} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={160}]% %mdk-data-line={160} {}The pseudo-code of Figure%mdk-data-line={160} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-dse}{}{\mdSpan[class={figure-label}]{1}}%mdk-data-line={160} {} shows the high level process of DSE. The variable %mdk-data-line={161} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{i}}%mdk-data-line={161} {} represents an input to program %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Constructor,Identifier,Python}{P}}%mdk-data-line={162} {}. Execution of program %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Constructor,Identifier,Python}{P}}%mdk-data-line={162} {} on the input %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{i}}%mdk-data-line={162} {} traces a path %mdk-data-line={163} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{p}}%mdk-data-line={163} {}, from which a logical formula %mdk-data-line={164} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{pathCondition}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{p}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={164} {} is constructed. Finally, the ATP is called with the negation of the path-condition to find a new input (that hopefully will cover a new path). This pseudo-code elides a number of details that we will deal with later.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-easy-dse,label={[2]\{.figure-label\}},elem={figure},toc-line={[2]\{.figure-label\}. Easy example: computing the maximum of four numbers in Python.},toc={tof},float-env={figure},float-name={Figure},caption={Easy example: computing the maximum of four numbers in Python.},data-line={169}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={170},data-line-code={171}]% \mdPrecode[data-line={171}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{s}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{t}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{s}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{t}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{8}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{t}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{else}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{8}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{s}\prebr{} \prebr{} \mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{max4}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={180}]{}\begin{mdDiv}[data-line={181}]% %mdk-data-line={181} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{2}.} }Easy example: computing the maximum of four numbers in Python.}%mdk-data-line={181} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent,para-continue},data-line={182}]% %mdk-data-line={182} {}Consider the Python function %mdk-data-line={182} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={182} {} in Figure%mdk-data-line={182} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-easy-dse}{}{\mdSpan[class={figure-label}]{2}}%mdk-data-line={182} {}, which computes the maximum of four numbers via three calls to the function %mdk-data-line={184} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max2}}%mdk-data-line={184} {}. Suppose we execute %mdk-data-line={184} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={184} {} with values of zero for all four arguments. In this case, the execution path %mdk-data-line={186} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={186} {} contains three comparisons (in the order %mdk-data-line={186} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={186} {}, %mdk-data-line={187} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={187} {}, %mdk-data-line={187} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={187} {}), all of which evaluate false. Thus, the path-condition for path %mdk-data-line={188} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={188} {} is %mdk-data-line={188} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={188} {}. Negating this condition yields %mdk-data-line={189} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{or}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{or}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={189} {}. Taking the execution ordering of the three comparisons into account, we derive three expressions from the negated path-condition to generate new inputs that will explore execution prefixes of path %mdk-data-line={192} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={192} {} of increasing length:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={194}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={194}]% %mdk-data-line={194} {}\mdEm{length 0}%mdk-data-line={194} {}: %mdk-data-line={194} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={194} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={195}]% %mdk-data-line={195} {}\mdEm{length 1}%mdk-data-line={195} {}: %mdk-data-line={195} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={195} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={196}]% %mdk-data-line={196} {}\mdEm{length 2}%mdk-data-line={196} {}: %mdk-data-line={196} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={196} {}% \end{mdLi}%% \end{mdUl}% \begin{mdP}[class={para-continue},data-line={198}]% %mdk-data-line={198} {}The purpose of taking execution order into account should be clear, as the comparison %mdk-data-line={199} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={199} {} only executes in the case where %mdk-data-line={199} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={199} {} holds. Integer solutions to the above three systems of constraints are:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={202}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={202}]% %mdk-data-line={202} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{2}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}}%mdk-data-line={202} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={203}]% %mdk-data-line={203} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{3}}%mdk-data-line={203} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={204}]% %mdk-data-line={204} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{2}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}}%mdk-data-line={204} {}% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={206}]% %mdk-data-line={206} {}In the three cases above, we sought solutions that kept as many of the variables as possible equal to the original input (in which all variables are equal to 0). Execution of the %mdk-data-line={208} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={208} {} function on the input corresponding to the first solution produces the path-condition %mdk-data-line={210} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={210} {}, from which we can produce more inputs. For this (loop-free function), there are a finite number of path-conditions. We leave it as an exercise to the reader to enumerate them all.% \end{mdP}% \mdHxxx[id=sec-leveraging-concrete-values-in-dse,label={[1.2]\{.heading-label\}},toc={},data-line={215},caption={[[1.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Leveraging concrete values in DSE},bookmark={1.2.{\hspace{0.5em}}Leveraging concrete values in DSE}]{%mdk-data-line={215} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.2}.{\hspace{0.5em}}}%mdk-data-line={215} {}Leveraging concrete values in DSE}\begin{mdP}[data-line={217}]% %mdk-data-line={217} {}We now consider several situations where we can make use of concrete values in DSE. In the realm of (unbounded-precision) integer arithmetic (e.g., bignum integer arithmetic, as in Python 3.0 onwards), it is easy to come up with tiny programs that will be %mdk-data-line={220} {}\mdEm{very difficult}%mdk-data-line={220} {}, if not %mdk-data-line={221} {}\mdEm{impossible}%mdk-data-line={221} {}, for any symbolic execution tool to deal with, such as the function %mdk-data-line={222} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={222} {} in Figure%mdk-data-line={223} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-fermat3}{}{\mdSpan[class={figure-label}]{3}}%mdk-data-line={223} {}.%mdk-data-line={223} {} %mdk-data-line={223} {}% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-fermat3,label={[3]\{.figure-label\}},elem={figure},toc-line={[3]\{.figure-label\}. Hard example for symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Hard example for symbolic execution},data-line={226}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={227},data-line-code={228}]% \mdPrecode[data-line={228}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{fermat3}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{3}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{z}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{6}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{+}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{10}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{String,Delim,Python,BracketOpen}{{"}}\mdToken{String,Python}{Fermat\prespace{1}and\prespace{1}Wiles\prespace{1}were\prespace{1}wrong!?!}\mdToken{String,Delim,Python,BracketClose}{{"}}\prebr{} {\preindent{3}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{0}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={234}]{}\begin{mdDiv}[data-line={235}]% %mdk-data-line={235} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{3}.} }Hard example for symbolic execution}%mdk-data-line={235} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={237}]% %mdk-data-line={237} {}Fermat%mdk-data-line={237} {}{'}%mdk-data-line={237} {}s Last Theorem, proved by Andrew Wiles in the late 20th century, states that no three positive integers %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={239} {}, %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={239} {}, and %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$z$}%mdk-data-line={239} {} can satisfy the equation %mdk-data-line={240} {}\mdSpan[class={math-inline},elem={math-inline}]{$x^n + y^n = z^n$}%mdk-data-line={240} {} for any integer value of %mdk-data-line={240} {}\mdSpan[class={math-inline},elem={math-inline}]{$n$}%mdk-data-line={240} {} greater than two. The function %mdk-data-line={241} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={241} {} encodes this statement for %mdk-data-line={241} {}\mdSpan[class={math-inline},elem={math-inline}]{$n=3$}%mdk-data-line={241} {}. It is not reasonable to have a computer waste time trying to find a solution that would cause %mdk-data-line={243} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={243} {} to print the string %mdk-data-line={244} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{String,Delim,Python,BracketOpen}{{"}}\mdToken{String,Python}{Fermat\prespace{1}and\prespace{1}Wiles\prespace{1}were\prespace{1}wrong!?!}\mdToken{String,Delim,Python,BracketClose}{{"}}}%mdk-data-line={244} {}. In cases of complex (non-linear) arithmetic operations, such as %mdk-data-line={246} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}}%mdk-data-line={246} {}, we might choose to handle the operation concretely.% \end{mdP}% \begin{mdP}[class={indent},data-line={248}]% %mdk-data-line={248} {}There are a number of ways to deal with the above issue: one is to recognize all non-linear terms in a symbolic expression and replace them with their concrete counterparts during execution. For the %mdk-data-line={250} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={250} {} example, this would mean that during DSE the symbolic expression %mdk-data-line={252} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{+}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={252} {} would be reduced to the constant %mdk-data-line={252} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{False}}%mdk-data-line={252} {} by evaluation on the concrete values of variables %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={253} {}, %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{y}}%mdk-data-line={253} {} and %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{z}}%mdk-data-line={253} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={255}]% %mdk-data-line={255} {}Besides difficult operations (such as non-linear arithmetic), other examples of code that we might treat concretely instead of symbolically include functions that are hard to invert, such as cryptographic hash functions, or low-level functions that we do not wish to test (such as operating system functions). Consider the code in Figure%mdk-data-line={261} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-hash}{}{\mdSpan[class={figure-label}]{4}}%mdk-data-line={261} {}, which applies the function %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={262} {} to argument %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={262} {} and compares it to argument %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{y}}%mdk-data-line={262} {}. By using the name %mdk-data-line={263} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={263} {} we simply mean to say that we wish to model this function as a black box, with no knowledge of how it operates internally.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-hash,label={[4]\{.figure-label\}},elem={figure},toc-line={[4]\{.figure-label\}. Another hard example for symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Another hard example for symbolic execution},data-line={267}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={268},data-line-code={269}]% \mdPrecode[data-line={269}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{dart}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{5}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{1}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{0}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={274}]{}\begin{mdDiv}[data-line={275}]% %mdk-data-line={275} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{4}.} }Another hard example for symbolic execution}%mdk-data-line={275} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={276}]% %mdk-data-line={276} {}In such a case, we can use DSE to execute the function %mdk-data-line={276} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={276} {} on a specific input (say %mdk-data-line={277} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{5013}}%mdk-data-line={277} {}) and observe its output (say %mdk-data-line={278} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{42}}%mdk-data-line={278} {}). That is, rather than execute %mdk-data-line={278} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={278} {} symbolically and invoke an ATP to invert the function%mdk-data-line={279} {}{'}%mdk-data-line={279} {}s path-condition, we simply treat the call to %mdk-data-line={280} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={280} {} concretely, substituting its return value (in this case %mdk-data-line={281} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{42}}%mdk-data-line={281} {}) for the specialized expression %mdk-data-line={282} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}}%mdk-data-line={282} {} to get the predicate %mdk-data-line={282} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={282} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={284}]% %mdk-data-line={284} {}Adding the constraint %mdk-data-line={284} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={284} {} yields the sound but rather specific path-condition %mdk-data-line={286} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={286} {}. Note that the path-condition %mdk-data-line={287} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={287} {} is not sound, as it admits any value for the variable %mdk-data-line={288} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={288} {}, which likely includes many values for which %mdk-data-line={289} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={289} {} is false.% \end{mdP}% \mdHxxx[id=sec-overview,label={[1.3]\{.heading-label\}},toc={},data-line={291},caption={[[1.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Overview},bookmark={1.3.{\hspace{0.5em}}Overview}]{%mdk-data-line={291} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.3}.{\hspace{0.5em}}}%mdk-data-line={291} {}Overview}\begin{mdP}[class={para-continue},data-line={293}]% %mdk-data-line={293} {}This introduction elides many important issues that arise in implementing DSE for a real language, which we will focus on in the remainder of the paper. These include how to:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={297}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={297}]% %mdk-data-line={297} {}Identify the code under test %mdk-data-line={297} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={297} {} and the symbolic inputs to %mdk-data-line={297} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={297} {};% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={298}]% %mdk-data-line={298} {}Trace the control flow path %mdk-data-line={298} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={298} {} taken by execution %mdk-data-line={298} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={298} {};% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={299}]% %mdk-data-line={299} {}Reinterpret program operations to compute symbolic expressions;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(4)]\{.ul-li-label\}},elem={li},data-line={300}]% %mdk-data-line={300} {}Generate a path-condition from %mdk-data-line={300} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={300} {} and the symbolic expressions;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(5)]\{.ul-li-label\}},elem={li},data-line={301}]% %mdk-data-line={301} {}Generate a new input %mdk-data-line={301} {}\mdSpan[class={math-inline},elem={math-inline}]{$i'$}%mdk-data-line={301} {} by negating (part of) the path-condition, translating the path-condition to the input language of an ATP, invoking the ATP, and lifting a satisfying model (if any) back up to the source level;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(6)]\{.ul-li-label\}},elem={li},data-line={304}]% %mdk-data-line={304} {}Guide the search to expose new paths.% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={306}]% %mdk-data-line={306} {}The rest of this paper is organized as follows. Section%mdk-data-line={306} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={306} {} describes an instrumented typing discipline where we lift each type (representing a set of concrete values) to a symbolic type (representing a set of pairs of concrete and symbolic values). Section%mdk-data-line={310} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-sp2dse}{}{\mdSpan[class={heading-label}]{3}}%mdk-data-line={310} {} shows how strongest postconditions defines a symbolic semantics for a small programming language and how strongest postconditions can be refined to model DSE. Section%mdk-data-line={313} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-impl}{}{\mdSpan[class={heading-label}]{4}}%mdk-data-line={313} {} describes an implementation of DSE for the Python language in the Python language that follows the instrumented semantics pattern closely (full implementation and tests available at%mdk-data-line={315} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={315} {}, tagged %mdk-data-line={315} {}{\textquotedblleft}v1.0{\textquotedblright}%mdk-data-line={315} {}). Section%mdk-data-line={316} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={316} {} describes the symbolic encoding of Python integer operations using two decision procedures of Z3: linear arithmetic with uninterpreted functions in place of non-linear operations; fixed-width bit-vectors with precise encodings of most operations. Section%mdk-data-line={320} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-extensions}{}{\mdSpan[class={heading-label}]{6}}%mdk-data-line={320} {} offers a number of ideas for projects to extend the capabilities of%mdk-data-line={321} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={321} {}.% \end{mdP}% \mdHxx[id=sec-semantics,label={[2]\{.heading-label\}},toc={},data-line={323},caption={[[2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Instrumented Types},bookmark={2.{\hspace{0.5em}}Instrumented Types}]{%mdk-data-line={323} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{2}.{\hspace{0.5em}}}%mdk-data-line={323} {}Instrumented Types}\begin{mdP}[data-line={325}]% %mdk-data-line={325} {}We are given a universe of classes/types %mdk-data-line={325} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={325} {}; a type %mdk-data-line={325} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={325} {} carries along a set of operations that apply to values of type %mdk-data-line={326} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={326} {}, where an operation %mdk-data-line={327} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={327} {} takes an argument list of typed values as input (the first being of type %mdk-data-line={328} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={328} {}) and produces a single typed value as output. Nullary (static) operations of type %mdk-data-line={329} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={329} {} can be used to create values of type %mdk-data-line={330} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={330} {} (such as constants, objects, etc.)% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={332}]% %mdk-data-line={332} {}A program %mdk-data-line={332} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={332} {} has typed input variables %mdk-data-line={333} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 : T_1 \ldots v_k : T_k$}%mdk-data-line={333} {} and a body from the language of statements %mdk-data-line={333} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={333} {}:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={335}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={336} \begin{mdMathprearray}%mdk \mathid{S}\mdMathspace{1}\rightarrow &\mdMathspace{1}\mathid{v}\mdMathspace{1}:=\mdMathspace{1}\mathid{E}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathid{S}_1\mdMathspace{1};\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end} \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={343}]% %mdk-data-line={343} {}The language of expressions (%mdk-data-line={343} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={343} {}) is defined by the application of operations to values, where constants (nullary operations) and program variables form the leaves of the expression tree and non-nullary operators form the interior nodes of the tree. For now, we will consider all values to be immutable. That is, the only source of mutation in the language is the assignment statement.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={352}]% %mdk-data-line={352} {}To introduce symbolic execution into the picture, we can imagine that a type %mdk-data-line={353} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={353} {} has (one or more) counterparts in a symbolic universe %mdk-data-line={354} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={354} {}. A type %mdk-data-line={354} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' \in U'$}%mdk-data-line={354} {} is a subtype of %mdk-data-line={355} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={355} {} with two purposes:% \end{mdP}% \begin{mdUl}[class={ul,list-star,loose},elem={ul},data-line={357}]% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={357}]% \begin{mdP}[data-line={357}]% %mdk-data-line={357} {}First, a value of type %mdk-data-line={357} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={357} {} represents a pair of values: a concrete value %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={358} {} of (super)type %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={358} {} and a symbolic expression %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={358} {}. A symbolic expression is a tree whose leaves are either nullary operators (i.e., constants) of a type in %mdk-data-line={360} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={360} {} or are Skolem constants representing the (symbolic) inputs (%mdk-data-line={361} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 \ldots v_k$}%mdk-data-line={361} {}) to the program %mdk-data-line={362} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={362} {}, and whose interior nodes represent operations from types in %mdk-data-line={363} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={363} {}. We refer to Skolem constants as %mdk-data-line={363} {}{\textquotedblleft}symbolic constants{\textquotedblright}%mdk-data-line={363} {} from this point on. Note that symbolic expressions do not contain references to program variables.% \end{mdP}%% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={367}]% \begin{mdP}[data-line={367}]% %mdk-data-line={367} {}Second, the type %mdk-data-line={367} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={367} {} redefines some of the operations %mdk-data-line={367} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={367} {}, namely those for which we wish to compute symbolic expressions. An operation %mdk-data-line={369} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={369} {} has the same parameter list as %mdk-data-line={369} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={369} {}, allowing it to take inputs with types from both %mdk-data-line={370} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={370} {} and %mdk-data-line={370} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={370} {}. The return type of %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={371} {} generally is from %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={371} {} (though it can be from %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={371} {}). Thus, %mdk-data-line={372} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={372} {} is a proper function subtype of %mdk-data-line={372} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={372} {}. The purpose of %mdk-data-line={373} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={373} {} is to: (1) perform operation %mdk-data-line={374} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={374} {} on the concrete values associated with its inputs; (2) build a symbolic expression tree rooted at operation %mdk-data-line={376} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={376} {} whose children are the trees associated with the inputs to %mdk-data-line={377} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={377} {}.% \end{mdP}%% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={379}]% %mdk-data-line={379} {}Figure%mdk-data-line={379} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={379} {} presents pseudo code for the instrumentation of a type %mdk-data-line={380} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={380} {} via a type %mdk-data-line={380} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={380} {}. The class %mdk-data-line={381} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={381} {} is used to hold an expression tree (%mdk-data-line={381} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Expr}}%mdk-data-line={381} {}). Given a class %mdk-data-line={382} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={382} {}, a symbolic type %mdk-data-line={382} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' \in U'$}%mdk-data-line={382} {} is defined by inheriting from both %mdk-data-line={383} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={383} {} and %mdk-data-line={383} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={383} {}. This ensures that a %mdk-data-line={383} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={383} {} can be used wherever a %mdk-data-line={384} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={384} {} is expected.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-subtype,label={[5]\{.figure-label\}},elem={figure},toc-line={[5]\{.figure-label\}. Type instrumentation to carry both concrete values and symbolic expressions.},toc={tof},float-env={figure},float-name={Figure},caption={Type instrumentation to carry both concrete values and symbolic expressions.},data-line={386}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-cpp2,lang-cpp2,cpp2,highlighted},data-line={387},data-line-code={388},language={cpp2}]% \mdPrecode[data-line={388}]{{\preindent{2}}\mdToken{Keyword,Cpp}{class}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T'$}}}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\prebr{} {\preindent{4}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T'$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{e}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{Expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Source,Cpp}{S}\mdToken{Identifier,Cpp}{ymbolic}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} \prebr{} {\preindent{4}}\mdToken{Keyword,Extra,Cpp}{override}{\prespace{1}}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Keyword,Cpp}{this}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{f1}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T_1$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{fk}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T_k$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\prebr{} {\preindent{6}}\mdToken{Keyword,Extra,Cpp}{var}{\prespace{1}}\mdToken{Identifier,Cpp}{c}{\prespace{1}}:={\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Keyword,Cpp}{this}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{f1}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{fk}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\prebr{} {\preindent{6}}\mdToken{Keyword,Extra,Cpp}{var}{\prespace{1}}\mdToken{Identifier,Cpp}{e}{\prespace{1}}:={\prespace{1}}\mdToken{Keyword,Cpp}{new}{\prespace{1}}\mdToken{Source,Cpp}{E}\mdToken{Identifier,Cpp}{xpr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{self}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{f1}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{fk}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\prebr{} {\preindent{6}}\mdToken{Keyword,Cpp}{return}{\prespace{1}}\mdToken{Keyword,Cpp}{new}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\prebr{} {\preindent{4}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{4}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\prebr{} {\preindent{2}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{2}}\prebr{} {\preindent{2}}\mdToken{Keyword,Cpp}{class}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{2}}\prebr{} {\preindent{2}}\mdToken{Keyword,Extra,Cpp}{function}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{v}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{=}{\prespace{1}}\mdToken{Identifier,Cpp}{v}{\prespace{1}}\mdToken{Keyword,Extra,Cpp}{instanceof}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Operator,Cpp}{?}{\prespace{1}}\mdToken{Identifier,Cpp}{v}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{getExpr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Identifier,Cpp}{v}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={403}]{}\begin{mdDiv}[data-line={404}]% %mdk-data-line={404} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{5}.} }Type instrumentation to carry both concrete values and symbolic expressions.}%mdk-data-line={404} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent,para-continue},data-line={405}]% %mdk-data-line={405} {}A type such as %mdk-data-line={405} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={405} {} only can be constructed by providing a concrete value %mdk-data-line={405} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={405} {} of type %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={406} {} and a symbolic expression %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={406} {} to the constructor for %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={406} {}. This will be done in exactly two places:% \end{mdP}% \begin{mdUl}[class={ul,list-star,loose},elem={ul},data-line={409}]% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={409}]% \begin{mdP}[data-line={409}]% %mdk-data-line={409} {}by the creation of symbolic constants associated with the primary inputs (%mdk-data-line={410} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 \ldots v_k$}%mdk-data-line={410} {}) to the program;% \end{mdP}%% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={412}]% \begin{mdP}[data-line={412}]% %mdk-data-line={412} {}by the instrumented operations as shown in Figure%mdk-data-line={412} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={412} {}.% \end{mdP}%% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={414}]% %mdk-data-line={414} {}An instrumented operation %mdk-data-line={414} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={414} {} on arguments (%mdk-data-line={414} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={414} {}, %mdk-data-line={414} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={414} {}, %mdk-data-line={414} {}{\dots}%mdk-data-line={414} {}, %mdk-data-line={414} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={414} {}) first invokes its corresponding underlying operator %mdk-data-line={416} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={416} {} on arguments (%mdk-data-line={416} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={416} {}, %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={416} {}, %mdk-data-line={416} {}{\dots}%mdk-data-line={416} {}, %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={416} {}) to get concrete value %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{c}}%mdk-data-line={416} {}. It then constructs a new expression tree %mdk-data-line={417} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{e}}%mdk-data-line={417} {} rooted at operator %mdk-data-line={418} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={418} {}, whose children are the result of mapping the function %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expr}}%mdk-data-line={419} {} over (%mdk-data-line={419} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={419} {}, %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={419} {}, %mdk-data-line={419} {}{\dots}%mdk-data-line={419} {}, %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={419} {}). The helper function %mdk-data-line={420} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expr}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{v}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={420} {} evaluates to an expression tree in the case that %mdk-data-line={421} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{v}}%mdk-data-line={421} {} is of %mdk-data-line={421} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={421} {} type (representing a type in %mdk-data-line={422} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={422} {}) and evaluates to %mdk-data-line={422} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{v}}%mdk-data-line={422} {} itself, a concrete value of some type in %mdk-data-line={423} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={423} {}, otherwise. Finally, having computed the values %mdk-data-line={424} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{c}}%mdk-data-line={424} {} and %mdk-data-line={424} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{e}}%mdk-data-line={424} {}, the instrumented operator returns %mdk-data-line={425} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}}%mdk-data-line={425} {}, where %mdk-data-line={425} {}\mdSpan[class={math-inline},elem={math-inline}]{$R$}%mdk-data-line={425} {} is the return type of operator %mdk-data-line={425} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={425} {}, and %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$R'$}%mdk-data-line={426} {} is a subtype of %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$R$}%mdk-data-line={426} {} from universe %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={426} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={428}]% %mdk-data-line={428} {}Looked at another way, the universe %mdk-data-line={428} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={428} {} represents the %mdk-data-line={428} {}{\textquotedblleft}tainting{\textquotedblright}%mdk-data-line={428} {} of types from %mdk-data-line={429} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={429} {}. Tainted values flow from program inputs to the operands of operators. If an operator has been redefined (as above) then the taint propagates from its inputs to its outputs. On the other hand, if the operator has not been redefined, then it will not propagate the taint. In the context of DSE, %mdk-data-line={433} {}{\textquotedblleft}taint{\textquotedblright}%mdk-data-line={433} {} means that the instrumented semantics carries along a symbolic expression tree %mdk-data-line={434} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={434} {} along with a concrete value %mdk-data-line={435} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={435} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={437}]% %mdk-data-line={437} {}The choice of types from the universe %mdk-data-line={437} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={437} {} determines how symbolic expressions are constructed. For each %mdk-data-line={438} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={438} {}, the %mdk-data-line={438} {}{\textquotedblleft}most symbolic{\textquotedblright}%mdk-data-line={438} {} (least concrete) choice is the %mdk-data-line={439} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={439} {} that redefines every operator of %mdk-data-line={439} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={439} {} (as shown in Figure%mdk-data-line={440} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={440} {}). The %mdk-data-line={441} {}{\textquotedblleft}least symbolic{\textquotedblright}%mdk-data-line={441} {} (most concrete) choice is %mdk-data-line={441} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' = T$}%mdk-data-line={441} {} which redefines no operators. Let %mdk-data-line={442} {}\mdSpan[class={math-inline},elem={math-inline}]{$symbolic(T)$}%mdk-data-line={442} {} be the set of types in %mdk-data-line={443} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={443} {} that are subtypes of %mdk-data-line={443} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={443} {}. The types in %mdk-data-line={444} {}\mdSpan[class={math-inline},elem={math-inline}]{$symbolic(T)$}%mdk-data-line={444} {} are partially ordered by subset inclusion on the set of operators from %mdk-data-line={445} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={445} {} they redefine.% \end{mdP}% \mdHxx[id=sec-sp2dse,label={[3]\{.heading-label\}},toc={},data-line={449},caption={[[3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From Strongest Postconditions to DSE},bookmark={3.{\hspace{0.5em}}From Strongest Postconditions to DSE}]{%mdk-data-line={449} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3}.{\hspace{0.5em}}}%mdk-data-line={449} {}From Strongest Postconditions to DSE}\begin{mdP}[data-line={451}]% %mdk-data-line={451} {}The previous section showed how symbolic expressions can be computed via a set of instrumented types, where the expressions are computed as a side-effect of the execution of program operations. This section shows how these symbolic expressions can be used to form a %mdk-data-line={455} {}\mdEm{path-condition}%mdk-data-line={455} {} (which then can be compiled into a logic formula and passed to an automated theorem prover to find new inputs to drive a program%mdk-data-line={457} {}{'}%mdk-data-line={457} {}s execution along new paths). We derive a %mdk-data-line={457} {}\mdEm{path-condition}%mdk-data-line={457} {} directly from the %mdk-data-line={458} {}\mdEm{strongest postcondition}%mdk-data-line={458} {} (symbolic) semantics of our programming language, refining it to model the basic operations of an interpreter.% \end{mdP}% \mdHxxx[id=sec-strongest-postconditions,label={[3.1]\{.heading-label\}},toc={},data-line={462},caption={[[3.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Strongest Postconditions},bookmark={3.1.{\hspace{0.5em}}Strongest Postconditions}]{%mdk-data-line={462} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.1}.{\hspace{0.5em}}}%mdk-data-line={462} {}Strongest Postconditions}\begin{mdP}[class={para-continue},data-line={464}]% %mdk-data-line={464} {}The strongest postcondition transformer %mdk-data-line={464} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={464} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{dijkstra76}{}{\mdSpan[class={bibitem-label}]{6}}]}%mdk-data-line={464} {} is defined over a predicate %mdk-data-line={465} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={465} {} representing a set of pre-states and a statement %mdk-data-line={466} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={466} {} from our language. The transformer %mdk-data-line={466} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP(P,S)$}%mdk-data-line={466} {} yields a predicate %mdk-data-line={467} {}\mdSpan[class={math-inline},elem={math-inline}]{$Q$}%mdk-data-line={467} {} such that for any state %mdk-data-line={467} {}\mdSpan[class={math-inline},elem={math-inline}]{$s$}%mdk-data-line={467} {} satisfying predicate %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={468} {}, the execution of statement %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={468} {} from state %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$s$}%mdk-data-line={468} {}, if it does not go wrong or diverge, yields a state %mdk-data-line={469} {}\mdSpan[class={math-inline},elem={math-inline}]{$s'$}%mdk-data-line={469} {} satisfying predicate %mdk-data-line={469} {}\mdSpan[class={math-inline},elem={math-inline}]{$Q$}%mdk-data-line={469} {}. The strongest postcondition for the statements in our language is defined by the following five rules:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={473}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={474} \begin{mdMathprearray}%mdk 1.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\exists \mathid{y}\mdMathspace{1}.\mdMathspace{1}(\mathid{x}\mdMathspace{1}=\mdMathspace{1}\mathid{E}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}])\mdMathspace{1}\wedge \mathid{P}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}]\mdMathbr{} 2.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathkw{skip})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{P}\mdMathbr{} 3.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathid{S}_{1};\mathid{S}_{2})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{SP}(\mathid{SP}(\mathid{P},\mathid{S}_{1}),\mdMathspace{1}\mathid{S}_{2})\mdMathbr{} 4.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{} \mdMathindent{4}&\mdMathspace{7}\mathid{SP}(\mathid{P}\wedge \mathid{E},\mathid{S}_1)\mdMathspace{1}\vee \mathid{SP}(\mathid{P}\mdMathspace{1}\wedge \neg \mathid{E},\mathid{S}_2)\mdMathbr{} 5.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{} \mdMathindent{4}&\mdMathspace{6}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S};\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end}\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mathkw{end}) \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={483}]% %mdk-data-line={483} {}Rule (1) defines the strongest postcondition for the assignment statement. The assignment is modeled logically by the equality %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$x = E$}%mdk-data-line={485} {} where any free occurrence of %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={485} {} in %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={485} {} is replaced by the existentially quantified variable %mdk-data-line={486} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={486} {}, which represents the value of %mdk-data-line={487} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={487} {} in the pre-state. The same substitution (%mdk-data-line={487} {}\mdSpan[class={math-inline},elem={math-inline}]{$[x \rightarrow y ]$}%mdk-data-line={487} {}) is applied to the pre-state predicate %mdk-data-line={488} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={488} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={490}]% %mdk-data-line={490} {}Rules (2)-(5) define the strongest postcondition for the four control-flow statements. The rules for the %mdk-data-line={491} {}\mdStrong{skip}%mdk-data-line={491} {} statement and sequencing (;) are straightforward. Of particular interest, note that the rule for the %mdk-data-line={493} {}\mdStrong{if-then-else}%mdk-data-line={493} {} statement splits cases on the expression %mdk-data-line={494} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={494} {}. It is here that DSE will choose one of the cases for us, as the concrete execution will evaluate %mdk-data-line={496} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={496} {} either to be true or false. This gives rise to the path-condition (either %mdk-data-line={497} {}\mdSpan[class={math-inline},elem={math-inline}]{$P \wedge E$}%mdk-data-line={497} {} or %mdk-data-line={497} {}\mdSpan[class={math-inline},elem={math-inline}]{$P \wedge \neg E$}%mdk-data-line={497} {}). The recursive rule for the %mdk-data-line={498} {}\mdStrong{while}%mdk-data-line={498} {} loop unfolds as many times as the expression %mdk-data-line={499} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={499} {} evaluates true, adding to the path-condition.% \end{mdP}% \mdHxxx[id=sp-refined,label={[3.2]\{.heading-label\}},toc={},data-line={501},caption={[[3.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From \$SP\$ to DSE},bookmark={3.2.{\hspace{0.5em}}From \$SP\$ to DSE}]{%mdk-data-line={501} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.2}.{\hspace{0.5em}}}%mdk-data-line={501} {}From %mdk-data-line={501} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={501} {} to DSE}\begin{mdP}[data-line={503}]% %mdk-data-line={503} {}Assume that an execution begins with the assignment of initial values %mdk-data-line={503} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_1 \ldots c_k$}%mdk-data-line={503} {} to the program %mdk-data-line={503} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={503} {}{'}%mdk-data-line={503} {}s inputs %mdk-data-line={504} {}\mdSpan[class={math-inline},elem={math-inline}]{$V = \{ v_1 : T_1 \ldots v_k : T_k \}$}%mdk-data-line={504} {}. To seed symbolic execution, some of the types %mdk-data-line={504} {}\mdSpan[class={math-inline},elem={math-inline}]{$T_i$}%mdk-data-line={504} {} are replaced by symbolic counterparts %mdk-data-line={505} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'_i$}%mdk-data-line={505} {}, in which case %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_i$}%mdk-data-line={506} {} is initialized to the value %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$sc_i = T'_i (c_i,SC(v_i))$}%mdk-data-line={506} {} instead of the value %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={506} {}, where %mdk-data-line={507} {}\mdSpan[class={math-inline},elem={math-inline}]{$SC(v_i)$}%mdk-data-line={507} {} is the symbolic constant representing the initial value of variable %mdk-data-line={507} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_i$}%mdk-data-line={507} {}. The symbolic constant %mdk-data-line={508} {}\mdSpan[class={math-inline},elem={math-inline}]{$SC(v_i)$}%mdk-data-line={508} {} can be thought of as representing any value of type %mdk-data-line={509} {}\mdSpan[class={math-inline},elem={math-inline}]{$T_i$}%mdk-data-line={509} {}, which includes the value %mdk-data-line={509} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={509} {}.%mdk-data-line={509} {} %mdk-data-line={509} {}% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={511}]% %mdk-data-line={511} {}Let %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_s$}%mdk-data-line={511} {} and %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_c$}%mdk-data-line={511} {} partition the variables of %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V$}%mdk-data-line={511} {} into those variables that are treated symbolically (%mdk-data-line={512} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_s$}%mdk-data-line={512} {}) and those that are treated concretely (%mdk-data-line={513} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_c$}%mdk-data-line={513} {}). The initial state of the program is characterized by the formula% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(1)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={515}]% %mdk-data-line={515} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(1)}}%mdk-data-line={515} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={516}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={516} Init = (\bigwedge_{v_i \in V_s} v_i = sc_i) ~\wedge~ (~\bigwedge_{v_i \in V_c} v_i = c_i) \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={519}]% %mdk-data-line={519} {}Thus, we see that the initial value of every input variable is characterized by a symbolic constant %mdk-data-line={520} {}\mdSpan[class={math-inline},elem={math-inline}]{$sc_i$}%mdk-data-line={520} {} or constant %mdk-data-line={520} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={520} {}. We assume that every non-input variable in the program is initialized before being used.% \end{mdP}% \begin{mdP}[class={indent},data-line={523}]% %mdk-data-line={523} {}The strongest postcondition is formulated to deal with open programs, programs in which some variables are used before being assigned to. This surfaces in Rule (1) for assignment, which uses existential quantification to refer to the value of variable %mdk-data-line={526} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={526} {} in the pre-state.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={528}]% %mdk-data-line={528} {}By construction, we have that every variable is defined before being used. This means that the precondition %mdk-data-line={530} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={530} {} can be reformulated as a pair %mdk-data-line={530} {}\mdSpan[class={math-inline},elem={math-inline}]{$<\sigma,P_c>$}%mdk-data-line={530} {}, where %mdk-data-line={531} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={531} {} is a store mapping variables to values and %mdk-data-line={531} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c$}%mdk-data-line={531} {} is the path-condition, a list of symbolic expressions (predicates) corresponding to the expressions %mdk-data-line={534} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={534} {} evaluated in the context of an %mdk-data-line={534} {}\mdStrong{if-then-else}%mdk-data-line={534} {} statement. Initially, we have that :% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(2)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={537}]% %mdk-data-line={537} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(2)}}%mdk-data-line={537} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={538}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={538} \sigma = \{ (v_i,sc_i) | v_i \in V_s \} \cup \{ (v_i,c_i) | v_i \in V_c \} \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={para-continue},data-line={541}]% %mdk-data-line={541} {}representing the initial condition %mdk-data-line={541} {}\mdSpan[class={math-inline},elem={math-inline}]{$Init$}%mdk-data-line={541} {}, and %mdk-data-line={541} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c = []$}%mdk-data-line={541} {}, the empty list. We use %mdk-data-line={542} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma'$}%mdk-data-line={542} {} to refer to the formula that the store %mdk-data-line={542} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={542} {} induces:% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(3)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={545}]% %mdk-data-line={545} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(3)}}%mdk-data-line={545} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={546}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={546} \sigma ' = \bigwedge_{(v,V) \in \sigma} (v = V) \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={549}]% %mdk-data-line={549} {}Thus, the pair %mdk-data-line={549} {}\mdSpan[class={math-inline},elem={math-inline}]{$<\sigma,P_c>$}%mdk-data-line={549} {} represents the predicate %mdk-data-line={550} {}\mdSpan[class={math-inline},elem={math-inline}]{$P = \sigma' \wedge (\bigwedge_{c \in P_c} c)$}%mdk-data-line={550} {}. A store %mdk-data-line={551} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={551} {} supports two operations: %mdk-data-line={551} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[x]$}%mdk-data-line={551} {} which denotes the value that %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={552} {} maps to under %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={552} {}; %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[x \mapsto V]$}%mdk-data-line={552} {}, which produces a new store in which %mdk-data-line={553} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={553} {} maps to value %mdk-data-line={553} {}\mdSpan[class={math-inline},elem={math-inline}]{$V$}%mdk-data-line={553} {} and is everywhere else the same as %mdk-data-line={554} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={554} {}.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={556}]% %mdk-data-line={556} {}Now, we can redefine strongest postcondition for assignment to eliminate the use of existential quantification and model the operation of an interpreter, by separating out the notion of the store:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={560}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={561} \begin{mdMathprearray}%mdk 1.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}<\sigma[\mathid{x}\mdMathspace{1}\mapsto \mathid{eval}(\sigma,\mathid{E})],\mdMathspace{1}\mathid{P}_\mathid{c}>\\ \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={564}]% %mdk-data-line={564} {}where %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$eval(\sigma,E)$}%mdk-data-line={564} {} evaluates expression %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={564} {} under the store %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={564} {} (where every occurrence of a free variable %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$v$}%mdk-data-line={566} {} in %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={566} {} is replaced by the value %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[v]$}%mdk-data-line={566} {}). This is the standard substitution rule of a standard operational semantics.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={569}]% %mdk-data-line={569} {}We also redefine the rule for the %mdk-data-line={569} {}\mdStrong{if-then-else}%mdk-data-line={569} {} statement so that it chooses which branch to take and appends the appropriate symbolic expression (predicate) to the path-condition %mdk-data-line={571} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c$}%mdk-data-line={571} {}:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={573}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={574} \begin{mdMathprearray}%mdk 4.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{2}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{let}\mdMathspace{1}\mathid{choice}\mdMathspace{1}=\mdMathspace{1}\mathid{eval}(\sigma,\mathid{E})\mdMathspace{1}\mathkw{in}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{if}\mdMathspace{1}\mathid{choice}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_1)\mdMathspace{1}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{else}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\neg \mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_2) \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={580}]% %mdk-data-line={580} {}The other strongest postcondition rules remain unchanged.% \end{mdP}% \mdHxxx[id=sec-summing-it-up,label={[3.3]\{.heading-label\}},toc={},data-line={582},caption={[[3.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Summing it up},bookmark={3.3.{\hspace{0.5em}}Summing it up}]{%mdk-data-line={582} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.3}.{\hspace{0.5em}}}%mdk-data-line={582} {}Summing it up}\begin{mdP}[data-line={584}]% %mdk-data-line={584} {}We have shown how the symbolic predicate transformer %mdk-data-line={584} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={584} {} can be refined into a symbolic interpreter operating over the symbolic types defined in the previous section. In the case when every input variable is symbolic and every operator is redefined, the path-condition is equivalent to the %mdk-data-line={589} {}\mdEm{strongest postcondition}%mdk-data-line={589} {} of the execution path %mdk-data-line={589} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={589} {}. This guarantees that the path-condition for %mdk-data-line={590} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={590} {} is %mdk-data-line={590} {}\mdEm{sound}%mdk-data-line={590} {}. In the case where a subset of the input variables are symbolic and/or not all operators are redefined, the path-condition of %mdk-data-line={592} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={592} {} is not guaranteed to be sound. We leave it as an exercise to the reader to establish sufficient conditions under which the use of concrete values in place of symbolic expressions is guaranteed to result in sound path-conditions.% \end{mdP}% \begin{mdP}[class={indent},data-line={598}]% %mdk-data-line={598} {}This section does not address the compilation of a symbolic expression to the (logic) language of an underlying ATP, nor the lifting of a satisfying assignment to a formula back to the level of the source language. This is best done for a particular source language and ATP, as detailed in the next section.% \end{mdP}% \mdHxx[id=sec-impl,label={[4]\{.heading-label\}},toc={},data-line={605},caption={[[4]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Architecture of PyExZ3},bookmark={4.{\hspace{0.5em}}Architecture of PyExZ3}]{%mdk-data-line={605} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4}.{\hspace{0.5em}}}%mdk-data-line={605} {}Architecture of PyExZ3}\begin{mdP}[data-line={607}]% %mdk-data-line={607} {}In this section we present the high-level architecture of a simple DSE tool for the Python language, written in Python, called%mdk-data-line={608} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={608} {}. Figure%mdk-data-line={609} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-arch}{}{\mdSpan[class={figure-label}]{6}}%mdk-data-line={609} {} shows the class diagram (dashed edges are %mdk-data-line={610} {}{\textquotedblleft}has-a{\textquotedblright}%mdk-data-line={610} {} relationships; solid edges are %mdk-data-line={611} {}{\textquotedblleft}is-a{\textquotedblright}%mdk-data-line={611} {} relationships) of the tool.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-arch,label={[6]\{.figure-label\}},elem={figure},toc-line={[6]\{.figure-label\}. Classes in PyExZ3},toc={tof},float-env={figure},float-name={Figure},caption={Classes in PyExZ3},page-align={here},data-line={613}]% \begin{mdP}[data-line={614}]% %mdk-data-line={614} {}\mdImg[width={1.00\linewidth},data-linkid={arch}]{arch.png}%mdk-data-line={614} {}% \end{mdP}% \mdHr[class={figureline,madoko},data-line={615}]{}\begin{mdDiv}[data-line={616}]% %mdk-data-line={616} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{6}.} }Classes in PyExZ3}%mdk-data-line={616} {}% \end{mdDiv}%% \end{mdDiv}% \mdHxxx[id=sec-loading-the-code-under-test,label={[4.1]\{.heading-label\}},toc={},data-line={619},caption={[[4.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Loading the code under test},bookmark={4.1.{\hspace{0.5em}}Loading the code under test}]{%mdk-data-line={619} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.1}.{\hspace{0.5em}}}%mdk-data-line={619} {}Loading the code under test}\begin{mdP}[data-line={621}]% %mdk-data-line={621} {}The %mdk-data-line={621} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Loader}}%mdk-data-line={621} {} class takes as input the name of a Python file (e.g., %mdk-data-line={621} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={621} {}) to import. The loader expects to find a function named %mdk-data-line={623} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={623} {} inside the file %mdk-data-line={623} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={623} {}, which will serve as the starting point for symbolic execution. The %mdk-data-line={624} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={624} {} class wraps this starting point. By default, each parameter to %mdk-data-line={625} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={625} {} is a %mdk-data-line={626} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={626} {} unless there is decorator %mdk-data-line={626} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Python}{@}\mdToken{Identifier,Python}{symbolic}}%mdk-data-line={626} {} specifying the type to use for a particular argument.% \end{mdP}% \begin{mdP}[class={indent},data-line={629}]% %mdk-data-line={629} {}The loader provides the capability to reload the module %mdk-data-line={630} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={630} {} so that the function %mdk-data-line={630} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={630} {} can be reexecuted within the same process from the same initial state with different inputs (see the class %mdk-data-line={632} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={632} {}) via the %mdk-data-line={633} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={633} {} class.% \end{mdP}% \begin{mdP}[class={indent},data-line={635}]% %mdk-data-line={635} {}Finally, the loader looks for specially named functions %mdk-data-line={635} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result}}%mdk-data-line={635} {} (%mdk-data-line={636} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result\_set}}%mdk-data-line={636} {}) in file %mdk-data-line={636} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={636} {} to use as a test oracle after the path exploration (by %mdk-data-line={637} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={637} {}) has completed. These functions are expected to return a list of values to check against the list of return values collected from the executions of the %mdk-data-line={640} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={640} {} function. The presence of the function %mdk-data-line={641} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result}}%mdk-data-line={641} {} (%mdk-data-line={641} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result\_set}}%mdk-data-line={641} {}) yields a comparison of the two lists as bags (sets). We use such weaker tests, rather than list equality, because the order in which paths are explored by the %mdk-data-line={644} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={644} {} can easily change due to small differences in the input programs.% \end{mdP}% \mdHxxx[id=sec-symbolic-types,label={[4.2]\{.heading-label\}},toc={},data-line={647},caption={[[4.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Symbolic types},bookmark={4.2.{\hspace{0.5em}}Symbolic types}]{%mdk-data-line={647} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.2}.{\hspace{0.5em}}}%mdk-data-line={647} {}Symbolic types}\begin{mdP}[data-line={649}]% %mdk-data-line={649} {}Python supports multiple inheritance and, more importantly, allows user-defined classes to inherit from its built-in types (such as %mdk-data-line={651} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={651} {} and %mdk-data-line={651} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={651} {}). We use these two features two implement symbolic versions of Python objects and integers, following the instrumented type approach defined in Section%mdk-data-line={654} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={654} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={656}]% %mdk-data-line={656} {}The abstract class %mdk-data-line={656} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={656} {} contains the symbolic expression tree and provides basic functions for constructing and accessing the tree. This class does double duty, as it is used to represent the (typed) symbolic constants associated with the parameters to the function, as well as the expression trees (per Section%mdk-data-line={660} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={660} {}). Recall that the symbolic constants only appear as leaves of expression trees. This means that the expression tree stored in a %mdk-data-line={662} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={662} {} will have instances of a %mdk-data-line={663} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={663} {} as some of its leaves, namely those leaves representing the symbolic constants. %mdk-data-line={665} {}%mdk-data-line={665} {} The abstract class provides an %mdk-data-line={666} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unwrap}}%mdk-data-line={666} {} method which returns the pair of concrete value and expression tree associated with the %mdk-data-line={668} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={668} {}, as well as a %mdk-data-line={668} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{wrap}}%mdk-data-line={668} {} method that takes a pair of concrete value and expression tree and creates a %mdk-data-line={669} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={669} {} encapsulating them.% \end{mdP}% \begin{mdP}[class={indent},data-line={672}]% %mdk-data-line={672} {}The class %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={672} {} inherits from both %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={672} {} and %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={672} {} and overrides the basic comparison operations (%mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_eq\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_neq\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_lt\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_le\_\_}}%mdk-data-line={673} {}, %mdk-data-line={674} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_gt\_\_}}%mdk-data-line={674} {}, and %mdk-data-line={674} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_ge\_\_}}%mdk-data-line={674} {}). The class %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={675} {} inherits from both %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={675} {} and %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={675} {} and overrides a number of %mdk-data-line={676} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={676} {}{'}%mdk-data-line={676} {}s arithmetic methods (%mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_add\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_sub\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_mul\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_mod\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_floordiv\_}}%mdk-data-line={677} {}) and bitwise methods (%mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_and\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_or\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_xor\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_lshift\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_rshift\_\_}}%mdk-data-line={679} {}).% \end{mdP}% \mdHxxx[id=sec-tracing-control-flow,label={[4.3]\{.heading-label\}},toc={},data-line={682},caption={[[4.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Tracing control-flow},bookmark={4.3.{\hspace{0.5em}}Tracing control-flow}]{%mdk-data-line={682} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.3}.{\hspace{0.5em}}}%mdk-data-line={682} {}Tracing control-flow}\begin{mdP}[data-line={684}]% %mdk-data-line={684} {}As Python interprets a program, it will evaluate expressions, substituting the value of a variable in its place in an expression, applying operators (methods) to parameter values and assigning the return values of methods to variables. Value of type %mdk-data-line={688} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={688} {} will simply flow through this interpretation, without necessitating any change to the program or the interpreter. This takes care of the case of the strongest-postcondition rule for assignment, as elaborated in Section%mdk-data-line={692} {}{\mdNbsp}\mdA[class={localref},target-element={h2}]{sp-refined}{}{\mdSpan[class={heading-label}]{3.2}}%mdk-data-line={692} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={694}]% %mdk-data-line={694} {}The strong-postcondition rule for a conditional test requires a little more work. In Python, any object can be tested in an %mdk-data-line={696} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{if}}%mdk-data-line={696} {} or %mdk-data-line={696} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{while}}%mdk-data-line={696} {} condition or as the operand of a Boolean operation (%mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{and}}%mdk-data-line={697} {}, %mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{or}}%mdk-data-line={697} {}, %mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}}%mdk-data-line={697} {}) The Python base class %mdk-data-line={698} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={698} {} provides a method named %mdk-data-line={698} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_bool\_\_}}%mdk-data-line={698} {} that the Python runtime calls whenever it needs to perform such a conditional test. This hook provides us what we need to trace the conditional control-flow of a Python execution. We override this method in the class %mdk-data-line={702} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={702} {} in order to inform the %mdk-data-line={702} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={702} {} object (defined later) of the symbolic expression for the conditional (as captured by the %mdk-data-line={704} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={704} {} subclass).% \end{mdP}% \begin{mdP}[class={indent},data-line={706}]% %mdk-data-line={706} {}Note that the use of this hook in combination with the tainted types will only trace those conditionals in a Python execution whose values inherit from %mdk-data-line={708} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={708} {}; by definition, %mdk-data-line={709} {}{\textquotedblleft}untainted{\textquotedblright}%mdk-data-line={709} {} conditionals do not depend on symbolic inputs so there is no value in adding them to the path-condition.% \end{mdP}% \mdHxxx[id=sec-recording-path-conditions,label={[4.4]\{.heading-label\}},toc={},data-line={712},caption={[[4.4]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Recording path-conditions},bookmark={4.4.{\hspace{0.5em}}Recording path-conditions}]{%mdk-data-line={712} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.4}.{\hspace{0.5em}}}%mdk-data-line={712} {}Recording path-conditions}\begin{mdP}[data-line={714}]% %mdk-data-line={714} {}A %mdk-data-line={714} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={714} {} records a conditional (more precisely the symbolic expression found in %mdk-data-line={715} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={715} {}) and which way it evaluated in an execution. A %mdk-data-line={716} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={716} {} has a %mdk-data-line={717} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={717} {}, a parent %mdk-data-line={717} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={717} {} and a set of %mdk-data-line={718} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={718} {} children. %mdk-data-line={718} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraints}}%mdk-data-line={718} {} form a tree, where each path starting from the root of the tree represents a path-condition. The tree represents all path-conditions that have been explored so far.% \end{mdP}% \begin{mdP}[class={indent},data-line={723}]% %mdk-data-line={723} {}The class %mdk-data-line={723} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={723} {} has a reference to the root of the tree of %mdk-data-line={724} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={724} {}s and is responsible for installing a new %mdk-data-line={725} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={725} {} in the tree when notified by the overridden %mdk-data-line={726} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_bool\_\_}}%mdk-data-line={726} {} method of %mdk-data-line={726} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={726} {}. %mdk-data-line={727} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={727} {} also tracks whether or not the current execution is following an existing path in the tree and grows the tree as needed. In fact, it actually tracks whether or not the current execution follows a particular %mdk-data-line={731} {}\mdEm{expected path}%mdk-data-line={731} {} in the tree.% \end{mdP}% \begin{mdP}[class={indent},data-line={733}]% %mdk-data-line={733} {}The expected path is the result of the %mdk-data-line={734} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={734} {} picking a constraint %mdk-data-line={734} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={734} {} in the tree, and asking the ATP if the path-condition consisting of the prefix of predicates up to but not including %mdk-data-line={736} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={736} {} in the tree, followed by the negation of %mdk-data-line={737} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={737} {}{'}%mdk-data-line={737} {}s predicate is satisfiable. If the ATP returns %mdk-data-line={738} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={738} {} (with a new input %mdk-data-line={738} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={738} {}), then the assumption is that path-condition prefix is sound (that is, the execution of the program on input %mdk-data-line={740} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={740} {} will follow the prefix).% \end{mdP}% \begin{mdP}[class={indent},data-line={742}]% %mdk-data-line={742} {}However, it is possible for the path-condition to be unsound and for the executed path to diverge early from the expected path, due to the fact that not every operation has a symbolic encoding. The tool simply reports the divergence and continues to process the execution as usual (as a diverging path may lead to some other interesting part of the code).% \end{mdP}% \mdHxxx[id=sec-from-symbolic-types-to-z3,label={[4.5]\{.heading-label\}},toc={},data-line={750},caption={[[4.5]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From symbolic types to Z3},bookmark={4.5.{\hspace{0.5em}}From symbolic types to Z3}]{%mdk-data-line={750} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.5}.{\hspace{0.5em}}}%mdk-data-line={750} {}From symbolic types to Z3}\begin{mdP}[data-line={752}]% %mdk-data-line={752} {}As we have explained DSE, the symbolic expressions are represented at the level of the source language. As detailed later in Section%mdk-data-line={754} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={754} {}, we must translate from the source language to the input language of an automated theorem prover (ATP), in this case%mdk-data-line={756} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={756} {}. This separation of languages is quite useful, as we may have the need to translate a given symbolic expression to the ATP%mdk-data-line={759} {}{'}%mdk-data-line={759} {}s language multiple times, to make use of different features of the underlying ATP. Furthermore, this separation of concerns allows us to easily retarget the DSE tool to a different ATP.% \end{mdP}% \begin{mdP}[class={indent},data-line={765}]% %mdk-data-line={765} {}The base class %mdk-data-line={765} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Expression}}%mdk-data-line={765} {} represents a Z3 formula. The two subclasses %mdk-data-line={766} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={766} {} and %mdk-data-line={766} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3BitVector}}%mdk-data-line={766} {} represent different ways to model arithmetic reasoning about integers in Z3. We will describe the details of these encodings in Section%mdk-data-line={768} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={768} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={770}]% %mdk-data-line={770} {}The class %mdk-data-line={770} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Wrapper}}%mdk-data-line={770} {} is responsible for performing the translation from the source language (Python) to Z3%mdk-data-line={771} {}{'}%mdk-data-line={771} {}s input language, invoking Z3, and lifting a Z3 answer back to the level of Python. The %mdk-data-line={773} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{findCounterexample}}%mdk-data-line={773} {} method does all the work, taking as input a list of %mdk-data-line={774} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={774} {}s (called %mdk-data-line={774} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{assertions}}%mdk-data-line={774} {}) as well as a single %mdk-data-line={775} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={775} {} (called the %mdk-data-line={776} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={776} {}). The %mdk-data-line={776} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{assertions}}%mdk-data-line={776} {} represent a path-condition prefix derived from the %mdk-data-line={777} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={777} {} tree that we wish the next execution to follow, while %mdk-data-line={778} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={778} {} represents the predicate following the prefix in the tree that we will negate.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={781}]% %mdk-data-line={781} {}The method constructs the formula% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(4)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={783}]% %mdk-data-line={783} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(4)}}%mdk-data-line={783} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={784}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={784} (\bigwedge_{a \in asserts} a) \wedge \neg query \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={787}]% %mdk-data-line={787} {}and asks Z3 if it is satisfiable. The method performs a standard syntactic %mdk-data-line={788} {}{\textquotedblleft}cone of influence{\textquotedblright}%mdk-data-line={788} {} (CIF) reduction on the %mdk-data-line={789} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={789} {} with respect to the %mdk-data-line={790} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={790} {} to shrink the size of the formula. For example, if %mdk-data-line={791} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={791} {} is the set of predicates %mdk-data-line={791} {}\mdSpan[class={math-inline},elem={math-inline}]{$\{ (x0) \}$}%mdk-data-line={791} {} and the query is %mdk-data-line={792} {}\mdSpan[class={math-inline},elem={math-inline}]{$(x=0)$}%mdk-data-line={792} {}, then the CIF yields the set %mdk-data-line={793} {}\mdSpan[class={math-inline},elem={math-inline}]{$\{ (x0)$}%mdk-data-line={793} {}, as the variable %mdk-data-line={794} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={794} {} is not in the set of variables (transitively) related to variable %mdk-data-line={795} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={795} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={797}]% %mdk-data-line={797} {}If the formula is satisfiable a model is requested from Z3 and lifted back to Python%mdk-data-line={798} {}{'}%mdk-data-line={798} {}s type universe. Note that because of the CIF reduction, the model may not mention certain input variables, in which case we simply keep their values from the execution from which the %mdk-data-line={801} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={801} {} and %mdk-data-line={801} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={801} {} were derived.% \end{mdP}% \mdHxxx[id=sec-putting-it-all-together,label={[4.6]\{.heading-label\}},toc={},data-line={803},caption={[[4.6]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Putting it all together},bookmark={4.6.{\hspace{0.5em}}Putting it all together}]{%mdk-data-line={803} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.6}.{\hspace{0.5em}}}%mdk-data-line={803} {}Putting it all together}\begin{mdP}[data-line={805}]% %mdk-data-line={805} {}The class %mdk-data-line={805} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={805} {} ties everything together. It kicks off an execution of the Python code under test using %mdk-data-line={806} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={806} {}. As the Python code executes, building symbolic expressions via %mdk-data-line={807} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={807} {} and its subclasses, callbacks to %mdk-data-line={808} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={808} {} create a path-condition, represented by %mdk-data-line={809} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={809} {} and %mdk-data-line={809} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={809} {}. Newly discovered %mdk-data-line={810} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraints}}%mdk-data-line={810} {} are added to the end of a deque maintained by %mdk-data-line={811} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={811} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={813}]% %mdk-data-line={813} {}Given the first seed execution, %mdk-data-line={813} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={813} {} starts the work of exploring paths in a breadth-first fashion. It removes a %mdk-data-line={814} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={814} {} %mdk-data-line={814} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={814} {} from the front of its deque and, if %mdk-data-line={815} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={815} {} has not been already %mdk-data-line={815} {}{\textquotedblleft}processed{\textquotedblright}%mdk-data-line={815} {}, uses %mdk-data-line={816} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Wrapper}}%mdk-data-line={816} {} to find a new input (as discussed in the previous section) where %mdk-data-line={817} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={817} {} is the query (to be negated) and the path to %mdk-data-line={817} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={817} {} in the %mdk-data-line={818} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={818} {} tree forms the assertions.% \end{mdP}% \begin{mdP}[class={indent},data-line={820}]% %mdk-data-line={820} {}A %mdk-data-line={820} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={820} {} %mdk-data-line={820} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={820} {} in the tree is considered %mdk-data-line={820} {}{\textquotedblleft}processed{\textquotedblright}%mdk-data-line={820} {} if an execution has covered %mdk-data-line={821} {}\mdSpan[class={math-inline},elem={math-inline}]{$c'$}%mdk-data-line={821} {}, a sibling of %mdk-data-line={821} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={821} {} in the tree that represents the negation of the predicate associated with %mdk-data-line={822} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={822} {}, or if constraint %mdk-data-line={822} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={822} {} has been removed from the deque.% \end{mdP}% \mdHxx[id=sec-int2z3,label={[5]\{.heading-label\}},toc={},data-line={825},caption={[[5]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From Python Integers to Z3 Arithmetic},bookmark={5.{\hspace{0.5em}}From Python Integers to Z3 Arithmetic}]{%mdk-data-line={825} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{5}.{\hspace{0.5em}}}%mdk-data-line={825} {}From Python Integers to Z3 Arithmetic}\begin{mdP}[data-line={827}]% %mdk-data-line={827} {}In languages such as C and Java, integers are finite-precision, generally limited to the size of a machine word (32 or 64 bits, for example). For such languages, satisfiability of finite-precision integer arithmetic is decidable and can be reduced to Z3%mdk-data-line={830} {}{'}%mdk-data-line={830} {}s theory of bit-vectors, where each arithmetic operation is encoded by a circuit. This translation permits reasoning about non-linear arithmetic problems, such as %mdk-data-line={833} {}\mdSpan[class={math-inline},elem={math-inline}]{$\exists x,y,z : x*z + y \leq (z/y)+5$}%mdk-data-line={833} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={835}]% %mdk-data-line={835} {}Python (3.0) integers, however, are not finite-precision. They are only limited by the size of machine memory. This means, for example, that Python integers don%mdk-data-line={837} {}{'}%mdk-data-line={837} {}t overflow or underflow. It also means that we can%mdk-data-line={838} {}{'}%mdk-data-line={838} {}t hope to decide algorithmically whether or not a given equation over integer variables has a solution in general. Hilbert%mdk-data-line={839} {}{'}%mdk-data-line={839} {}s famous 10th problem and its solution by Matiyasevich tells us that it is undecidable whether or not a polynomial equation of the form %mdk-data-line={842} {}\mdSpan[class={math-inline},elem={math-inline}]{$p(x_1, \ldots, x_n) = 0$}%mdk-data-line={842} {} with integer coefficients has an solution in the integers.% \end{mdP}% \begin{mdP}[class={indent},data-line={845}]% %mdk-data-line={845} {}This means that we will resort to heuristic approaches in our use of the%mdk-data-line={846} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={846} {} ATP. The special case of linear integer arithmetic (LIA) is decidable and supported by Z3. In order to deal with non-linear operations, we use uninterpreted functions (UF). Thus, if Z3 returns %mdk-data-line={849} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={849} {} we know that there is no solution, but if the Z3 %mdk-data-line={850} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={850} {}, we must treat the answer as a %mdk-data-line={850} {}{\textquotedblleft}don{'}t know{\textquotedblright}%mdk-data-line={850} {}. The class %mdk-data-line={851} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={851} {} is used to translate a symbolic expression into the theory LIA+UF and check for unsatisfiability. We leave it as an implementation exercise to check if a symbolic expression can be converted to LIA (without the use of UF) in order to make use of %mdk-data-line={855} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={855} {} answers from the LIA solver.% \end{mdP}% \begin{mdP}[class={indent},data-line={857}]% %mdk-data-line={857} {}If the translation to %mdk-data-line={857} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={857} {} does not return %mdk-data-line={857} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={857} {}, we use Z3%mdk-data-line={858} {}{'}%mdk-data-line={858} {}s bit-vector decision procedure (via the class %mdk-data-line={859} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3BitVector}}%mdk-data-line={859} {}) to heuristically try to find satisfiable answers, even in the presence of non-linear arithmetic. We start with bit-vectors of size %mdk-data-line={861} {}\mdSpan[class={math-inline},elem={math-inline}]{$N=32$}%mdk-data-line={861} {} and %mdk-data-line={861} {}\mdEm{bound}%mdk-data-line={861} {} the values of the symbolic constants to fit within 8 bits in order to find satisfiable solutions with small values. Also, because Python integers do not overflow/underflow, the bound helps us reserve space in the bit-vector to allow the results of operations to exceed the bound while not overflowing the bit-vector. As long as Z3 returns %mdk-data-line={867} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={867} {} we increase the bound. If the bound reaches %mdk-data-line={868} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={868} {}, we increase %mdk-data-line={868} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={868} {} by 8 bits, leaving the bound where it is and continue.% \end{mdP}% \begin{mdP}[class={indent},data-line={871}]% %mdk-data-line={871} {}If Z3 returns %mdk-data-line={872} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={872} {}, it may be the case that Z3 found a solution that involved overflow in the bit-vector world of arithmetic (modulo %mdk-data-line={874} {}\mdSpan[class={math-inline},elem={math-inline}]{$2^N-1$}%mdk-data-line={874} {}). Therefore, the solution is validated back in the Python world by evaluating the formula under that solution using Python semantics. If the formula does not evaluate to the same value in both worlds, then we increase %mdk-data-line={879} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={879} {} by 8 bits (to create a gap between the bound and %mdk-data-line={880} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={880} {}) and continue to search for a solution.% \end{mdP}% \begin{mdP}[class={indent},data-line={883}]% %mdk-data-line={883} {}The process terminates when we find a valid satisfying solution or %mdk-data-line={884} {}\mdSpan[class={math-inline},elem={math-inline}]{$N=64$}%mdk-data-line={884} {} and the bound reaches 64 (in which case, we return %mdk-data-line={884} {}{\textquotedblleft}don{'}t know{\textquotedblright}%mdk-data-line={884} {}).% \end{mdP}% \mdHxx[id=sec-extensions,label={[6]\{.heading-label\}},toc={},data-line={886},caption={[[6]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Extensions},bookmark={6.{\hspace{0.5em}}Extensions}]{%mdk-data-line={886} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{6}.{\hspace{0.5em}}}%mdk-data-line={886} {}Extensions}\begin{mdP}[data-line={888}]% %mdk-data-line={888} {}We have presented the basics of dynamic symbolic execution (for Python). A more thorough treatment would deal with other data types besides integers, such as Python dictionaries, strings and lists, each of which presents their own challenges for symbolic reasoning. There are many other interesting challenges in DSE, such as dealing with user-defined classes (rather than built-in types as done here) and multi-threaded execution.% \end{mdP}% \mdHxx[id=sec-acknowledgements,label={[7]\{.heading-label\}},toc={},data-line={897},caption={[[7]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Acknowledgements},bookmark={7.{\hspace{0.5em}}Acknowledgements}]{%mdk-data-line={897} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{7}.{\hspace{0.5em}}}%mdk-data-line={897} {}Acknowledgements}\begin{mdP}[data-line={899}]% %mdk-data-line={899} {}Many thanks to the students of the 2014 Marktoberdorf Summer School on Dependable Software Systems Engineering for their questions and feedback about the first author%mdk-data-line={901} {}{'}%mdk-data-line={901} {}s lectures on dynamic symbolic execution. The following students of the summer school helpfully provided tests for the%mdk-data-line={903} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={903} {} tool: Daniel Darvas, Damien Rusinek, Christian Dehnert and Thomas Pani. Thanks also to Peter Chapman for his contributions.% \end{mdP}% \mdHxx[id=sec-references,label={8},toc={},data-line={963},caption={References},bookmark={References}]{%mdk-data-line={963} {}References}\begin{mdBibliography}[class={bibliography,bib-numeric},elem={bibliography},bibstyle={plainnat},bibdata={dse},caption={14},data-line={964;out{\textbackslash}DSE-bib.bbl:2}]% \begin{mdBibitem}[class={bibitem},id=cadare05,label={[1]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar and Engler(2005)},caption={Cristian Cadar and Dawson{\textbackslash} R. Engler. \\Execution generated test cases: How to make systems code crash itself. \\In \_Proceedings of 12th International SPIN Workshop\_{\textbackslash}/, pages 2--23, 2005.},searchterm={Cristian+Cadar+Dawson+Engler+Execution+generated+test+cases+make+systems+code+crash+itself+\_Proceedings+International+SPIN+Workshop\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:5}]% %mdk-data-line={964;out\DSE-bib.bbl:6} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{1}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:6} {}Cristian Cadar and Dawson%mdk-data-line={964;out\DSE-bib.bbl:6} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:6} {}R. Engler. %mdk-data-line={964;out\DSE-bib.bbl:7} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:7} {} Execution generated test cases: How to make systems code crash itself. %mdk-data-line={964;out\DSE-bib.bbl:9} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:9} {} In %mdk-data-line={964;out\DSE-bib.bbl:9} {}\mdEm{Proceedings of 12th International SPIN Workshop}%mdk-data-line={964;out\DSE-bib.bbl:9} {}%mdk-data-line={964;out\DSE-bib.bbl:9} {}, pages 2%mdk-data-line={964;out\DSE-bib.bbl:10} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:10} {}23, 2005.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=cadars13,label={[2]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar and Sen(2013)},caption={Cristian Cadar and Koushik Sen. \\Symbolic execution for software testing: three decades later.},searchterm={Symbolic+execution+software+testing+three+decades+later++Cristian+Cadar+Koushik+},data-line={964;out{\textbackslash}DSE-bib.bbl:13}]% %mdk-data-line={964;out\DSE-bib.bbl:14} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{2}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:14} {}Cristian Cadar and Koushik Sen. %mdk-data-line={964;out\DSE-bib.bbl:15} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:15} {} Symbolic execution for software testing: three decades later. %mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} %mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:16} {}%mdk-data-line={964;out\DSE-bib.bbl:16} {}, 56%mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} (2):%mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} 82%mdk-data-line={964;out\DSE-bib.bbl:16} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:16} {}90, 2013.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=cadargpde06,label={[3]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar et{\textbackslash} al.(2006)Cadar, Ganesh, Pawlowski, Dill, and\\ Engler},caption={Cristian Cadar, Vijay Ganesh, Peter{\textbackslash} M. Pawlowski, David{\textbackslash} L. Dill, and Dawson{\textbackslash} R. Engler. \\EXE: automatically generating inputs of death. \\In \_Proceedings of the 13th ACM Conference on Computer and Communications Security\_{\textbackslash}/, pages 322--335, 2006.},searchterm={Cristian+Cadar+Vijay+Ganesh+Peter+Pawlowski+David+Dill+Dawson+Engler+automatically+generating+inputs+death+\_Proceedings+Conference+Computer+Communications+Security\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:20}]% %mdk-data-line={964;out\DSE-bib.bbl:21} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{3}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:21} {}Cristian Cadar, Vijay Ganesh, Peter%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}M. Pawlowski, David%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}L. Dill, and Dawson%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}R. Engler. %mdk-data-line={964;out\DSE-bib.bbl:23} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:23} {} EXE: automatically generating inputs of death. %mdk-data-line={964;out\DSE-bib.bbl:24} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:24} {} In %mdk-data-line={964;out\DSE-bib.bbl:24} {}\mdEm{Proceedings of the 13th ACM Conference on Computer and Communications Security}%mdk-data-line={964;out\DSE-bib.bbl:25} {}%mdk-data-line={964;out\DSE-bib.bbl:25} {}, pages 322%mdk-data-line={964;out\DSE-bib.bbl:25} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:25} {}335, 2006.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=clarke76,label={[4]\{.bibitem-label\}},elem={bibitem},cite-label={Clarke(1976)},caption={Lori{\textbackslash} A. Clarke. \\A system to generate test data and symbolically execute programs.},searchterm={+system+generate+test+data+symbolically+execute+programs++Lori+Clarke+},data-line={964;out{\textbackslash}DSE-bib.bbl:28}]% %mdk-data-line={964;out\DSE-bib.bbl:29} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{4}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:29} {}Lori%mdk-data-line={964;out\DSE-bib.bbl:29} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:29} {}A. Clarke. %mdk-data-line={964;out\DSE-bib.bbl:30} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:30} {} A system to generate test data and symbolically execute programs. %mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:31} {} %mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdEm{IEEE Transactions on Software Engineering}%mdk-data-line={964;out\DSE-bib.bbl:31} {}%mdk-data-line={964;out\DSE-bib.bbl:31} {}, 2%mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:31} {} (3):%mdk-data-line={964;out\DSE-bib.bbl:32} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:32} {} 215%mdk-data-line={964;out\DSE-bib.bbl:32} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:32} {}222, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=demourab08,label={[5]\{.bibitem-label\}},elem={bibitem},cite-label={de{\textbackslash} Moura and Bj{\o}rner(2008)},caption={Leonardo{\textbackslash} Mendon{\c{c}}a de{\textbackslash} Moura and Nikolaj Bj{\o}rner. \\Z3: an efficient SMT solver.},searchterm={+efficient+solver++Leonardo+Mendon+Moura+Nikolaj+rner+},data-line={964;out{\textbackslash}DSE-bib.bbl:35}]% %mdk-data-line={964;out\DSE-bib.bbl:36} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{5}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Leonardo%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Mendon%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\c{c}}%mdk-data-line={964;out\DSE-bib.bbl:36} {}a de%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Moura and Nikolaj Bj%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\o}%mdk-data-line={964;out\DSE-bib.bbl:36} {}rner. %mdk-data-line={964;out\DSE-bib.bbl:37} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:37} {} Z3: an efficient SMT solver. %mdk-data-line={964;out\DSE-bib.bbl:38} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:38} {} In %mdk-data-line={964;out\DSE-bib.bbl:38} {}\mdEm{Proceedings of the 14th International Conference of Tools and Algorithms for the Construction and Analysis of Systems}%mdk-data-line={964;out\DSE-bib.bbl:39} {}%mdk-data-line={964;out\DSE-bib.bbl:39} {}, pages 337%mdk-data-line={964;out\DSE-bib.bbl:39} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:39} {}340, 2008.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=dijkstra76,label={[6]\{.bibitem-label\}},elem={bibitem},cite-label={Dijkstra(1976)},caption={Edsger{\textbackslash} W. Dijkstra. \\\_A Discipline of Programming\_{\textbackslash}/.},searchterm={+Discipline+Programming\_++Edsger+Dijkstra+},data-line={964;out{\textbackslash}DSE-bib.bbl:43}]% %mdk-data-line={964;out\DSE-bib.bbl:44} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{6}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:44} {}Edsger%mdk-data-line={964;out\DSE-bib.bbl:44} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:44} {}W. Dijkstra. %mdk-data-line={964;out\DSE-bib.bbl:45} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:45} {} %mdk-data-line={964;out\DSE-bib.bbl:45} {}\mdEm{A Discipline of Programming}%mdk-data-line={964;out\DSE-bib.bbl:45} {}%mdk-data-line={964;out\DSE-bib.bbl:45} {}. %mdk-data-line={964;out\DSE-bib.bbl:46} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:46} {} Prentice-Hall, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroid11,label={[7]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid(2011)},caption={Patrice Godefroid. \\Higher-order test generation.},searchterm={Higher+order+test+generation++Patrice+Godefroid+},data-line={964;out{\textbackslash}DSE-bib.bbl:49}]% %mdk-data-line={964;out\DSE-bib.bbl:50} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{7}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:50} {}Patrice Godefroid. %mdk-data-line={964;out\DSE-bib.bbl:51} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:51} {} Higher-order test generation. %mdk-data-line={964;out\DSE-bib.bbl:52} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:52} {} In %mdk-data-line={964;out\DSE-bib.bbl:52} {}\mdEm{Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation}%mdk-data-line={964;out\DSE-bib.bbl:53} {}%mdk-data-line={964;out\DSE-bib.bbl:53} {}, pages 258%mdk-data-line={964;out\DSE-bib.bbl:53} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:53} {}269, 2011.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroidks05,label={[8]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid et{\textbackslash} al.(2005)Godefroid, Klarlund, and Sen},caption={Patrice Godefroid, Nils Klarlund, and Koushik Sen. \\DART: directed automated random testing.},searchterm={DART+directed+automated+random+testing++Patrice+Godefroid+Nils+Klarlund+Koushik+},data-line={964;out{\textbackslash}DSE-bib.bbl:56}]% %mdk-data-line={964;out\DSE-bib.bbl:57} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{8}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:57} {}Patrice Godefroid, Nils Klarlund, and Koushik Sen. %mdk-data-line={964;out\DSE-bib.bbl:58} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:58} {} DART: directed automated random testing. %mdk-data-line={964;out\DSE-bib.bbl:59} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:59} {} In %mdk-data-line={964;out\DSE-bib.bbl:59} {}\mdEm{Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation}%mdk-data-line={964;out\DSE-bib.bbl:60} {}%mdk-data-line={964;out\DSE-bib.bbl:60} {}, pages 213%mdk-data-line={964;out\DSE-bib.bbl:60} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:60} {}223, 2005.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroidlm12,label={[9]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid et{\textbackslash} al.(2012)Godefroid, Levin, and Molnar},caption={Patrice Godefroid, Michael{\textbackslash} Y. Levin, and David{\textbackslash} A. Molnar. \\SAGE: whitebox fuzzing for security testing.},searchterm={SAGE+whitebox+fuzzing+security+testing++Patrice+Godefroid+Michael+Levin+David+Molnar+},data-line={964;out{\textbackslash}DSE-bib.bbl:63}]% %mdk-data-line={964;out\DSE-bib.bbl:64} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{9}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:64} {}Patrice Godefroid, Michael%mdk-data-line={964;out\DSE-bib.bbl:64} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:64} {}Y. Levin, and David%mdk-data-line={964;out\DSE-bib.bbl:64} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:64} {}A. Molnar. %mdk-data-line={964;out\DSE-bib.bbl:65} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:65} {} SAGE: whitebox fuzzing for security testing. %mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} %mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:66} {}%mdk-data-line={964;out\DSE-bib.bbl:66} {}, 55%mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} (3):%mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} 40%mdk-data-line={964;out\DSE-bib.bbl:66} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:66} {}44, 2012.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=gupta00,label={[10]\{.bibitem-label\}},elem={bibitem},cite-label={Gupta et{\textbackslash} al.(2000)Gupta, Mathur, and Soffa},caption={Neelam Gupta, Aditya{\textbackslash} P. Mathur, and Mary{\textbackslash} Lou Soffa. \\Generating test data for branch coverage.},searchterm={Generating+test+data+branch+coverage++Neelam+Gupta+Aditya+Mathur+Mary+Soffa+},data-line={964;out{\textbackslash}DSE-bib.bbl:70}]% %mdk-data-line={964;out\DSE-bib.bbl:71} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{10}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:71} {}Neelam Gupta, Aditya%mdk-data-line={964;out\DSE-bib.bbl:71} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:71} {}P. Mathur, and Mary%mdk-data-line={964;out\DSE-bib.bbl:71} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:71} {}Lou Soffa. %mdk-data-line={964;out\DSE-bib.bbl:72} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:72} {} Generating test data for branch coverage. %mdk-data-line={964;out\DSE-bib.bbl:73} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:73} {} In %mdk-data-line={964;out\DSE-bib.bbl:73} {}\mdEm{Proceedings of the Automate Software Engineering Conference}%mdk-data-line={964;out\DSE-bib.bbl:74} {}%mdk-data-line={964;out\DSE-bib.bbl:74} {}, pages 219%mdk-data-line={964;out\DSE-bib.bbl:74} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:74} {}228, 2000.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=king76,label={[11]\{.bibitem-label\}},elem={bibitem},cite-label={King(1976)},caption={James{\textbackslash} C. King. \\Symbolic execution and program testing.},searchterm={Symbolic+execution+program+testing++James+King+},data-line={964;out{\textbackslash}DSE-bib.bbl:77}]% %mdk-data-line={964;out\DSE-bib.bbl:78} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{11}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:78} {}James%mdk-data-line={964;out\DSE-bib.bbl:78} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:78} {}C. King. %mdk-data-line={964;out\DSE-bib.bbl:79} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:79} {} Symbolic execution and program testing. %mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} %mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:80} {}%mdk-data-line={964;out\DSE-bib.bbl:80} {}, 19%mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} (7):%mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} 385–394, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=korel90,label={[12]\{.bibitem-label\}},elem={bibitem},cite-label={Korel(1990)},caption={Bogdan Korel. \\Automated software test data generation.},searchterm={Automated+software+test+data+generation++Bogdan+Korel+},data-line={964;out{\textbackslash}DSE-bib.bbl:84}]% %mdk-data-line={964;out\DSE-bib.bbl:85} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{12}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:85} {}Bogdan Korel. %mdk-data-line={964;out\DSE-bib.bbl:86} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:86} {} Automated software test data generation. %mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:87} {} %mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdEm{IEEE Transactions on Software Engineering}%mdk-data-line={964;out\DSE-bib.bbl:87} {}%mdk-data-line={964;out\DSE-bib.bbl:87} {}, 16%mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:87} {} (8):%mdk-data-line={964;out\DSE-bib.bbl:88} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:88} {} 870%mdk-data-line={964;out\DSE-bib.bbl:88} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:88} {}879, 1990.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=korel92,label={[13]\{.bibitem-label\}},elem={bibitem},cite-label={Korel(1992)},caption={Bogdan Korel. \\Dynamic method of software test data generation.},searchterm={Dynamic+method+software+test+data+generation++Bogdan+Korel+},data-line={964;out{\textbackslash}DSE-bib.bbl:91}]% %mdk-data-line={964;out\DSE-bib.bbl:92} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{13}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:92} {}Bogdan Korel. %mdk-data-line={964;out\DSE-bib.bbl:93} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:93} {} Dynamic method of software test data generation. %mdk-data-line={964;out\DSE-bib.bbl:94} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:94} {} %mdk-data-line={964;out\DSE-bib.bbl:94} {}\mdEm{Journal of Software Testing, Verification and Reliability}%mdk-data-line={964;out\DSE-bib.bbl:94} {}%mdk-data-line={964;out\DSE-bib.bbl:94} {}, 2%mdk-data-line={964;out\DSE-bib.bbl:95} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:95} {} (4):%mdk-data-line={964;out\DSE-bib.bbl:95} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:95} {} 203%mdk-data-line={964;out\DSE-bib.bbl:95} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:95} {}213, 1992.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=senacav06,label={[14]\{.bibitem-label\}},elem={bibitem},cite-label={Sen and Agha(2006)},caption={Koushik Sen and Gul Agha. \\CUTE and jcute: Concolic unit testing and explicit path model-checking tools. \\In \_Proceedings of 18th Computer Aided Verification Conference\_{\textbackslash}/, pages 419--423, 2006.},searchterm={Koushik+Agha+CUTE+jcute+Concolic+unit+testing+explicit+path+model+checking+tools+\_Proceedings+Computer+Aided+Verification+Conference\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:98}]% %mdk-data-line={964;out\DSE-bib.bbl:99} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{14}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:99} {}Koushik Sen and Gul Agha. %mdk-data-line={964;out\DSE-bib.bbl:100} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:100} {} CUTE and jcute: Concolic unit testing and explicit path model-checking tools. %mdk-data-line={964;out\DSE-bib.bbl:102} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:102} {} In %mdk-data-line={964;out\DSE-bib.bbl:102} {}\mdEm{Proceedings of 18th Computer Aided Verification Conference}%mdk-data-line={964;out\DSE-bib.bbl:102} {}%mdk-data-line={964;out\DSE-bib.bbl:102} {}, pages 419%mdk-data-line={964;out\DSE-bib.bbl:103} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:103} {}423, 2006.% \end{mdBibitem}%% \end{mdBibliography}% \begin{mdDiv}[class={logomadoko,block},elem={logomadoko},text-align={right},font-size={xx-small},margin-top={4em},data-line={967}]% %mdk-data-line={968} {}Created with{\mdNbsp}\mdA{https://www.madoko.net}{}{Madoko.net}.% \end{mdDiv}% \end{document} ================================================ FILE: marktoberdorf_paper/DSE.html ================================================ Deconstructing Dynamic Symbolic Execution

Deconstructing Dynamic Symbolic Execution

Thomas Ball, Jakub Daniel
Microsoft Research, Charles University

Dynamic symbolic execution (DSE) is a well-known technique for automatically generating tests to achieve higher levels of coverage in a program. Two keys ideas of DSE are to: (1) seed symbolic execution by executing a program on an initial input; (2) using concrete values from the program execution in place of symbolic expressions whenever symbolic reasoning is hard or not desired. In this paper, we describe DSE for a simple core language and then present a minimalist implementation of DSE for Python (in Python) that follows this basic recipe. The code is available at http://www.github.com/thomasjball/pyexz3/ (tagged “v1.0”) and has been designed to make it easy to experiment with and extend.

1. Introduction

Static, path-based symbolic execution explores one control-flow path at a time through a (sequential) program $P$, using an automated theorem prover (ATP) to determine if the current path $p$ is feasible [4, 11]. Ideally, symbolic execution a path $p$ through program $P$ yields a logic formula $\phi_p$ that describes the set of inputs $I$ (possibly empty) to program $P$ such that for any $i \in I$, execution of $P(i)$ follows path $p$.

If the formula $\phi_p$ is unsatisfiable then $I$ is empty and so path $p$ is not feasible; if the formula is satisfiable then $I$ is not empty and so path $p$ is feasible. In this case, a model of $\phi_p$ provides a witness $i \in I$. Thus, an ATP that can provide such models can be used in conjunction with symbolic execution to automatically generate tests to cover paths in a program. Combined with a search strategy, one gets, in the limit, an exhaustive white-box testing procedure, for which there are many applications [2, 3, 9].

The formula $\phi_p$ is called a path-condition of the path $p$. We will see that a given path $p$ can induce many different path-conditions. A path-condition $\psi_p$ for path $p$ is sound if every input assignment satisfying $\psi_p$ defines an execution of program $P$ that follows path $p$ [7]. By its definition, the formula $\phi_p$ is sound and the best representation of $p$ (as for all sound path-conditions $\psi_p$, we have that $\psi_p \implies \phi_p$). In practice, we attempt to compute sound under-approximations of $\phi_p$ such as $\psi_p$. However, we also find it necessary (and useful) to compute unsound path-conditions.

A path-condition can be translated into the input language of an ATP, such as Z3[5], which provides an answer of “unsatisfiable”, “satisfiable” or “unknown”, due to theoretical or practical limitations in automatically deciding satisfiability of various logics. In the case that the ATP is able to prove “satisfiable” we can query it for satisfying model in order to generate test inputs. A path-condition for $p$ can be thought of as function from a program's primary inputs to a boolean output representing whether or not $p$ is executed under a given input. Thus, we are asking the ATP to invert a function when we ask it to decide the satisfiability/unsatisfiability of a path-condition

The static translation of a path $p$ through a program $P$ into the most precise path-condition $\phi_p$ is not a simple task, as programming languages and their semantics are very complex. Completely characterizing the set of inputs $I$ that follow path $p$ means providing a symbolic interpretation of every operation in the language so that the ATP can reason about it. For example, consider a method call in Python. Python's algorithm for method resolution order (see MRO) depends on the inheritance hierarchy of the program, a directed, acyclic graph that can evolve during program execution. Symbolically encoding Python's method resolution order is possible but non-trivial. There are other reasons it is hard or undesirable to symbolically execute various operations, as will detail later.

1.1. Dynamic symbolic execution

Dynamic symbolic execution (DSE) is a form of path-based symbolic execution based on two insights. First, the approach starts by executing program $P$ on some input $i$, seeding the symbolic execution process with a feasible path [10, 12, 13]. Second, DSE uses concrete values from the execution $P(i)$ in place of symbolic expressions whenever symbolic reasoning is not possible or desired [1, 8]. The major benefit of DSE is to simplify the construction of a symbolic execution tool by leveraging the concrete execution behavior (given by actually running the program). As DSE combines both concrete and symbolic reasoning, it also has been called “concolic” execution [14].

  i = an input to program P
while defined(i):
p = path covered by execution P(i)
cond = pathCondition(p)
s = ATP(Not(cond))
i = s.model()

Figure 1. Pseudo-code for dynamic symbolic execution

The pseudo-code of Figure 1 shows the high level process of DSE. The variable i represents an input to program P. Execution of program P on the input i traces a path p, from which a logical formula pathCondition(p) is constructed. Finally, the ATP is called with the negation of the path-condition to find a new input (that hopefully will cover a new path). This pseudo-code ellides a number of details that we will deal with later.

def max2(s,t):
if (s < t):
return t
else:
return s

def max4(a,b,c,d):
return max2(max2(a,b),max2(c,d))

Figure 2. Easy example: computing the maximum of four numbers in Python.

Consider the Python function max4 in Figure 2, which computes the maximum of four numbers via three calls to the function max2. Suppose we execute max4 with values of zero for all four arguments. In this case, the execution path $p$ contains three comparisons (in the order (a < b), (c < d), (a < c)), all of which evaluate false. Thus, the path-condition for path $p$ is (not(a<b) and not(c<d) and not(a < c)). Negating this condition yields ((a<b) or (c<d) or (a<c)). Taking the execution ordering of the three comparisons into account, we derive three expressions from the negated path-condition to generate new inputs that will explore execution prefixes of path $p$ of increasing length:

  • length 0: (a<b)
  • length 1: not (a<b) and (c<d)
  • length 2: not (a<b) and not (c<d) and (a<c)

The purpose of taking execution order into account should be clear, as the comparison (a<c) only executes in the case where (not (a<b) and not (c<d)) holds.

Integer solutions to the above three systems of constraints are:

  • a == 0 and b == 2 and c == 0 and d == 0
  • a == 0 and b == 0 and c == 0 and d == 3
  • a == 0 and b == 0 and c == 2 and d == 0

In the three cases above, we sought solutions that kept as many of the variables as possible equal to the original input (in which all variables are equal to 0). Execution the max4 function on the input corresponding to the first solution produces the path-condition ((a<b) and not(c<d) and not(b < c)), from which we can produce more inputs. For this (loop-free function), there are a finite number of path-conditions. We leave it as an exercise to the reader to enumerate them all.

1.2. Leveraging concrete values in DSE

We now consider several situations where we can make use of concrete values in DSE. In the realm of (unbounded-precision) integer arithmetic (e.g., bignum integer arithmetic, as in Python 3.0 onwards), it is easy to come up with tiny programs that will be very difficult, if not impossible, for any symbolic execution tool to deal with, such as the function fermat3 in Figure 3.

def fermat3(x,y,z):
if (x > 0 and y > 0 and z > 0):
if (x*x*x + y*y*y == z*z*z):
return "Fermat and Wiles were wrong!?!"
return 0

Figure 3. Hard example for symbolic execution

Fermat's Last Theorem, proved by Andrew Wiles in the late 20th century, states that no three positive integers $x$, $y$, and $z$ can satisfy the equation $x^n + y^n = z^n$ for any integer value of $n$ greater than two. The function fermat3 encodes this statement for $n=3$. It is not reasonable to have a computer waste time trying to find a solution that would cause fermat3 to print the string "Fermat and Wiles were wrong!?!". In cases of complex (non-linear) arithmetic operations, such as x*x*x, we might choose to treat the operation concretely.

There are a number of ways to deal with the above issue: one is to recognize all non-linear terms in a symbolic expression and replace them with their concrete counterparts during execution. For the fermat3 example, this would mean that during DSE the symbolic expression (x*x*x + y*y*y == z*z*z) would be reduced to the constant False by evaluation on the concrete values of variables x, y and z.

Besides difficult operations (such as non-linear arithmetic), other examples of code that we might treat concretely instead of symbolically include functions that are hard to invert, such as cryptographic hash functions, or low-level functions that we do not wish to test (such as operating system functions). Consider the code in Figure 4, which applies the function unknown to argument x and compares it to argument y. By using the name unknown we simply mean to say that we wish treat this function as a black box, with no knowledge of how it operates internally.

def dart(x,y):
if (unknown(x) == y):
return 1
return 0

Figure 4. Another hard example for symbolic execution

In such a case, we can use DSE to execute the function unknown function on a specific input (say 5013) and observe its output (say 42). That is, rather than try to execute unknown symbolically and invoke an ATP to invert the function's path-condition, we simply treat the call to unknown concretely, substituting its return value (in this case 42) for the specialized expression unknown(5013) == y to get the predicate (42 == y).

Adding the constraint (x == 5013) yields the sound but rather specific path-condition (x == 5013) and (42 == y). Note that the path-condition (42 == y) is not sound, as it admits any value for the variable x, which likely includes many values for which (unknown(x) == y) is false.

1.3. Overview

This introduction elides many important issues that arise in implementing DSE for a real language, which we will focus on in the remainder of the paper. These include how to:

  • Identify the code under test $P$ and the symbolic inputs to $P$;
  • Trace the control flow path $p$ taken by execution $P(i)$;
  • Reinterpret program operations to compute symbolic expressions;
  • Generate a path-condition from $p$ and the symbolic expressions;
  • Generate a new input $i'$ by negating (part of) the path-condition, translating the path-condition to the input language of an ATP, invoking the ATP, and lifting a satisfying model (if any) back up to the source level;
  • Guide the search to expose new paths.

The rest of this paper is organized as follows. Section 2 describes an instrumented typing discipline where we lift each type (representing a set of concrete values) to a symbolic type (representing a set of pairs of concrete and symbolic values). Section 3 shows how strongest postconditions defines a symbolic semantics for a small programming language and how strongest postconditions can be refined to model DSE. Section 4 describes an implementation of DSE for the Python language in the Python language that follows the instrumented semantics pattern closely (full implementation and tests available at PyExZ3, tagged “v1.0”). Section 5 describes the symbolic encoding of Python integer operations using two decision procedures of Z3: linear arithmetic with uninterpreted functions in place of non-linear operations; fixed-width bitvectors with precise encodings of most operations. Section 6 offers a number of ideas for projects to extend the capabilities of PyExZ3.

2. Instrumented Types

We are given a universe of classes/types $U$; a type $T \in U$ carries along a set of operations that apply to values of type $T$, where an operation $o \in T$ takes an argument list of typed values as input (the first being of type $T$) and produces a single typed value as output. Nullary (static) operations of type $T$ can be used to create values of type $T$ (such as constants, objects, etc.)

A program $P$ has typed input variables $v_1 : T_1 \ldots v_k : T_k$ and a body from the language of statements $S$:

\[\begin{mdMathprearray}%
\mathid{S}\mdMathspace{1}\rightarrow   &\mdMathspace{1}\mathid{v}\mdMathspace{1}:=\mdMathspace{1}\mathid{E}\mdMathbr{}
\mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mdMathbr{}
\mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathid{S}_1\mdMathspace{1};\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mdMathbr{}
\mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end}\mdMathbr{}
\mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end}
\end{mdMathprearray}\]

The language of expressions ($E$) is defined by the application of operations to values, where constants (nullary operations) and program variables form the leaves of the expression tree and non-nullary operators form the interior nodes of the tree. For now, we will consider all values to be immutable. That is, the only source of mutation in the language is the assignment statement.

To introduce symbolic execution into the picture, we can imagine that a type $T \in U$ has (one or more) counterparts in a symbolic universe $U'$. A type $T' \in U'$ is a subtype of $T \in U$ with two purposes:

  • First, a value of type $T'$ represents a pair of values: a concrete value $c$ of (super)type $T$ and a symbolic expression $e$. A symbolic expression is a tree whose leaves are either nullary operators (i.e., constants) of a type in $U$ or are Skolem constants representing the (symbolic) inputs ($v_1 \ldots v_k$) to the program $P$, and whose interior nodes represent operations from types in $U$. We refer to Skolem constants as “symbolic constants” from this point on. Note that symbolic expressions do not contain references to program variables.

  • Second, the type $T'$ redefines some of the operations $o \in T$, namely those for which we wish to compute symbolic expressions. An operation $o \in T'$ has the same parameter list as $o \in T$, allowing it to take inputs with types from both $U$ and $U'$. The return type of $o \in T'$ generally is from $U'$ (though it can be from $U$). Thus, $o \in T'$ is a proper function subtype of $o \in T$. The purpose of $o \in T'$ is to: (1) perform operation $o \in T$ on the concrete values associated with its inputs; (2) build a symbolic expression tree rooted at operation $o$ whose children are the trees associated with the inputs to $o$.

Figure 5 presents pseudo code for the instrumention of a type $T$ via a type $T'$. The class Symbolic is used to hold an expression tree (Expr). Given a class $T \in U$, a symbolic type $T' \in U'$ is defined by inheriting from both $T$ and Symbolic. This ensures that a $T'$ can be used whereever a $T$ is expected.

  class $T'$ : $T$, Symbolic {
$T'$(c:$T$, e:Expr) : $T$(c), Symbolic(e) {}

override o(this:$T$, f1:$T_1$, ... , fk:$T_k$) : $R'$ {
var c := $T$.o(this, f1, ... ,fk)
var e := new Expr($T$.o, expr(self), expr(f1), ..., expr(fk))
return new $R'$(c,e)
}
...
}

class $R'$ : $R$, Symbolic { ... }

function expr(v) = v instanceof Symbolic ? v.getExpr() : v

Figure 5. Type instrumentation to carry both concrete values and symbolic expressions.

A type such as $T'$ only can be constructed by providing a concrete value $c$ of type $T$ and a symbolic expression $e$ to the constructor for $T'$. This will be done in exactly two places:

  • by the creation of symbolic constants associated with the primary inputs ($v_1 \ldots v_k$) to the program;

  • by the instrumented operations as shown in Figure 5.

An instrumented operation $o$ on arguments (this, f1, …, fk) first invokes its corresponding underlying operator $T.o$ on arguments (this, f1, …, fk) to get concrete value c. It then constructs a new expression tree e rooted at operator $T.o$, whose children are the result of mapping the function expr over (this, f1, …, fk). The helper function expr(v) evaluates to an expression tree in the case that v is of Symbolic type (representing a type in $U'$) and evaluates to v itself, a concrete value of some type in $U$, otherwise. Finally, having computed the values c and e, the instrumented operator returns $R'$(c,e), where $R$ is the return type of operator $T.o$, and $R'$ is a subtype of $R$ from universe $U'$.

Looked at another way, the universe $U'$ represents the “tainting” of types from $U$. Tainted values flow from program inputs to the operands of operators. If an operator has been redefined (as above) then taintedness propagates from its inputs to its outputs. On the other hand, if the operator has not been redefined, then it will not propagate taintedness. In the context of DSE, “taintedness” means that the instrumented semantics carries along a symbolic expression tree $e$ along with a concrete value $c$.

The choice of types from the universe $U'$ determines how symbolic expressions are constructed. For each $T \in U$, the “most symbolic” (least concrete) choice is the $T'$ that redefines every operator of $T$ (as shown in Figure 5). The “least symbolic” (most concrete) choice is $T' = T$ which redefines no operators. Let $symbolic(T)$ be the set of types in $U'$ that are subtypes of $T$. The types in $symbolic(T)$ are partially ordered by subset inclusion on the set of operators from $T$ they redefine.

3. From Strongest Postconditions to DSE

The previous section showed how symbolic expressions can be computed via a set of instrumented types, where the expressions are computed as a side-effect of the execution of program operations. This section shows how these symbolic expressions can be used to form a path-condition (which then can be compiled into a logic formula and passed to an automated theorem prover to find new inputs to drive a program's execution along new paths). We derive a path-condition directly from the strongest postcondition (symbolic) semantics of our programming language, refining it to model the basic operations of an interpreter.

3.1. Strongest Postconditions

The strongest postcondition transformer $SP$ [6] is defined over a predicate $P$ representing a set of pre-states and a statement $S$ from our language. The transformer $Q = SP(P,S)$ yields a predicate $Q$ such that for any state $s$ satisfying predicate $P$, the execution of statement $S$ from state $s$, if it does not go wrong or diverge, yields a state $s'$ satisfying predicate $Q$. The strongest postcondition for the statements in our language is defined by the following five rules:

\[\begin{mdMathprearray}%
1.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\exists \mathid{y}\mdMathspace{1}.\mdMathspace{1}(\mathid{x}\mdMathspace{1}=\mdMathspace{1}\mathid{E}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}])\mdMathspace{1}\wedge \mathid{P}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}]\mdMathbr{}
2.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathkw{skip})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{P}\mdMathbr{}
3.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathid{S}_{1};\mathid{S}_{2})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{SP}(\mathid{SP}(\mathid{P},\mathid{S}_{1}),\mdMathspace{1}\mathid{S}_{2})\mdMathbr{}
4.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{}
\mdMathindent{4}&\mdMathspace{7}\mathid{SP}(\mathid{P}\wedge \mathid{E},\mathid{S}_1)\mdMathspace{1}\vee  \mathid{SP}(\mathid{P}\mdMathspace{1}\wedge \neg \mathid{E},\mathid{S}_2)\mdMathbr{}
5.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{}
\mdMathindent{4}&\mdMathspace{6}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S};\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end}\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mathkw{end})
\end{mdMathprearray}\]

Rule (1) defines the strongest postcondition for the assignment statement. The assignment is modelled logically by the equality $x = E$ where any free occurrence of $x$ in $E$ is replaced by the existentially quantified variable $y$, which represents the value of $x$ in the pre-state. The same substitution ($[x \rightarrow y ]$) is applied to the pre-state predicate $P$.

Rules (2)-(5) define the strongest postcondition for the four control-flow statements. The rules for the skip statement and sequencing (;) are straightforward. Of particular interest, note that the rule for the if-then-else statement splits cases on the expression $E$. It is here that DSE will choose one of the cases for us, as the concrete execution will evaluate $E$ either to be true or false. This gives rise to the path-condition (either $P \wedge E$ or $P \wedge \neg E$). The recursive rule for the while loop unfolds as many times as the expression $E$ evaluates true, adding to the path-condition.

3.2. From $SP$ to DSE

Assume that an execution begins with the assignment of initial values $c_1 \ldots c_k$ to the program $P$'s inputs $V = \{ v_1 : T_1 \ldots v_k : T_k \}$. To seed symbolic execution, some of the types $T_i$ are replaced by symbolic counterparts $T'_i$, in which case $v_i$ is initialized to the value $sc_i = T'_i (c_i,SC(v_i))$ instead of the value $c_i$, where $SC(v_i)$ is the symbolic constant representing the initial value of variable $v_i$. The symbolic constant $SC(v_i)$ can be thought of as representing any value of type $T_i$, which includes the value $c_i$.

Let $V_s$ and $V_c$ partition the variables of $V$ into those variables that are treated symbolically ($V_s$) and those that are treated concretely ($V_c$). The initial state of the program is characterized by the formula

(1)
\[Init = (\bigwedge_{v_i \in V_s} v_i = sc_i) ~\wedge~ (~\bigwedge_{v_i \in V_c} v_i = c_i)\]

Thus, we see that the initial value of every input variable is characterized by a symbolic constant $sc_i$ or constant $c_i$. We assume that every non-input variable in the program is initialized before being used.

The strongest postcondition is formulated to deal with open programs, programs in which some variables are used before being assigned to. This surfaces in Rule (1) for assignment, which uses existential quantification to refer to the value of variable $x$ in the pre-state.

By construction, we have that every variable is defined before being used. This means that the precondition $P$ can be reformulated as a pair $<\sigma,P_c>$, where $t$ is a store mapping variables to values and $P_c$ is the path-condition, a list of symbolic expressions (predicates) corresponding to the expressions $E$ evaluated in the context of an if-then-else statement. Initially, we have that :

(2)
\[\sigma = \{ (v_i,sc_i) | v_i \in V_s \} \cup \{ (v_i,c_i) | v_i \in V_c \}\]

representing the initial condition $Init$, and $P_c = []$, the empty list. We use $\sigma'$ to refer to the formula that the store $\sigma$ induces:

(3)
\[\sigma ' =  \bigwedge_{(v,V) \in \sigma} (v = V)\]

Thus, the pair $<\sigma,P_c>$ represents the predicate $P = \sigma' \wedge (\bigwedge_{c \in P_c} c)$. A store $\sigma$ supports two operations: $\sigma[x]$ which denotes the value that $x$ maps to under $\sigma$; $\sigma[x \mapsto V]$, which produces a new store in which $x$ maps to value $V$ and is everywhere else the same as $\sigma$.

Now, we can redefine strongest postcondition for assignment to eliminate the use of existential quantification and model the operation of an interpreter, by separating out the notion of the store:

\[\begin{mdMathprearray}%
1.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}<\sigma[\mathid{x}\mdMathspace{1}\mapsto \mathid{eval}(\sigma,\mathid{E})],\mdMathspace{1}\mathid{P}_\mathid{c}>\\
\end{mdMathprearray}\]

where $eval(\sigma,E)$ evaluates expression $E$ under the store $\sigma$ (where every occurrence of a free variable $v$ in $E$ is replaced by the value $\sigma[v]$). This is the standard substitution rule of a standard operational semantics.

We also redefine the rule for the if-then-else statement so that it chooses which branch to take and appends the appropriate symbolic expression (predicate) to the path-condition $P_c$:

\[\begin{mdMathprearray}%
4.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{2}\mdMathbr{}
\mdMathindent{3}&\mdMathspace{3}\mathkw{let}\mdMathspace{1}\mathid{choice}\mdMathspace{1}=\mdMathspace{1}\mathid{eval}(\sigma,\mathid{E})\mdMathspace{1}\mathkw{in}\mdMathbr{}
\mdMathindent{3}&\mdMathspace{3}\mathkw{if}\mdMathspace{1}\mathid{choice}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_1)\mdMathspace{1}\mdMathbr{}
\mdMathindent{3}&\mdMathspace{3}\mathkw{else}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\neg \mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_2)
\end{mdMathprearray}\]

The other strongest postcondition rules remain unchanged.

3.3. Summing it up

We have shown how the symbolic predicate transformer $SP$ can be refined into an symbolic interpreter operating over the symbolic types defined in the previous section. In the case when every input variable is symbolic and every operator is redefined, the path-condition is equivalent to the strongest postcondition of the execution path $p$. This guarantees that the path-condition for $p$ is sound. In the case where a subset of the input variables are symbolic and/or not all operators are redefined, the path-condition of $p$ is not guaranteed to be sound. We leave it as an exercise to the reader to establish sufficient conditions under which the use of concrete values in place of symbolic expressions is guaranteed to result in sound path-conditions.

This section does not address the compilation of a symbolic expression to the (logic) language of an underlying ATP, nor the lifting of a satsifying assignment to a formula back to the level of the source language. This is best done for a particular source language and ATP, as detailed in the next section.

4. Architecture of PyExZ3

In this section we present the high-level architecture of a simple DSE tool for the Python language, written in Python, called PyExZ3. Figure 6 shows the class diagram (dashed edges are “has-a” relationships; solid edges are “is-a” relationships) of the tool.

arch


Figure 6. Classes in PyExZ3

4.1. Loading/testing the code under test

The Loader class takes as input the name of a Python file (e.g., foo.py) to import. The loader expects to find a function named foo inside the file foo.py, which will serve as the starting point for symbolic execution. Thc FunctionInvocation class wraps this starting point. By default, each parameter to foo is a SymbolicInteger unless there is decorator @symbolic specifying the type to use for a particular argument.

The loader provides the capability to reload the file/module foo.py so that the function foo can be reexecuted within the same process from the same initial state with different inputs (see the class ExplorationEngine) via the FunctionInvocation class.

Finally, the loader looks for specially named functions expected_result (expected_result_set) in file foo.py to use as a test oracle after the path exploration (by ExplorationEngine) has completed. These functions are expected to return a list of values to check against the list of return values collected from the executions of the foo function. The presence of the function expected_result (expected_result_set) yields a comparison of the two lists as bags (sets). We use such weaker tests, rather than list equality, because the order in which paths are explored by the ExplorationEngine can easily change due to small differences in the input programs.

4.2. Symbolic types

Python supports multiple inheritance and, more importantly, allows user-defined classes to inherit from its built-in types (such as object and int). We use these two features two implement symbolic versions of Python objects and integers, following the instrumented type approach defined in Section 2.

The abstract class SymbolicType contains the symbolic expression tree and provides basic functions for constructing and accessing the tree. This class does double duty, as it is used to represent the (typed) symbolic constants associated with the parameters to the function, as well as the expression trees (per Section 2). Recall that the symbolic constants only appear as leaves of expression trees. This means that the expression tree stored in a SymbolicType will have instances of a SymbolicType as some of its leaves, namely those leaves representing the symbolic constants. The abstract class provides an unwrap method which returns the pair of concrete value and expression tree associated with the SymbolicType, as well as a wrap method that takes a pair of concrete value and expression tree and creates a SymbolicType encapsulating them.

The class SymbolicObject inherits from both object and SymbolicType and overrides the basic comparison operations (__eq__, __neq__, __lt__, __le__, __gt__, and __ge__). The class SymbolicInteger inherits from both int and SymbolicObject and overrides a number of int's arithmetic methods (__add__, __sub__, __mul__, __mod__, __floordiv_) and bitwise methods (__and__, __or__, __xor__, __lshift__, __rshift__).

4.3. Tracing control-flow

As Python interprets a program, it will evaluate expressions, substituting the value of a variable in its place in an expression, applying operators (methods) to parameter values and assigning the return values of methods to variables. Value of type SymbolicInteger will simply flow through this interpretation, without necessitating any change to the program or the interpreter. This takes care of the case of the strongest-postcondition rule for assignment, as elaborated in Section 3.2.

The strong-postcondition rule for a conditional test requires a little more work. In Python, any object can be tested in an if or while condition or as the operand of a boolean operation (and, or, not) The Python base class object provides a method named __bool__ that the Python runtime calls whenever it needs to perform such a conditional test. This hook provides us what we need to trace the conditional control-flow of a Python execution. We override this method in the class SymbolicObject in order to inform the PathToConstraint object (defined later) of the symbolic expression for the conditional (as captured by the SymbolicInteger subclass).

Note that the use of this hook in combination with the tainted types will only trace those conditionals in a Python execution whose values inherit from SymbolicObject; by definition, “untainted” conditionals do not depend on symbolic inputs so there is no value in adding them to the path-condition.

4.4. Recording path-conditions

A Predicate records a conditional (more precisly the symbolic expression found in SymbolicInteger) and which way it evaluated in an execution. A Constraint has a Predicate, a parent Constraint and a set of Constraint children. Constraints form a tree, where each path starting from the root of the tree represents a path-condition. The tree represents all path-conditions that have been explored so far.

The class PathToConstraint has a reference to the root of the tree of Constraints and is responsible for installing a new Constraint in the tree when notified by the overrided __bool__ method of SymbolicObject. PathToConstraint also tracks whether or not the current execution is following an existing path in the tree and grows the tree as needed. In fact, it actually tracks whether or not the current execution follows a particular expected path in the tree.

The expected path is the result of the ExplorationEngine picking a constraint $c$ in the tree, and asking the ATP if the path-condition consisting of the prefix of predicates up to but not including $c$ in the tree, followed by the negation of $c$'s predicate is satisfiable. If the ATP returns “satisfiable” (with a new input $i$), then the assumption is that path-condition prefix is sound (that is, the execution of the program on input $i$ will follow the prefix).

However, it is possible for the path-condition to be unsound and for the executed path to diverge early from the expected path, due to the fact that not every operation has a symbolic encoding. The tool simply reports the divergence and continues to process the execution as usual (as a diverging path may lead to some other interesting part of the code).

4.5. From symbolic types to Z3

As we have explained DSE, the symbolic expressions are represented at the level of the source language. As detailed later in Section 5, we must translate from the source language to the input language of an automated theorem prover (ATP), in this case Z3. This separation of languages is quite useful, as we may have the need to translate a given symbolic expression to the ATP's language multiple times, to make use of different features of the underlying ATP. Furthermore, this separation of concerns allows us to easily retarget the DSE tool to a different ATP.

The base class Z3Expression represents a Z3 formula. The two subclasses Z3Integer and Z3BitVector represent different ways to model arithmetic reasoning about integers in Z3. We will describe the details of these encodings in Section 5.

The class Z3Wrapper is responsible for performing the translation from the source language (Python) to Z3's input language, invoking Z3, and lifting a Z3 answer back to the level of Python. The findCounterexample method does all the work, taking as input a list of Predicates (called assertions) as well as a single Predicate (called the query). The assertions represent a path-condition prefix derived from the Constraint tree that we wish the next execution to follow, while query represents the predicate following the prefix in the tree that we will negate.

The method constructs the formula

(4)
\[(\bigwedge_{a \in asserts} a) \wedge \neg query\]

and asks Z3 if it is satisfiable. The method performs a standard syntactic “cone of influence” (CIF) reduction on the asserts with respect to the query to shrink the size of the formula. For example, if asserts is the set of predicates $\{ (x<a), (a<0), (y>0) \}$ and the query is $(x=0)$, then the CIF yields the set $\{ (x<a), (a<0) \}$, which does not include the predicate $(y>0)$, as the variable $y$ is not in the set of variables (transitively) related to variable $x$.

If the formula is satisfiable a model is requested from Z3 and lifted back to Python's type universe. Note that because of the CIF reduction, the model may not mention certain input variables, in which case we simply keep their values from the execution from which the asserts and query were derived.

4.6. Putting it all together

The class ExplorationEngine ties everything together. It kicks off an execution of the Python code under test using FunctionInvocation. As the Python code executes, building symbolic expressions via SymbolicType and its subclasses, callbacks to PathToConstraint create a path-condition, represented by Constraint and Predicate. Newly discovered Constraints are added to the end of a deque maintained by ExplorationEngine.

Given the first seed execution, ExplorationEngine starts the work of exploring paths in a breadth-first fashion. It removes a Constraint $c$ from the front of its deque and, if $c$ has not been already “processed”, uses Z3Wrapper to find a new input (as discussed in the previous section) where $c$ is the query (to be negated) and the path to $c$ in the Constraint tree forms the assertions.

A Constraint $c$ in the tree is considered “processed” if an execution has covered $c'$, a sibling of $c$ in the tree that represents the negation of the predicate associated with $c$, or if constraint $c$ has been removed from the deque.

5. From Python Integers to Z3 Arithmetic

In languages such as C and Java, integers are finite-precision, generally limited to the size of a machine word (32 or 64 bits, for example). For such languages, satisfiability of finite-precision integer arithmetic is decidable and can be reduced to Z3's theory of bit-vectors, where each arithmetic operation is encoded by a circuit. This translation permits reasoning about non-linear arithmetic problems, such as $\exists x,y,z : x*z + y \leq (z/y)+5$.

Python (3.0) integers, however, are not finite-precision. They are only limited by the size of machine memory. This means, for example, that Python integers don't overflow or underflow. It also means that we can't hope to decide algorithmically whether or not a given equation over integer variables has a solution in general. Hibert's famous 10th problem and its solution by Matiyasevich tells us that it is undecidable whether or not a polynomial equation of the form $p(x_1, \ldots, x_n) = 0$ with integer coefficients has an solution in the integers.

This means that we will resort to heuristic approaches in our use of the Z3 ATP. The special case of linear integer arithmetic (LIA) is decidable and supported by Z3. In order to deal with non-linear operations, we use uninterpreted functions (UF). Thus, if Z3 returns “unsatisfiable” we know that there is no solution, but if the Z3 “satisfiable”, we must treat the answer as a “don't know”. The class Z3Integer is used to translate a symbolic expression into the theory LIA+UF and check for unsatisfiability. We leave it as an implementation exercise to check if a symbolic expression can be converted to LIA (without the use of UF) in order to make use of “satisfiable” answers from the LIA solver.

If the translation to Z3Integer does not return “unsatisfiable”, we use Z3's bit vector decision procedure (via the class Z3BitVector) to heuristically try to find satisfiable answers, even in the presence of non-linear arithmetic. We start with bitvectors of size $N=32$ and bound the values of the symbolic constants to fit within 8 bits in order to find satisfiable solutions with small values. Also, because Python integers do not overflow/underflow, the bound helps us reserve space in the bitvector to allow the results of operations to exceed the bound while not overflowing the bitvector. As long as Z3 returns “unsatisfiable” we increase the bound. If the bound reaches $N$, we increase $N$ by 8 bits, leaving the bound where it is and continue.

If Z3 returns “satisfiable”, it may be the case that Z3 found a solution that involved overflow in the bitvector world of arithemetic (modulo $2^N-1$). Therefore, the solution is validated back in the Python world by evaluating the formula under that solution using Python semantics. If the formula does not evaluate to the same value in both worlds, then we increase $N$ by 8 bits (to create a gap between the bound and $N$) and continue to search for a solution.

The process terminates when we find a valid satisfying solution or $N=64$ and the bound reaches 64 (in which case, we return “don't know”).

6. Extensions

We have presented the basics of dynamic symbolic execution (for Python). A more thorough treatment would deal with other data types besides integers, such as Python dictionaries, strings and lists, each of which presents their own challenges for symbolic reasoning. There are many other interesting challenges in DSE, such as dealing with user-defined classes (rather than built-in types as done here) and multi-threaded execution.

7. Acknowledgements

Many thanks to the students of the 2014 Marktoberdorf Summer School on Dependable Software Systems Engineering for their questions and feedback about the first author's lectures on dynamic symbolic execution. The following students of the summer school helpfully provided tests for the PyExZ3 tool: Daniel Darvas, Damien Rusinek, Christian Dehnert and Thomas Pani. Thanks also to Peter Chapman for his contributions.

References

[1]  Cristian Cadar and Dawson R. Engler. Execution generated test cases: How to make systems code crash itself. In Proceedings of 12th International SPIN Workshop, pages 223, 2005. 🔎
[2]  Cristian Cadar and Koushik Sen. Symbolic execution for software testing: three decades later. Communications of the ACM, 56 (2): 8290, 2013. 🔎
[3]  Cristian Cadar, Vijay Ganesh, Peter M. Pawlowski, David L. Dill, and Dawson R. Engler. EXE: automatically generating inputs of death. In Proceedings of the 13th ACM Conference on Computer and Communications Security, pages 322335, 2006. 🔎
[4]  Lori A. Clarke. A system to generate test data and symbolically execute programs. IEEE Transactions on Software Engineering, 2 (3): 215222, 1976. 🔎
[5]  Leonardo Mendonça de Moura and Nikolaj Bjørner. Z3: an efficient SMT solver. In Proceedings of the 14th International Conference of Tools and Algorithms for the Construction and Analysis of Systems, pages 337340, 2008. 🔎
[6]  Edsger W. Dijkstra. A Discipline of Programming. Prentice-Hall, 1976. 🔎
[7]  Patrice Godefroid. Higher-order test generation. In Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation, pages 258269, 2011. 🔎
[8]  Patrice Godefroid, Nils Klarlund, and Koushik Sen. DART: directed automated random testing. In Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation, pages 213223, 2005. 🔎
[9]  Patrice Godefroid, Michael Y. Levin, and David A. Molnar. SAGE: whitebox fuzzing for security testing. Communications of the ACM, 55 (3): 4044, 2012. 🔎
[10]  Neelam Gupta, Aditya P. Mathur, and Mary Lou Soffa. Generating test data for branch coverage. In Proceedings of the Automate Software Engineering Conference, pages 219228, 2000. 🔎
[11]  James C. King. Symbolic execution and program testing. Communications of the ACM, 19 (7): 385–394, 1976. 🔎
[12]  Bogdan Korel. Automated software test data generation. IEEE Transactions on Software Engineering, 16 (8): 870879, 1990. 🔎
[13]  Bogdan Korel. Dynamic method of software test data generation. Journal of Software Testing, Verification and Reliability, 2 (4): 203213, 1992. 🔎
[14]  Koushik Sen and Gul Agha. CUTE and jcute: Concolic unit testing and explicit path model-checking tools. In Proceedings of 18th Computer Aided Verification Conference, pages 419423, 2006. 🔎
================================================ FILE: marktoberdorf_paper/forPublisher/IOS-Book-Article.cls ================================================ %% This is file `IOSarticle.cls' %% %% Generic LaTeX 2e class file for the IOS Press publications %% %% Macros written by Vytas Statulevicius, VTeX, Lithuania %% for IOS Press, The Netherlands %% Please submit bugs or your comments to vytas@vtex.lt %% %% You are free to use this class file as you see fit, provided %% that you do not make changes to the file. %% If you DO make changes, you are required to rename this file. %% %% It may be distributed under the terms of the LaTeX Project Public %% License, as described in lppl.txt in the base LaTeX distribution. %% Either version 1.0 or, at your option, any later version. %% %% \CharacterTable %% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z %% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z %% Digits \0\1\2\3\4\5\6\7\8\9 %% Exclamation \! Double quote \" Hash (number) \# %% Dollar \$ Percent \% Ampersand \& %% Acute accent \' Left paren \( Right paren \) %% Asterisk \* Plus \+ Comma \, %% Minus \- Point \. Solidus \/ %% Colon \: Semicolon \; Less than \< %% Equals \= Greater than \> Question mark \? %% Commercial at \@ Left bracket \[ Backslash \\ %% Right bracket \] Circumflex \^ Underscore \_ %% Grave accent \` Left brace \{ Vertical bar \| %% Right brace \} Tilde \~} %% %% %% Bug fixes and changes: %% 2004.05.19 - small change o layout %% 2004.09.14 - \parindent changed %% 2006.03.27 - centering on A4, no running heads, \snm makes uppercase %% 2006.04.20 - changed: \thebibliography size, indent, \parindent \NeedsTeXFormat{LaTeX2e}[1995/12/01] \ProvidesClass{IOS-Book-Article} [2006/04/20 v1.0, IOS Press] \newif\if@restonecol \@restonecolfalse \newif\if@openright \newif\if@mainmatter \@mainmattertrue \DeclareOption{draft}{\setlength\overfullrule{5pt}} \DeclareOption{final}{\setlength\overfullrule{0pt}} \DeclareOption{openright}{\@openrighttrue} \DeclareOption{openany}{\@openrightfalse} \DeclareOption{onecolumn}{\@twocolumnfalse\@restonecoltrue} \DeclareOption{twocolumn}{\@twocolumntrue} \DeclareOption{leqno}{\input{leqno.clo}} \DeclareOption{fleqn}{\input{fleqn.clo}}% % % Numbering switches: \newif\if@seceqn \@seceqnfalse \DeclareOption{seceqn}{\@seceqntrue} \newif\if@secfloat \@secfloatfalse \DeclareOption{secfloat}{\@secfloattrue} \newif\if@secthm \DeclareOption{secthm}{\@secthmtrue} % % % Selection of font size and page dimensions % If 12pt option is used, page will be reduced by 80% at printing time \newif\if@ten@point \@ten@pointfalse \DeclareOption{10pt}{\@ten@pointtrue} \DeclareOption{12pt}{\@ten@pointfalse} % Information about the publication \def\booktitle#1{\gdef\book@title{#1}} \def\bookeditors#1{\gdef\book@editors{#1}} \def\publisher#1{\gdef\@publisher{#1}} \booktitle{Book Title} \bookeditors{Book Editors} \publisher{IOS Press} \ExecuteOptions{10pt,onecolumn,twoside,final,openright,fleqn} \ProcessOptions % %************************* FONTS %\def\@xivpt{14} %\def\@xviipt{17} %\def\@xviiipt{18} %\def\@xxpt{20} %\def\@xxivpt{24} % Fonts: \typeout{Ten point} % \renewcommand\normalsize{% \@setfontsize\normalsize\@xpt{12pt plus .5\p@ minus .1\p@}% \abovedisplayskip 12\p@ \@plus3pt \@minus3pt% \abovedisplayshortskip\abovedisplayskip% \belowdisplayshortskip\abovedisplayskip% \belowdisplayskip \abovedisplayskip% \let\@listi\@listI} \newcommand\small{% \@setfontsize\small\@ixpt\@xipt% \abovedisplayskip 5.5\p@ \@plus3pt% \abovedisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \belowdisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \def\@listi{\leftmargin\leftmargini \topsep 5\p@ \@plus2\p@ \@minus2\p@ \parsep \z@ \itemsep \parsep}% \belowdisplayskip \abovedisplayskip% } \newcommand\footnotesize{% \@setfontsize\footnotesize\@viiipt\@xpt% \abovedisplayskip 5.5\p@ \@plus3pt% \abovedisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \belowdisplayshortskip 5.5\p@ \@plus1pt \@minus1pt% \def\@listi{\leftmargin\leftmargini \topsep 4\p@ \@plus2\p@ \@minus2\p@ \parsep \z@ \itemsep \parsep}% \belowdisplayskip \abovedisplayskip% } \newcommand\scriptsize{\@setfontsize\scriptsize\@viiipt{9.5}} \newcommand\tiny{\@setfontsize\tiny\@vipt\@viipt} \newcommand\large{\@setfontsize\large\@xiipt{14}} \newcommand\Large{\@setfontsize\Large\@xivpt{18}} \newcommand\LARGE{\@setfontsize\LARGE\@xviipt{22}} \newcommand\huge{\@setfontsize\huge\@xxpt{25}} \newcommand\Huge{\@setfontsize\Huge\@xxvpt{30}} \normalsize % Customization of fonts \renewcommand\sldefault{it} \renewcommand\bfdefault{b} \let\slshape\itshape % % ********************* DIMENSIONS: % TEXT DIMENSIONS \setlength\parindent{18\p@} \@settopoint\parindent \setlength\textwidth{124mm} \@settopoint\textwidth \setlength\textheight{200mm} \@settopoint\textheight \setlength\columnsep{10mm} \@settopoint\columnsep \setlength\columnwidth{95mm} \@settopoint\columnwidth \setlength\columnseprule{0\p@} \hoffset -0.5cm \voffset -1cm % HEADS: \setlength\headheight{12\p@} \setlength\headsep {15\p@} \setlength\topskip {10\p@} \setlength\footskip {25\p@} \setlength\maxdepth {.5\topskip} % SIDE MARGINS \setlength\oddsidemargin {0mm} \setlength\evensidemargin {0mm} \setlength\topmargin {10mm} \@settopoint\topmargin % TEXT PARAMETERS \setlength\lineskip{1\p@} \setlength\normallineskip{1\p@} \renewcommand\baselinestretch{} \setlength\parskip{0\p@} % Center on A4: \def\paper@width {210mm} \def\paper@height{297mm} \hoffset=-1in \voffset=-1in \@tempdima=\paper@width \advance\@tempdima by-\textwidth \divide\@tempdima by2 \setlength\evensidemargin {\@tempdima}% \setlength\oddsidemargin {\@tempdima}% \@tempdima=\paper@height \advance\@tempdima by-\textheight \advance\@tempdima by-\headsep \advance\@tempdima by-\headheight \divide\@tempdima by2 \setlength\topmargin {\@tempdima}% % BREAKS \setlength\smallskipamount{6\p@ \@plus 1\p@ \@minus 1\p@} \setlength\medskipamount{12\p@ \@plus 3\p@ \@minus 3\p@} \setlength\bigskipamount{24pt \@plus 3\p@ \@minus 3\p@} % PAGE-BREAKING PENALTIES \clubpenalty=4000 \widowpenalty=4000 \displaywidowpenalty=50 \predisplaypenalty=0 % Breaking before a math display. % \postdisplaypenalty % Breaking after a math display. % \interlinepenalty % Breaking at a line within a paragraph. % \brokenpenalty % Breaking after a hyphenated line. \pretolerance=100 % Badness tolerance for the first pass (before hyphenation) \tolerance=800 % Badness tolerance after hyphenation \hbadness=800 % Badness above which bad hboxes will be shown \emergencystretch=3\p@ \hfuzz=1\p@ % do not be to critical about boxes % \doublehyphendemerits=0 \adjdemerits=0 \brokenpenalty=0 \interlinepenalty=0 % \if@twocolumn \setlength\marginparsep {10\p@} \else \setlength\marginparsep{7\p@} \fi \setlength\marginparpush{5\p@} % FOOTNOTES \setlength\footnotesep{6.65\p@} \setlength{\skip\footins}{12\p@ \@plus 6\p@} % FLOATS \setlength\floatsep {15\p@ \@plus 10\p@ \@minus 4\p@} \setlength\textfloatsep{12\p@ \@plus 6\p@ \@minus 4\p@} \setlength\intextsep {12\p@ \@plus 6\p@ \@minus 4\p@} \setlength\dblfloatsep {15\p@ \@plus 10\p@ \@minus 4\p@} \setlength\dbltextfloatsep{12\p@ \@plus 12\p@ \@minus 4\p@} % For floats on a separate float page or column: \setlength\@fptop{0\p@ \@plus 1fil} \setlength\@fpsep{8\p@ \@plus 1000fil} \setlength\@fpbot{0\p@ \@plus 1fil} \setlength\@dblfptop{0\p@ \@plus 1fil} \setlength\@dblfpsep{8\p@ \@plus 1000fil} \setlength\@dblfpbot{0\p@ \@plus 1fil} % \setcounter{topnumber}{5} \renewcommand\topfraction{.90} \setcounter{bottomnumber}{5} \renewcommand\bottomfraction{.90} \setcounter{totalnumber}{10} \renewcommand\textfraction{.10} \renewcommand\floatpagefraction{.9} \setcounter{dbltopnumber}{5} \renewcommand\dbltopfraction{.99} \renewcommand\dblfloatpagefraction{.8} % % PENALTIES \@lowpenalty 51 \@medpenalty 151 \@highpenalty 301 \@beginparpenalty -\@lowpenalty \@endparpenalty -\@lowpenalty \@itempenalty -\@lowpenalty % LISTS \setlength\partopsep{0\p@} \def\@listI{\leftmargin\leftmargini \parsep 0\p@ \@plus2\p@ \@minus\p@ \topsep 9\p@ \@plus2\p@ \@minus2\p@ \partopsep\p@ \itemsep 1\p@ \@plus.5\p@ \@minus1\p@} \let\@listi\@listI \@listi \def\@listii {\leftmargin\leftmarginii \labelwidth\leftmarginii \advance\labelwidth-\labelsep \topsep 4\p@ \@plus2\p@ \@minus\p@ \parsep 0\p@ \@plus1\p@ \@minus\p@ \itemsep \parsep} \def\@listiii{\leftmargin\leftmarginiii \labelwidth\leftmarginiii \advance\labelwidth-\labelsep \topsep 2\p@ \@plus\p@\@minus\p@ \parsep \z@ \partopsep \p@ \@plus\z@ \@minus\p@ \itemsep \topsep} \def\@listiv {\leftmargin\leftmarginiv \labelwidth\leftmarginiv \advance\labelwidth-\labelsep} \def\@listv {\leftmargin\leftmarginv \labelwidth\leftmarginv \advance\labelwidth-\labelsep} \def\@listvi {\leftmargin\leftmarginvi \labelwidth\leftmarginvi \advance\labelwidth-\labelsep} % \DeclareMathSizes{\@xivpt}{\@xivpt}{\@xpt}{\@viiipt} \DeclareMathSizes{12}{12}{\@viiipt}{\@viipt} % % ******************** HEADINGS % % normal heading \def\ps@headings{% \let\@oddfoot\@empty\let\@evenfoot\@empty \def\@evenhead{\footnotesize\rlap{\thepage}\hfill\textit{\leftmark}\hfill}% \def\@oddhead{\footnotesize\hfill\textit{\rightmark}\hfill\llap{\thepage}}% }% % empty RH \def\ps@empty{\let\@mkboth\@gobbletwo \def\@oddhead{\hfill}\def\@oddfoot{} \let\@evenhead\@oddhead\let\@evenfoot\@oddfoot} % % RH with pagenumber at bottom \def\ps@plain{\let\@mkboth\@gobbletwo \def\@oddhead{\hfill}\def\@oddfoot{} \let\@evenhead\@oddhead \def\@oddfoot{\hfill\footnotesize\thepage\hfill} \let\@evenfoot\@oddfoot } % First page RH \def\ps@copyright{\let\@mkboth\@gobbletwo \def\@evenhead{\parbox[t]{.75\textwidth}{\footnotesize\raggedright\itshape\titleheadline}\hfill\footnotesize\thepage}% \def\@oddhead {\parbox[t]{.75\textwidth}{\footnotesize\raggedright\itshape\titleheadline}\hfill\footnotesize\thepage}% \let\@oddfoot\relax% \let\@evenfoot\@oddfoot% } % % HEADLINE: Book Title % Book Editors % IOS Press, 0000 % \def\titleheadline{% \book@title\\ \book@editors\\ \@publisher, \the\@pubyear} % \def\@copyright{\@issn/\the@copyear/\$\@price\ \copyright@sign\ \the\@pubyear\@copyrightowner}% % % ************************ FOOTNOTE % \newcommand\@makefntext[1]{% \parindent1em\@makefnmark #1} \def\@makefnmark{\@textsuperscript{\normalfont\@thefnmark}}% % % ************************ Counters \setcounter{secnumdepth}{3} \newcounter {section} \newcounter {subsection}[section] \newcounter {subsubsection}[subsection] \newcounter {paragraph}[subsubsection] \newcounter {subparagraph}[paragraph] \renewcommand \thesection {\@arabic\c@section} \renewcommand\thesubsection {\thesection.\@arabic\c@subsection} \renewcommand\thesubsubsection{\thesubsection .\@arabic\c@subsubsection} \renewcommand\theparagraph {\thesubsubsection.\@arabic\c@paragraph} \renewcommand\thesubparagraph {\theparagraph.\@arabic\c@subparagraph} % % ******************** Sectioning commands \def\no@harm{\let\thanks=\@gobble \let\\=\@empty} %**************** Section commands \def\nohyphen{\pretolerance=10000 \tolerance=10000 \hyphenpenalty=10000 \exhyphenpenalty=10000} \newcommand\section{\@startsection {section}{1}{\z@}% {-\bigskipamount}% {\medskipamount}% {\normalsize\bfseries\nohyphen\raggedright}} \newcommand\subsection{\@startsection {subsection}{2}{\z@}% {-\medskipamount}% {\medskipamount}% {\normalsize\itshape\nohyphen\raggedright}} \newcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}% {-\medskipamount}% {\smallskipamount}% {\normalsize\itshape\nohyphen\raggedright}} \newcommand\paragraph{\@startsection{paragraph}{4}{\z@}% {\smallskipamount}% {-1em}% {\normalsize\itshape}} \newcommand\subparagraph{\@startsection{subparagraph}{5}{\z@}% {0.1pt}% {-1em}% {\normalsize\itshape}} % Format for the counter: \def\@seccntformat#1{\csname the#1\endcsname.\enspace} % \def\appendix{\par \setcounter{section}{0}% \setcounter{subsection}{0}% \gdef\thesection{\Alph{section}}} % \def\acknowledgements{\section*{\acknowledgementsname}% \typeout{\acknowledgementsname}} % \def\notes{\section*{Notes}\footnotesize} \def\endnotes{\par \vskip 6pt plus12pt minus2pt\relax} %****************** LISTS \if@twocolumn \setlength\leftmargini {2em} \else \setlength\leftmargini {2.5em} \fi \leftmargin \leftmargini \setlength\leftmarginii {2.2em} \setlength\leftmarginiii {1.87em} \setlength\leftmarginiv {1.7em} \if@twocolumn \setlength\leftmarginv {.5em} \setlength\leftmarginvi {.5em} \else \setlength\leftmarginv {1em} \setlength\leftmarginvi {1em} \fi \setlength \labelsep {.4em} \setlength \labelwidth{\leftmargini} \addtolength\labelwidth{-\labelsep} % \renewcommand\theenumi{\@arabic\c@enumi} \renewcommand\theenumii{\@alph\c@enumii} \renewcommand\theenumiii{\@roman\c@enumiii} \renewcommand\theenumiv{\@Alph\c@enumiv} \newcommand\labelenumi{\theenumi.} \newcommand\labelenumii{(\theenumii)} \newcommand\labelenumiii{\theenumiii.} \newcommand\labelenumiv{\theenumiv.} \renewcommand\p@enumii{\theenumi} \renewcommand\p@enumiii{\theenumi(\theenumii)} \renewcommand\p@enumiv{\p@enumiii\theenumiii} % \def\setenumlabel#1{\gdef\max@enumlabel{#1}} \setenumlabel{1.} % \def\enumerate{\@ifnextchar[{\enumerate@}{\enumerate@[\max@enumlabel]}} % \def\enumerate@[#1]{\ifnum \@enumdepth >4 \@toodeep\else \advance\@enumdepth \@ne \edef\@enumctr{enum\romannumeral\the\@enumdepth}% \list {\csname label\@enumctr\endcsname}% {\usecounter{\@enumctr}\def\makelabel##1{{\hfill\rm ##1}} \settowidth{\labelwidth}{#1} \advance\labelwidth by\parindent \labelsep=0.5em \leftmargin\z@ \rightmargin\z@ \itemindent=\labelwidth \advance\itemindent\labelsep \leftmargin=\the\itemindent\itemindent=\z@ \partopsep\z@ \topsep\smallskipamount \parsep\z@ \itemsep\z@ %\@rightskip\z@ plus 1fil \listparindent\z@}\fi\setenumlabel{1.}} %%%%%%%%%%%%%%%%%%%%%% ITEMIZE \newcommand\labelitemi{\normalfont\bfseries \textbullet} \newcommand\labelitemii{\textasteriskcentered} \newcommand\labelitemiii{\textasteriskcentered} \newcommand\labelitemiv{\textperiodcentered} \let\@itemize@indent\parindent % \def\itemize{\@ifnextchar[{\itemize@}{\itemize@[]}} \def\itemize@[#1]{\ifnum \@itemdepth >4 \@toodeep\else \advance\@itemdepth \@ne \edef\@itemitem{labelitem\romannumeral\the\@itemdepth}% \if.#1. \else\def\@@tempa{#1}\edef\@itemitem{@@tempa}\fi\list {\csname\@itemitem\endcsname}{\settowidth{\labelwidth} {\csname\@itemitem\endcsname} \def\makelabel##1{##1}\labelsep=0.5em%ST \itemindent=\labelwidth \advance\itemindent\labelsep \advance\itemindent\@itemize@indent \leftmargin\the\itemindent \itemindent=\z@ \partopsep\z@ \topsep\smallskipamount \parsep\z@ %\@rightskip\z@ plus 1fil \itemsep\z@ \listparindent\z@} \fi} % \newenvironment{description} {\list{}{\labelwidth\z@ \itemindent-\leftmargin \let\makelabel\descriptionlabel}} {\endlist} \newcommand*\descriptionlabel[1]{\hspace\labelsep \normalfont\bfseries #1} \newenvironment{verse} {\let\\\@centercr \list{}{\itemsep \z@ \itemindent -1.5em% \listparindent\itemindent \rightmargin \leftmargin \advance\leftmargin 1.5em}% \item\relax} {\endlist} \newenvironment{quotation} {\list{}{\small\listparindent2mm% \itemindent\z@ % \rightmargin\z@ \leftmargin\parindent% \partopsep\z@ \topsep\smallskipamount \parsep\z@% }% \item[\Q@strut]\relax} {\endlist} \def\Q@strut{\leavevmode\hbox{\vrule height9pt depth1pt width0pt}} \newenvironment{quote} {\list{}{\listparindent\z@% \itemindent \listparindent% \rightmargin\z@ \leftmargin 1.5em% \partopsep\z@ \topsep6pt \parsep\z@% }% \item[\Q@strut]\relax} {\endlist} % %************************** TABULAR \let\savehline\hline \def\thline{\noalign{\vskip3pt}\savehline\noalign{\vskip3pt}}% \def\fhline{\noalign{\vskip1pt}\savehline\noalign{\vskip7pt}}% \def\bhline{\noalign{\vskip3pt}\noalign{\global\arrayrulewidth=1\p@}\savehline\noalign{\global\arrayrulewidth=.5\p@}\noalign{\vskip3pt}}% \def\lhline{\noalign{\vskip3pt}\noalign{\global\arrayrulewidth=.3\p@}\savehline\noalign{\global\arrayrulewidth=.5\p@}\noalign{\vskip3pt}} % %************************** MATH SETTINGS \setlength\mathindent{2em} \setlength\arraycolsep{1.2\p@} \setlength\tabcolsep{6\p@} \setlength\arrayrulewidth{.4\p@} \setlength\doublerulesep{2\p@} \setlength\tabbingsep{\labelsep} \setlength\jot{6\p@} \skip\@mpfootins = \skip\footins \setlength\fboxsep{3\p@} \setlength\fboxrule{.4\p@} \if@seceqn \@addtoreset {equation}{section} \renewcommand\theequation{\thesection.\@arabic\c@equation} \else \renewcommand\theequation{\@arabic\c@equation} \fi %******* TABLES, FIGURES, ALGORITHM \newcounter{figure} \if@secfloat \@addtoreset{figure}{section} \renewcommand \thefigure {\thesection.\@arabic\c@figure} \else \renewcommand \thefigure {\@arabic\c@figure} \fi \def\fps@figure{tbp} \def\ftype@figure{1} \def\ext@figure{lof} \def\fnum@figure{\figurename~\thefigure.} \newenvironment{figure} {\let\@makecaption\@makefigurecaption\let\@floatboxreset\@figureboxreset\@float{figure}} {\end@float} \newenvironment{figure*} {\let\@makecaption\@makefigurecaption\let\@floatboxreset\@figureboxreset\@dblfloat{figure}} {\end@dblfloat} \def\@figureboxreset{% \reset@font% \centering% \@setnobreak% \@setminipage% } \long\def\@makefigurecaption#1#2{\footnotesize% \vskip\abovecaptionskip \setbox\@tempboxa\hbox{\textbf{#1}\enspace #2}% \ifdim \wd\@tempboxa >\hsize \unhbox\@tempboxa\par \else \hbox to\hsize{\hfil\box\@tempboxa\hfil}% \fi} % % TABLE \newcounter{table} \if@secfloat \@addtoreset{table}{section} \renewcommand \thetable{\thesection.\@arabic\c@table} \else \renewcommand \thetable{\@arabic\c@table} \fi \def\fps@table{tbp} \def\ftype@table{2} \def\ext@table{lot} \def\fnum@table{\tablename~\thetable.} % \newenvironment{table} {\let\@makecaption\@maketablecaption% \let\@floatboxreset\@tableboxreset\@float{table}} {\end@float} \newenvironment{table*} {\let\@makecaption\@maketablecaption% \let\@floatboxreset\@tableboxreset\@dblfloat{table}} {\end@dblfloat} % \def\@tableboxreset{% \reset@font% \centering\footnotesize% \def\arraystretch{1.2} \@setnobreak% \@setminipage% } \newlength\abovecaptionskip \newlength\belowcaptionskip \setlength\abovecaptionskip{8\p@} \setlength\belowcaptionskip{3\p@} % \newdimen\tablewidth \tablewidth\textwidth \newdimen\saved@tablewidth \saved@tablewidth\textwidth % \long\def\@maketablecaption#1#2{% \begingroup% \footnotesize% \global\setbox\@tempboxa\hbox{\textbf{#1}\enspace #2}% \endgroup% \centering% \ifdim \wd\@tempboxa>\tablewidth % \parbox[t]{\tablewidth}{\footnotesize\textbf{#1}\enspace #2\vphantom{Ay}\par}% \else \hbox to\hsize{\hfill\box\@tempboxa\vphantom{Ay}\hfill}% \fi% \global\saved@tablewidth\tablewidth% \global\tablewidth\hsize\vskip\belowcaptionskip} % % %%****************** Algorithm \newcounter{algorithm} \if@secfloat \@addtoreset{algorithm}{section} \renewcommand \thealgorithm{\thesection.\@arabic\c@algorithm} \else \renewcommand \thealgorithm{\@arabic\c@algorithm} \fi \def\fps@algorithm{tbp} \def\ftype@algorithm{4} \def\ext@algorithm{loa} \def\fnum@algorithm{\algorithmname~\thealgorithm.} % \newenvironment{algorithm} {\let\@makecaption\@makealgorithmcaption% \let\@floatboxreset\@algorithmboxreset\@float{algorithm}} {\end@float} \newenvironment{algorithm*} {\let\@makecaption\@makealgorithmcaption% \let\@floatboxreset\@algorithmboxreset\@dblfloat{algorithm}} {\end@dblfloat} \def\@algorithmboxreset{% \reset@font% \centering \@setnobreak% \@setminipage% } \long\def\@makealgorithmcaption#1#2{\vskip 2ex \small \hbox to \hsize{\parbox[t]{\hsize}{{\bf #1} #2}}} % %%%% Program Code: \def\programcode{% \let\@makealgorithmcaption\@makefigurecaption \def\algorithmname{Program Code}} %********************* COMPATIBILITY WITH OLD LATEX: \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} \DeclareOldFontCommand{\sf}{\normalfont\sffamily}{\mathsf} \DeclareOldFontCommand{\tt}{\normalfont\ttfamily}{\mathtt} \DeclareOldFontCommand{\bf}{\normalfont\bfseries}{\mathbf} \DeclareOldFontCommand{\it}{\normalfont\itshape}{\mathit} \let\sl\it \DeclareOldFontCommand{\sc}{\normalfont\scshape}{\@nomath\sc} \DeclareRobustCommand*\cal{\@fontswitch\relax\mathcal} \DeclareRobustCommand*\mit{\@fontswitch\relax\mathnormal} % % *********** MATH % \if@secthm \@addtoreset{thm}{section} \def\thethm{\thesection.\arabic{thm}} \else \def\thethm{\arabic{thm}} \fi % %***************************** BIBLIOGRAPHY \newenvironment{thebibliography}[1] {\section*{\refname}\footnotesize\rmfamily\upshape% \list{\@biblabel{\@arabic\c@enumiv}}% {\settowidth\labelwidth{\@biblabel{#1}}% \leftmargin\labelwidth \setlength\labelsep{8\p@} \advance\leftmargin\labelsep \usecounter{enumiv}% \let\p@enumiv\@empty \renewcommand\theenumiv{\@arabic\c@enumiv}}% \sloppy \clubpenalty4000 \@clubpenalty \clubpenalty \widowpenalty4000% \sfcode`\.\@m} {\def\@noitemerr {\@latex@warning{Empty `thebibliography' environment}}% \endlist} % \newcommand\newblock{\hskip .11em\@plus.33em\@minus.07em} % \def\@citex[#1]#2{% \let\@citea\@empty \@cite{\@for\@citeb:=#2\do {\@citea\def\@citea{,\penalty\@m\hskip.1pt}% \edef\@citeb{\expandafter\@firstofone\@citeb}% \if@filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi \@ifundefined{b@\@citeb}{\mbox{\reset@font\bfseries ?}% \G@refundefinedtrue \@latex@warning {Citation `\@citeb' on page \thepage \space undefined}}% {\hbox{\csname b@\@citeb\endcsname}}}}{#1}} %****************************** FRONTMATTER * % \newtoks\t@glob@notes \newtoks\t@loc@notes \newcount\note@cnt \newcounter{author} \newcount\n@author \def\n@author@{} \newcounter{address} % \newcount\sv@hyphenpenalty % \newcount\prev@elem \prev@elem=0 \newcount\cur@elem \cur@elem=0 \chardef\e@pretitle=1 \chardef\e@title=1 \chardef\e@subtitle=1 \chardef\e@author=2 \chardef\e@address=3 % \newif\if@newelem \newif\if@firstauthor \newif\if@preface \newif\if@hasabstract \newif\if@haskeywords % \newbox\fm@box \newdimen\fm@size \newbox\t@abstract \newbox\t@keywords % \def\add@tok#1#2{\global#1\expandafter{\the#1#2}} \def\add@xtok#1#2{\begingroup \no@harm \xdef\@act{\global\noexpand#1{\the#1#2}}\@act \endgroup} % \def\tailthanksref[#1]#2{\noexpand\pthanksref{#1}} \def\pthanksref#1{\global\advance\note@cnt\@ne\ifnum\note@cnt>\@ne \global\t@loc@notes\expandafter{\the\t@loc@notes\note@sep}\fi \global\t@loc@notes\expandafter{\the\t@loc@notes#1}} % \def\beg@elem{\global\t@loc@notes={}\global\note@cnt\z@} \def\@xnamedef#1{\expandafter\xdef\csname #1\endcsname} \def\no@harm{% \let\\=\relax \let\rm\relax \let\ss=\relax \let\ae=\relax \let\oe=\relax \let\AE=\relax \let\OE=\relax \let\o=\relax \let\O=\relax \let\i=\relax \let\j=\relax \let\aa=\relax \let\AA=\relax \let\l=\relax \let\L=\relax \let\d=\relax \let\b=\relax \let\c=\relax \let\bar=\relax \def\protect{\noexpand\protect\noexpand}} % \def\proc@elem#1#2{\begingroup \no@harm \def\thanks##1##{\@gobble}% \def\thanksref##1##{\@gobble}% \@xnamedef{@#1}{#2}% \endgroup \prev@elem=\cur@elem \cur@elem=\csname e@#1\endcsname \expandafter\elem@nothanksref#2\thanksref\relax% \expandafter\elem@nothanks#2\thanks\relax} % \def\elem@nothanksref#1\thanksref{\futurelet\@peektok\elem@thanksref} \def\elem@thanksref{\ifx\@peektok\relax \else \expandafter\elem@morethanksref \fi} \def\elem@morethanksref[#1]#2{\add@thanks{#1}\elem@nothanksref} % \def\elem@nothanks#1\thanks{\futurelet\@peektok\elem@thanks} \def\elem@thanks{\ifx\@peektok\relax \else \ifx\@peektok[ \expandafter\expandafter\expandafter\elem@morethankse \else \expandafter\expandafter\expandafter\elem@morethanks \fi\fi} % \def\elem@morethankse[#1]#2{\thanks@optarg[#1]{#2}\add@thanks{#1}\elem@nothanks} \def\elem@morethanks#1{\thanks@optarg[]{#1}\add@thanks{}\elem@nothanks} % \def\add@thanks#1{% \global\advance\note@cnt\@ne \ifnum\note@cnt>\@ne \add@xtok\t@loc@notes{\note@sep}\fi \ifx.#1.\add@xtok\t@loc@notes{\thefootnote}\else \add@xtok\t@loc@notes{#1}\fi% } \def\add@addressref#1{% \global\advance\note@cnt\@ne \ifnum\note@cnt>\@ne \add@xtok\t@loc@notes{\note@sep}\fi \add@tok\t@loc@notes{\ref{#1}}% } \def\note@sep{,} % \def\thanks@optarg[#1]#2{% \ifx.#1.\add@tok\t@glob@notes{\footnotetext}% \else\add@tok\t@glob@notes{\freefootnotetext}\fi% \refstepcounter{footnote}% \ifx.#1.\add@xtok\t@glob@notes{[\the\c@footnote]}% \else\add@xtok\t@glob@notes{[#1]}\fi% \add@tok\t@glob@notes{{#2}}% \ignorespaces}% % % FRONTMATTER % \def\artty#1{} % \newdimen\a@title@skip \a@title@skip=12\p@ \newskip\b@section@skip \b@section@skip=12\p@ plus6\p@ minus6\p@% \newskip\b@pretitle@skip \b@pretitle@skip=6\p@ % \def\frontmatter{% \let\@corresp@note\relax \global\t@glob@notes={}\global\c@author\z@ \global\c@address\z@ \global\n@author=0\n@author@\relax \global\advance\n@author\m@ne \global\@firstauthortrue \global\@hasabstractfalse \global\@prefacefalse \parindent\z@ \open@fm \ignorespaces} % \def\preface{\@prefacetrue} % % ENDFRONTMATTER % \def\endfrontmatter{% \global\n@author=\c@author \@writecount \global\@topnum\z@ \ifx\@firstpage\@lastpage \gdef\@pagerange{\@firstpage} \else \gdef\@pagerange{\@firstpage--\@lastpage} \fi % \thispagestyle{copyright}% \if@twocolumn\else\output@glob@notes\fi \if@preface \@hasabstractfalse \fi \if@hasabstract \normal@text \vskip 18\p@ \centering \leavevmode\box\t@abstract\par \fi \if@haskeywords \normal@text \if@hasabstract \vskip6pt\else\vskip18pt\fi \centering \leavevmode\box\t@keywords\par \fi \close@fm \if@twocolumn\output@glob@notes\fi \markboth{\@runauthor\@runtitle}{\@runauthor\@runtitle}% \global\@prefacefalse \global\leftskip\z@ \global\@rightskip\z@ \global\rightskip\@rightskip % \global\c@footnote=0 \let\title\relax \let\author\relax \let\address\relax \let\frontmatter\relax \let\endfrontmatter\relax \let\@maketitle\relax \let\@@maketitle\relax \normal@text} % % Dvieju koloneliu zurnale per visa lapo ploti eina % tik pretitle, title ir subtitle. Tam ivedame komanda % \maketitle, kuri uzdaro box'a \def\two@c@maketitle{% \global\let\close@fm\relax% \vskip\b@section@skip% \par \egroup \emergencystretch=1pc \twocolumn[\unvbox\fm@box]} % \if@restonecol \let\maketitle\relax \else \let\maketitle\two@c@maketitle \fi % % \newdimen\t@xtheight \def\init@settings{ \splittopskip=\topskip \splitmaxdepth=\maxdepth \t@xtheight\textheight \advance\t@xtheight-\splittopskip} % \def\open@fm{ \global\setbox\fm@box=\vbox\bgroup \hsize=\textwidth \centering \sv@hyphenpenalty\hyphenpenalty \hyphenpenalty\@M} % \def\close@fm{% \vskip\b@section@skip% \par \egroup \if@twocolumn\else% \fm@size=\dp\fm@box \advance\fm@size by \ht\fm@box \@whiledim\fm@size>\t@xtheight \do{% \global\setbox\@tempboxa=\vsplit\fm@box to \t@xtheight \unvbox\@tempboxa \newpage \fm@size=\dp\fm@box \advance\fm@size by \ht\fm@box} \fi% \if@twocolumn \emergencystretch=1pc \twocolumn[\unvbox\fm@box] \else \unvbox\fm@box \fi} % \def\output@glob@notes{\bgroup \the\t@glob@notes \egroup} % \def\justify@off{\let\\=\@normalcr \leftskip\z@ \@rightskip\@flushglue \rightskip\@rightskip} \def\justify@on{\let\\=\@normalcr \parfillskip\@flushglue% \leftskip\z@ \@rightskip\z@ \rightskip\@rightskip} % \def\normal@text{\global\let\\=\@normalcr \global\leftskip\z@ \global\@rightskip\z@ \global\rightskip\@rightskip \global\parfillskip\@flushglue} % \def\@writecount{\write\@mainaux{\string\global \string\@namedef{n@author@}{\the\n@author}}% } % % TITLE \def\pretitle#1{% \vspace*{\b@pretitle@skip}\pretitle@size#1\par\vskip6\p@\hrule \vskip12\p@} % \def\title#1{% \beg@elem \title@note@fmt \add@tok\t@glob@notes {\title@note@fmt}% \proc@elem{title}{#1}% \def\title@notes{\the\t@loc@notes}% \title@fmt{\@title}{\title@notes}% \ignorespaces} % \newdimen\@@topskip \@@topskip=24\p@ % \def\title@fmt#1#2{% \vspace*{\@@topskip} {\title@size #1\hbox{$^{#2}$}\par}% \vskip\a@title@skip% } % \def\subtitle#1{% \beg@elem \proc@elem{subtitle}{#1}% \def\title@notes{\the\t@loc@notes}% \subtitle@fmt{\@subtitle}{\title@notes}% \ignorespaces} % % \def\subtitle@fmt#1#2{% {\subtitle@size #1\,\hbox{$^{\mathrm{#2}}$}\par}% \vskip\a@title@skip% } % \def\title@note@fmt{\def\thefootnote{\arabic{footnote}}} % % AUTHOR % \newdimen\b@author@skip \b@author@skip 12\p@ % \def\author{\@ifnextchar[{\author@optarg}{\author@optarg[]}} % \def\author@optarg[#1]#2{\stepcounter{author}% \beg@elem\def\degs##1{##1}\def\fnms##1{##1}\def\inits##1{##1}% \def\snm##1{\MakeUppercase{##1}}\def\roles##1{##1}% \if@firstauthor% \first@author \global\@firstauthorfalse \fi% \@for\@tempa:=#1\do{\expandafter\add@addressref\expandafter{\@tempa}}% \proc@elem{author}{#2}% \author@fmt{\the\c@author}{\the\t@loc@notes}{\@author}}% % %\newbox\author@box % \def\author@fmt#1#2#3{\@newelemtrue \ifnum\prev@elem=\e@author \global\@newelemfalse \fi \if@newelem \author@fmt@init \fi \edef\@tempb{#2}\ifx\@tempb\@empty \hbox{#3}\else \hbox{#3\,$^{\mathrm{#2}}$}% \fi} % \def\first@author{\author@note@fmt% \add@tok\t@glob@notes% {\author@note@fmt}}% % \def\author@fmt@init{% \par \vskip \b@author@skip \authors@size\centering \leavevmode} % \def\and{\unskip~and~} % \def\author@note@fmt{% \def\thefootnote{\arabic{footnote}}} % \def\sxarabic#1{% \expandafter\ifcase\value{#1} \or *\or **\or *** \or **** \or *****\fi } % % ADDRESS % \def\email#1{{e-mail:\ #1}} % \def\address{\@ifstar{\address@star}% {\@ifnextchar[{\address@optarg}{\address@noptarg}}} % \def\address@optarg[#1]#2{\refstepcounter{address}% \beg@elem \proc@elem{address}{#2}% \address@fmt{\the\c@address}{\the\t@loc@notes}{\@address}\label{#1}% \ignorespaces} % \def\address@noptarg#1{\refstepcounter{address}% \beg@elem \proc@elem{address}{#1}% \address@fmt{\z@}{\the\t@loc@notes}{\@address}% \ignorespaces} % \def\address@star#1{% \beg@elem \proc@elem{address}{#1}% \address@fmt{\m@ne}{\the\t@loc@notes}{\@address}% \ignorespaces} % \def\theaddress{\alph{address}} % \def\address@fmt#1#2#3{\@newelemtrue \ifnum\prev@elem=\e@address \@newelemfalse \fi \if@newelem \address@fmt@init \fi \bgroup\parskip\z@\noindent\centering \address@size \ifnum#1=\z@ #3\,$^{\mathrm{#2}}$\space% \else \ifnum#1=\m@ne $^{\phantom{\mathrm{\theaddress}}\,}$#3\,$^{\mathrm{#2}}$% \else $^{\mathrm{\theaddress}\,}$#3\,$^{\mathrm{#2}}$% \fi \fi \par\egroup} % \def\address@fmt@init{% \def\@currentlabel{\theaddress} \par \vskip 2\p@ plus 1\p@ minus 1\p@} % % ABSTRACT % \def\abstract{\@ifnextchar[{\@abstract}{\@abstract[]}} \def\@abstract[#1]{% \global\@hasabstracttrue \hyphenpenalty\sv@hyphenpenalty \global\setbox\t@abstract=\vbox\bgroup \linewidth\abstract@width \hsize\abstract@width \justify@on\abstract@size\parindent 1em \abstract@indent\textbf{\abstractname}\ignorespaces} \def\endabstract{\par\egroup} % % KEYWORDS \def\sep{\unskip, } \global\@haskeywordsfalse \newdimen\dp@t@keywords \def\keyword{\global\@haskeywordstrue% \global\setbox\t@keywords=\vbox\bgroup% \hsize\abstract@width% \justify@on\abstract@size\parindent 0\p@ \textbf{\keywordsname}\ignorespaces } \def\endkeyword{\par\egroup\global\dp@t@keywords=\dp\t@keywords} \def\keywords#1{\begin{keyword}#1\end{keyword}} % % % % Running title \def\runningtitle#1{\gdef\@runtitle{#1}} \def\@runtitle{} \def\runningauthor#1{{\def\etal{et al.}\gdef\@runauthor{#1\@runsep}}} \def\@runauthor{} \def\runningsep#1{\gdef\@runsep{#1}} \def\@runsep{\ /\ } % \def\journal#1{\gdef\@journal{#1}} \@ifundefined{@journal}{\gdef\@journal{Journal not defined}}{} \def\volume#1{\gdef\@volume{#1}} \def\@volume{0} \def\issue#1{\gdef\@issue{#1}} \def\@issue{0} % % \newcount\@pubyear \newcount\@copyear \@pubyear=\number\year \@copyear\@pubyear \advance\@copyear-2000 \def\pubyear#1{\global\@pubyear#1 \global\@copyear\@pubyear \global\advance\@copyear-2000% \ignorespaces} % \def\the@copyear{\ifnum\@copyear<10 0\fi\the\@copyear} % \pubyear{2003} % \def\firstpage#1{\def\@tempa{#1}\ifx\@tempa\@empty\else \gdef\@firstpage{#1}\gdef\@lastpage{#1}% \global\c@page=#1 \ignorespaces\fi } \def\@firstpage{1} \def\lastpage#1{\def\@tempa{#1}\ifx\@tempa\@empty\else \gdef\@lastpage{#1}\ignorespaces\fi} \def\@lastpage{0} \def\@pagerange{1--0} % Write the last page: \def\write@last@page{% \write\@mainaux{\string\global\string\@namedef{@lastpage}{\the\c@page}}} \AtEndDocument{\write@last@page} % SGML \long\def\convertas#1#2{#2} \def\sday#1{#1}\def\smonth#1{#1}\def\syear#1{#1} \def\aid#1{\gdef\@aid{#1}} % \def\SSDI#1{\gdef\@ssdi{#1}} \def\@ssdi{000000-00} \def\issn#1{\gdef\@issn{#1}} \def\price#1{\gdef\@price{#1}} % \def\date#1{\gdef\@date{#1}} \def\@date{\today} % \def\empty@data{\@nil} % %***************** BACKMATTER \newcommand\backmatter{\goodbreak} %**************** INICIALIZATION \newcommand\refname{References} \newcommand\figurename{Figure} \newcommand\tablename{Table} \newcommand\algorithmname{Algorithm} \newcommand\appendixname{Appendix} \newcommand\abstractname{Abstract. } \newcommand\keywordsname{Keywords. } \def\acknowledgementsname{Acknowledgements} % \def\copyright@sign{\copyright} % % DIMENSIONS \def\@articletypesize{\large} \def\pretitle@size{\LARGE} \def\title@size{\huge} \def\subtitle@size{\large\itshape} \def\authors@size{\normalsize} \def\abstract@size{\footnotesize} \def\abstract@width{22pc} \def\abstract@indent{\noindent} \def\address@size{\normalsize\itshape} % Block preparation of contents: \def\addcontentsline#1#2#3{} \long\def\addtocontents#1#2{} % \newcommand\today{} \edef\today{\ifcase\month\or January\or February\or March\or April\or May\or June\or July\or August\or September\or October\or November\or December\fi \space\number\day, \number\year} % \@twosidetrue \pagenumbering{arabic} \frenchspacing \init@settings \if@twocolumn\setlength\tablewidth{\columnwidth} \else\setlength\tablewidth{\textwidth}\fi %\pagestyle{headings} \pagestyle{empty} \endinput %% %% End of file `IOS-Book-Article.cls'. ================================================ FILE: marktoberdorf_paper/forPublisher/css.sty ================================================ %--------------------------------------------------------------------------- % Copyright 2013 Microsoft Corporation. % % This is free software; you can redistribute it and/or modify it under the % terms of the Apache License, Version 2.0. A copy of the License can be % found in the file "license.txt" at the root of this distribution. %--------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage{iftex} \RequirePackage{etoolbox} \RequirePackage{xkeyval} \RequirePackage[table]{xcolor} \RequirePackage{mdframed} \RequirePackage{graphicx} \RequirePackage{tablefootnote} % font selection \ifXeTeX\RequirePackage{fontspec}\else \ifLuaTeX\RequirePackage{fontspec}\else \providecommand{\fontspec}[2][]{} \fi\fi % Define CSS 17 standard colors \definecolor{Red}{HTML}{FF0000} \definecolor{Lime}{HTML}{00FF00} \definecolor{Blue}{HTML}{0000FF} \definecolor{Yellow}{HTML}{FFFF00} \definecolor{Cyan}{HTML}{00FFFF} \definecolor{Magenta}{HTML}{FF00FF} \definecolor{Navy}{HTML}{000080} \definecolor{Maroon}{HTML}{800000} \definecolor{Green}{HTML}{008000} \definecolor{Teal}{HTML}{008080} \definecolor{Purple}{HTML}{800080} \definecolor{Olive}{HTML}{808000} \definecolor{Black}{HTML}{000000} \definecolor{Dimgray}{HTML}{696969} \definecolor{Gray}{HTML}{808080} \definecolor{Darkgray}{HTML}{A9A9A9} \definecolor{Silver}{HTML}{C0C0C0} \definecolor{Lightgray}{HTML}{D3D3D3} \definecolor{Gainsboro}{HTML}{DCDCDC} \definecolor{Floralwhite}{HTML}{FFFAF0} \definecolor{Ivory}{HTML}{FFFFF0} \definecolor{White}{HTML}{FFFFFF} \definecolor{Orange}{HTML}{FFA500} \definecolor{Aqua}{HTML}{00FFFF} \definecolor{Fuchsia}{HTML}{FF00FF} % --------------------------------------------- % Basic LaTeX helpers % --------------------------------------------- % use '\defcommand' to define a command no matter if it is predefined or not \def\defcommand{\@ifstar\defcommand@S\defcommand@N} \def\defcommand@S#1{\let#1\outer\renewcommand*#1} \def\defcommand@N#1{\let#1\outer\renewcommand#1} \def\providecsgdef#1{\ifcsdef{#1}{\providecommand\@foo}{\csgdef{#1}}} \providecommand\@swap[2]{#2#1} \providecommand\@swaparg[2]{#2{#1}} \providecommand\expandnext[2]{\expandafter\@swaparg\expandafter{#2}{#1}} \newcommand\@expandafter\expandnext %legacy \newcommand\expandnextii[3]{\expandnext{\expandnext{#1}{#2}}{#3}} \newcommand\expandnextiii[4]{\expandnext{\expandnextii{#1}{#2}{#3}}{#4}} \newcommand\expandnextiv[5]{\expandnext{\expandnextiii{#1}{#2}{#3}{#4}}{#5}} \newcommand{\eifstrequal}{\expandafter\ifstrequal\expandafter} \newcommand{\eeifstrequal}[2]{\expandnext{\eifstrequal{#1}}{#2}} \providecommand\providelength[1]{% \begingroup \escapechar\m@ne \xdef\@gtempa{\string#1}% \endgroup \@ifundefined{\@gtempa}% {\newskip#1}% {}% } % is a string an element of a list of (comma separated) strings \newcommand{\eifstrelement}[4]{% \def\@found{}% \@for\@ii:=#2\do{% \eeifstrequal{\@ii}{#1}{\def\@found{true}}{}% }% \ifdefvoid{\@found}{#4}{#3}% } % do two lists of strings intersect? \newcommand{\ifintersect}[4]{% \def\@intersect{}% \@for\@sname:=#1\do{% \ifdefvoid{\@intersect}{% \eifstrelement{\@sname}{#2}{\def\@intersect{true}}{}% }{}% }% \ifdefvoid{\@intersect}{#4}{#3}% } % get string head and tail \def\strsplit#1{\expandafter\strsplitx#1\empty\empty\empty} \def\strsplitx#1#2\empty{% \edef\strhead{#1}% \edef\strtail{#2}% } % normalize colors: to lowercase and then capitalize \newcommand{\cssDefNormalizeColor}[2]{% \expandafter\@cssNormColor#2\empty{#1}\empty% } \def\@cssNormColor#1#2\empty#3\empty{% \uppercase{\def\@hd{#1}}\lowercase{\def\@tl{#2}}% \expandafter\global\expandafter\edef\csname #3\endcsname{\@hd\@tl}% } % --------------------------------------------------- % Some TeX stuff to compose functions % --------------------------------------------------- \newcommand{\apptox}[2]{% apptox{\cmd1}{\cmd2} == newcommand{\cmd1'}[1]{\cmd1{\cmd2{#1}}} \providecommand{#1}[1]{##1}% define it if necessary (as identity) \protected@edef#1##1{#1{\protect #2{##1}}}% } \newcommand{\pretox}[2]{% pretox{\cmd1}{\cmd2} == newcommand{\cmd1'}[1]{\cmd2{\cmd1{#1}}} \providecommand{#1}[1]{##1}% \protected@edef#1##1{\protect #2{#1{##1}}}% } %------------------------------------------------------------- % Save footnotes inside mdframed and minipage environments %------------------------------------------------------------- \newif\if@saveFootnotes \newcommand{\cssSaveFootnotes}% {\if@saveFootnotes\else% \let\footnote\tablefootnote% \fi% \@saveFootnotestrue}% \newcommand{\cssRestoreFootnotes}% {\if@saveFootnotes\else% \tfn@tablefootnoteprintout% \gdef\tfn@fnt{0}% \fi}% %------------------------------------------------------------- % Setup mdframed with default values %------------------------------------------------------------- \newlength{\cssPixel}\setlength{\cssPixel}{0.4pt}% assume 180 dpi \mdfsetup{% leftmargin=0pt,% rightmargin=0pt,% skipabove=0pt,% skipbelow=0pt,% innertopmargin=0pt,% innerbottommargin=0pt,% innerleftmargin=0pt,% innerrightmargin=0pt,% middlelinewidth=0pt,% linewidth=0pt,% outerlinewidth=0pt,innerlinewidth=0pt% } % --------------------------------------------------- % Basic command to process attributes passed to TeX % --------------------------------------------------- \newif\if@usewrap \newcommand{\@doBefore}{} \newcommand{\@doAfter}{} \newcommand{\@wrapCmd}[1]{#1} \newcommand{\@cssUseCmd}{\renewcommand{\@wrapCmd}[1]{##1}\renewcommand{\@doAfter}{}\@usewraptrue} \newcommand{\@cssUseEnv}{\renewcommand{\@doBefore}{}\renewcommand{\@doAfter}{}\@usewrapfalse} \newcommand{\@cssApplyCmd}[1]{{\@wrapCmd{#1}}} \newcommand{\@cssApplyBefore}{\@doBefore{}} \newcommand{\@cssApplyAfter}{\@doAfter{}} \newcommand{\@cssProcessAttrs}[2]{% \setkeys*{cssx}{#1}\setrmkeys*{csspre}\setrmkeys*{css}\setrmkeys*{csspost}% defaults \@cssApplyRulesFor{parentclass}{css}{\cssParentClass}% \setkeys*{cssx}{#2}\setrmkeys*{csspre}\setrmkeys*{css}\setrmkeys*{csspost}% regular \protected@edef\cssParentClass{\cssClass}% } \newcommand{\@cmdBefore}[2]{#1#2} \newcommand{\@cmdAfter}[2]{#2#1} \newcommand{\cssWrapCmd}[1]{\apptox{\@wrapCmd}{#1}} \newcommand{\cssDoBeforeX}[1]{#1} \newcommand{\cssDoAfterX}[1]{\preto\@doAfter{#1}} \newcommand{\cssDoBefore}[1]{\if@usewrap\cssWrapCmd{\@cmdBefore{#1}}\else #1\fi} \newcommand{\cssDoAfter}[1]{\if@usewrap\cssWrapCmd{\@cmdAfter{#1}}\else\preto\@doAfter{#1}\fi} %\newcommand{\cssDoBeforeX}[1]{\if@usewrap\cssWrapCmd{\@cmdBefore{#1}}\else #1\fi} %\newcommand{\cssDoAfterX}[1]{\if@usewrap\cssWrapCmd{\@cmdAfter{#1}}\else\preto\@doAfter{#1}\fi} \newcommand{\cssDoEnv}[1]{\cssDoBefore{\protect\begin{#1}}\cssDoAfter{\protect\end{#1}}} \newcommand{\cssDoEnvOpt}[2]{\cssDoBefore{\begin{#1}[#2]}\cssDoAfter{\end{#1}}} \newcommand{\cssDoEnvArg}[2]{\cssDoBefore{\begin{#1}{#2}}\cssDoAfter{\end{#1}}} \newcommand{\cssDoEnvArgII}[3]{\cssDoBefore{\begin{#1}{#2}{#3}}\cssDoAfter{\end{#1}}} \newcommand{\newKey}[4][]{\define@key{#2}{#3}[#1]{#4}} \newcommand{\newLength}[2]{\providelength{#1}\setlength{#1}{#2}} \newcommand{\@cssReset}{} \newcommand{\cssAddReset}[1]{\appto{\@cssReset}{#1}} \newcommand{\cssNewResetCommand}[2]{\newcommand{#1}{#2}\cssAddReset{\renewcommand{#1}{#2}}} \newlength{\cssFill} \setlength{\cssFill}{2sp plus 1fill minus 2sp} % make \fill unequal to 0pt, and detectable as 2sp \newcommand{\cssNewLengthKey}[4][0pt]{% \newLength{#4}{#1}% \newKey{#2}{#3}{% \ifstrequal{##1}{auto}{\setlength{#4}{\cssFill}}{\setlength{#4}{##1}}% }% \cssAddReset{\setlength{#4}{#1}}% } \newcommand{\cssNewKeyNoReset}[4]{% \newcommand{#3}{#4}% \newKey{#1}{#2}{\renewcommand{#3}{##1}}% } \newcommand{\cssNewKey}[4]{% \cssNewResetCommand{#3}{#4}% \newKey{#1}{#2}{%(#2=##1)%debug key setting \renewcommand{#3}{##1}}% } \newcommand{\cssNewKeyX}[5]{% \cssNewResetCommand{#3}{#4}% \newKey{#1}{#2}{\renewcommand{#3}{##1}#5{##1}}% } \newcommand{\cssNewListKey}[4]{% \cssNewResetCommand{#3}{#4}% \newKey{#1}{#2}{\appto{#3}{,##1}}% } \newcommand{\cssNewListKeyX}[5]{% \cssNewResetCommand{#3}{#4}% \newKey{#1}{#2}{\appto{#3}{,##1}#5{##1}}% } \newcommand{\cssNewPseudoKey}[3]{% \newKey{#1}{#2}{\setkeys{#1}{#3}}% } %------------------------------------------------------------- % css: display %------------------------------------------------------------- \cssNewKey{css}{display}{\cssDisplay}{block} %------------------------------------------------------------- % css: width, height, and margins %------------------------------------------------------------- \cssNewLengthKey{css}{margin-left}{\cssMarginLeft} \cssNewLengthKey{css}{margin-right}{\cssMarginRight} \cssNewLengthKey{css}{margin-top}{\cssMarginTop} \cssNewLengthKey{css}{margin-bottom}{\cssMarginBottom} \cssNewLengthKey[1sp]{css}{width}{\cssWidth} \cssNewLengthKey[1sp]{css}{height}{\cssHeight} \cssNewKey{css}{vertical-align}{\cssVerticalAlign}{} \cssNewPseudoKey{css}{margin}{margin-top=#1,margin-bottom=#1,margin-left=#1,margin-right=#1} \newcommand{\@cssProcessMargins}{% \eifstrequal{\cssDisplay}{block}% {\@cssBlockEndPar\@cssBlockMargins}% {\eifstrequal{\cssDisplay}{inline-block}% {\@cssBlockMargins}% {\@cssInlineMargins}% }% } \newcommand{\@cssBlockEndPar}{% \cssIfHasClass{para-continue,para-block}{}{\cssDoAfterX{\leavevmode\par\global\hangindent=0pt\relax}}% } \newif\if@hasdim \newlength{\cssHeightFull} % height including padding and border \newlength{\cssWidthFull} % width including padding and border \newLength{\@cssMarginAfter}{0pt} \newLength{\@cssParSkip}{\parskip} \newLength{\@cssParIndent}{\parindent} \newcommand{\@cssFixMathSpacing}{\strut\vspace{-\baselineskip}} % fixes weird abovedisplay skip spacing \newcommand{\@cssBlockMargins}{% \@hasdimfalse \ifdim\cssWidth=1sp\setlength{\cssWidthFull}{1sp}\else\@hasdimtrue\fi \ifdim\cssHeight=1sp\setlength{\cssHeightFull}{1sp}\else\@hasdimtrue\fi \if@hasdim% % set full height and width \setlength{\cssWidthFull}{\dimexpr\cssWidth+\cssPaddingLeft+\cssPaddingRight\relax}% \eifstrequal{\cssBorderLeftStyle}{none}{}{\addtolength{\cssWidthFull}{\cssBorderWidth}}% \eifstrequal{\cssBorderRightStyle}{none}{}{\addtolength{\cssWidthFull}{\cssBorderWidth}}% \setlength{\cssHeightFull}{\dimexpr\cssHeight+\cssPaddingTop+\cssPaddingBottom\relax}% \eifstrequal{\cssBorderTopStyle}{none}{}{\addtolength{\cssHeightFull}{\cssBorderWidth}}% \eifstrequal{\cssBorderBottomStyle}{none}{}{\addtolength{\cssHeightFull}{\cssBorderWidth}}% % set default width? \ifdim\cssWidth=1sp% in this case, cssWidthFull is just padding and borders \setlength{\cssWidth}{\dimexpr\linewidth-\cssWidthFull-\cssMarginLeft-\cssMarginRight}% \addtolength{\cssWidthFull}{\cssWidth}% \fi% %minipage \ifdim\cssMarginTop=0pt\else\cssDoBeforeX{\vspace{\cssMarginTop}}\fi \ifdim\cssMarginLeft=0pt\else\cssDoBeforeX{\hspace*{\cssMarginLeft}}\fi \setlength{\@cssParIndent}{\parindent}% save parskip and parindent since minipage resets it \setlength{\@cssParSkip}{\parskip}% \eifstrequal{\cssVerticalAlign}{bottom}{\def\@cssValign{b}}% {\eifstrequal{\cssVerticalAlign}{center}{\def\@cssValign{c}}% {\eifstrequal{\cssVerticalAlign}{top}{\def\@cssValign{t}}% {\def\@cssValign{c}}}}% including `middle` \ifdim\cssHeight=1sp% \cssDoBeforeX{\begin{minipage}[\@cssValign]{\cssWidthFull}}% \else \cssDoBeforeX{\begin{minipage}[\@cssValign][\cssHeightFull]{\cssWidthFull}}% \fi \cssDoBeforeX{\cssSaveFootnotes\setlength{\parskip}{\@cssParSkip}\setlength{\parindent}{\@cssParIndent}}% %note: DoAfter prepends, so in opposite order \ifdim\cssMarginBottom=0pt\else\cssDoAfterX{\vspace{\cssMarginBottom}}\fi \ifdim\cssMarginRight=0pt\else\cssDoAfterX{\hspace*{\cssMarginRight}}\fi \cssDoAfterX{\end{minipage}\cssRestoreFootnotes}% \else % no height/width: trivlist \@hasdimfalse \ifdim\cssMarginLeft=0pt\else\@hasdimtrue\fi \ifdim\cssMarginRight=0pt\else\@hasdimtrue\fi \ifdim\cssMarginTop=0pt\else\@hasdimtrue\fi \ifdim\cssMarginBottom=0pt\else\@hasdimtrue\fi \if@hasdim \setlength{\@cssMarginAfter}{\dimexpr\cssMarginBottom-\cssMarginTop\relax}% \list{}{% \leftmargin=\cssMarginLeft% \rightmargin=\cssMarginRight% \topsep=\cssMarginTop% \itemsep=0pt% \parsep=0pt% \parskip=0pt% \partopsep=0pt% \listparindent=\parindent% }% \cssDoAfterX{\endlist}% \ifdim\@cssMarginAfter=0pt\else\cssDoAfter{\vspace{\@cssMarginAfter}}\fi% \eifstrequal{\cssTextAlign}{left}% we need to do alignment here for inline cmds' with a display=block {\raggedright}% {\eifstrequal{\cssTextAlign}{right}% {\raggedleft}% {\eifstrequal{\cssTextAlign}{center}% {\centering}% {}}}% \cssIfHasClass{math-display}% {\item\@cssFixMathSpacing}% {\item\relax}% \fi \fi } \newcommand{\@cssHide}[1]{} \newcommand{\@cssInlineMargins}{% \ifdim\cssMarginLeft=0pt\else\cssDoBefore{\hspace*{\cssMarginLeft}}\fi \ifdim\cssMarginRight=0pt\else\cssDoAfter{\hspace*{\cssMarginRight}}\fi \ifdim\cssMarginBottom=0pt\else\cssDoBefore{\rule[-\cssMarginBottom]{0pt}{\cssMarginBottom}}\fi \ifdim\cssMarginTop=0pt\else\cssDoBefore{\rule{0pt}{\dimexpr\baselineskip*0.7+\cssMarginTop\relax}}\fi \eifstrequal{\cssDisplay}{hidden}{% \cssWrapCmd{\@cssHide}% }{}% } %------------------------------------------------------------- % css: Borders and padding %------------------------------------------------------------- \cssNewLengthKey{css}{padding-left}{\cssPaddingLeft} \cssNewLengthKey{css}{padding-right}{\cssPaddingRight} \cssNewLengthKey{css}{padding-top}{\cssPaddingTop} \cssNewLengthKey{css}{padding-bottom}{\cssPaddingBottom} \newlength{\cssBorderWidthTotal} \cssNewLengthKey[\cssPixel]{css}{border-width}{\cssBorderWidth} \cssNewKey{css}{border-color}{\cssBorderColor}{black} \cssNewKey{css}{border-top-style}{\cssBorderTopStyle}{none} \cssNewKey{css}{border-bottom-style}{\cssBorderBottomStyle}{none} \cssNewKey{css}{border-left-style}{\cssBorderLeftStyle}{none} \cssNewKey{css}{border-right-style}{\cssBorderRightStyle}{none} \cssNewKey{css}{background-color}{\cssBackgroundColor}{white} \cssNewPseudoKey{css}{padding}{padding-top=#1,padding-bottom=#1,padding-right=#1,padding-left=#1} \cssNewPseudoKey{css}{border-style}% {border-top-style=#1,border-bottom-style=#1,border-left-style=#1,border-right-style=#1} \newcommand{\@cssProcessPadding}{% \eifstrequal{\cssDisplay}{block}% {\@cssBlockPadding}% {\eifstrequal{\cssDisplay}{block-inline}% {\@cssBlockPadding}% {\@cssInlinePadding}% }} % Special math-framed environment that fixes vertical spacing around math display \newenvironment{mdmathframed}[1][]% {\begin{mdframed}[#1]\@cssFixMathSpacing}% {\@cssFixMathSpacing\end{mdframed}} \newif\if@needframe \newLength{\@cssPaddingLength}{0pt} \newcommand{\@cssFramedArgs}{} \newcommand{\@cssBorderStyleAll}{} \newcommand{\@cssBlockPadding}{% \@needframefalse% \eifstrequal{\cssBorderTopStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderBottomStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderLeftStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderRightStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBackgroundColor}{white}{}{\@needframetrue}% \ifdim\cssPaddingTop=0pt\else\@needframetrue\fi \ifdim\cssPaddingBottom=0pt\else\@needframetrue\fi \ifdim\cssPaddingLeft=0pt\else\@needframetrue\fi \ifdim\cssPaddingRight=0pt\else\@needframetrue\fi \strsplit{\cssBackgroundColor}% \eifstrequal{\strhead}{\#}% {\definecolor{Temp}{HTML}{\strtail}\edef\@@bcolor{Temp}}% {\cssDefNormalizeColor{@bcolor}{\cssBackgroundColor}\edef\@@bcolor{\@bcolor}}% %\expandafter\lowercase\expandafter{\expandafter\def\expandafter\bcolor\expandafter{\cssBackgroundColor}}% \if@needframe% \cssDoAfter{\cssRestoreFootnotes}% first, because post commands are pre-pended \renewcommand{\@cssFramedArgs}{% innertopmargin=\the\cssPaddingTop,% innerbottommargin=\the\cssPaddingBottom,% innerleftmargin=\the\cssPaddingLeft,% innerrightmargin=\the\cssPaddingRight,% linewidth=\the\cssBorderWidth,% linecolor=\cssBorderColor,% backgroundcolor=\@@bcolor% }% \setlength{\cssBorderWidthTotal}{0pt}% \eifstrequal{\cssBorderTopStyle}{none}{\appto{\@cssFramedArgs}{,topline=false}}{}% \eifstrequal{\cssBorderBottomStyle}{none}{\appto{\@cssFramedArgs}{,bottomline=false}}{}% \eifstrequal{\cssBorderLeftStyle}{none}{\appto{\@cssFramedArgs}{,leftline=false}}% {\addtolength{\cssBorderWidthTotal}{\cssBorderWidth}}% \eifstrequal{\cssBorderRightStyle}{none}{\appto{\@cssFramedArgs}{,rightline=false}}% {\addtolength{\cssBorderWidthTotal}{\cssBorderWidth}}% \cssIfHasClass{math-display}% {\expandnext{\cssDoEnvOpt{mdmathframed}}{\@cssFramedArgs}}% {\expandnext{\cssDoEnvOpt{mdframed}}{\@cssFramedArgs}}% % insert a minipage if height or width was set so the frame is as large \@hasdimfalse \ifdim\cssWidth=1sp\else\@hasdimtrue\fi \ifdim\cssHeight=1sp\else\@hasdimtrue\fi \if@hasdim% \ifdim\cssHeight=1sp% \cssDoBefore{\begin{minipage}{\cssWidth}}% \else \cssDoBefore{\begin{minipage}[t][\cssHeight]{\cssWidth}}% \fi \cssDoBefore{\setlength{\parskip}{\@cssParSkip}\setlength{\parindent}{\@cssParIndent}}% %note: DoAfter prepends, so in opposite order \cssDoAfter{\end{minipage}}% \fi \cssDoBefore{\cssSaveFootnotes}% \fi } \newcommand{\@robustFramebox}[2]{% \eifstrequal{\cssTextAlign}{center}{\framebox[#1][c]{#2}}% {\eifstrequal{\cssTextAlign}{right}{\framebox[#1][r]{#2}}% {\framebox[#1][l]{#2}}}% } \newcommand{\@robustMakebox}[2]{% \eifstrequal{\cssDisplay}{table-cell}% {\@robustTableParbox{#1}{#2}}% {\eifstrequal{\cssTextAlign}{center}{\makebox[#1][c]{#2}}% {\eifstrequal{\cssTextAlign}{right}{\makebox[#1][r]{#2}}% {\makebox[#1][l]{#2}}}}% } \newcommand{\@robustRaisebox}[2]{% \raisebox{#1}{#2}% } \newcommand{\@robustHeight}[1]{% \eifstrequal{\cssVerticalAlign}{top}% {\raisebox{0pt}[0pt][\cssHeight]{#1}}% {\eifstrequal{\cssVerticalAlign}{middle}% {\raisebox{0pt}[0.5\cssHeight][0.5\cssHeight]{#1}}% {\eifstrequal{\cssVerticalAlign}{baseline}% {\raisebox{0pt}[\dimexpr\cssHeight-\depth\relax][\depth]{#1}}% {\raisebox{0pt}[\cssHeight][0pt]{#1}}% bottom }}% } \newcommand{\@robustTableParbox}[2]{% \eifstrequal{\cssVerticalAlign}{top}{\def\@cssValign{t}}% {\eifstrequal{\cssVerticalAlign}{center}{\def\@cssValign{c}}% {\eifstrequal{\cssVerticalAlign}{middle}{\def\@cssValign{c}}}% {\def\@cssValign{b}}}% \ifdim\cssHeight=1sp% \parbox[\@cssValign]{#1}{#2}% \else% \parbox[\@cssValign][\cssHeight]{#1}{#2}% \fi% } \newcommand{\@cssInlinePadding}{% \eifstrequal{\cssBackgroundColor}{}{}% {\eifstrequal{\cssBackgroundColor}{white}{}% {\strsplit{\cssBackgroundColor}% \eifstrequal{\strhead}{\#}% {\cssWrapCmd{\protect\colorbox[HTML]{\strtail}}}% {\cssWrapCmd{\@robustColorbox{\cssBackgroundColor}}}% }% }% \@needframefalse% \eifstrequal{\cssBorderTopStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderBottomStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderLeftStyle}{none}{}{\@needframetrue}% \eifstrequal{\cssBorderRightStyle}{none}{}{\@needframetrue}% \if@needframe% \setlength{\fboxrule}{\cssBorderWidth}% \ifdim\cssWidth=1sp% \cssWrapCmd{\fbox}% \else \cssWrapCmd{\@robustFramebox{\cssWidth}}% \fi \else \ifdim\cssWidth=1sp\else \cssWrapCmd{\@robustMakebox{\cssWidth}}% \fi \fi % height? \ifdim\cssHeight=1sp\else\cssWrapCmd{\@robustHeight}\fi % raisebox? \eifstrequal{\cssDisplay}{inline}{% \eifstrequal{\cssVerticalAlign}{}{}% {\eifstrequal{\cssVerticalAlign}{top}{}% {\eifstrequal{\cssVerticalAlign}{bottom}{}% {\eifstrequal{\cssVerticalAlign}{middle}{}% {\eifstrequal{\cssVerticalAlign}{baseline}{}% {\cssWrapCmd{\@robustRaisebox{\cssVerticalAlign}}% }}}}}% }{}% % padding \if@needframe \setlength{\fboxsep}{\cssPaddingTop}% todo: define our own box so we can set paddingtop/bot separately \ifdim\cssPaddingBottom>\fboxsep\setlength{\fboxsep}{\cssPaddingBottom}\fi \ifdim\cssPaddingLeft=\fboxsep\else\hspace*{\dimexpr\cssPaddingLeft-\fboxsep\relax}\fi \ifdim\cssPaddingRight=\fboxsep\else\hspace*{\dimexpr\cssPaddingRight-\fboxsep\relax}\fi \else \ifdim\cssPaddingLeft=0pt\else\cssDoBefore{\hspace*{\cssPaddingLeft}}\fi \ifdim\cssPaddingRight=0pt\else\cssDoAfter{\hspace*{\cssPaddingRight}}\fi \ifdim\cssPaddingBottom=0pt\else\cssDoBefore{\protect\rule[-\cssPaddingBottom]{0pt}{\cssPaddingBottom}}\fi \ifdim\cssPaddingTop=0pt\else\cssDoBefore{\protect\rule{0pt}{\dimexpr\cssPaddingTop+0.8em\relax}}\fi \fi } %------------------------------------------------------------- % css: Textalign, textindent etc %------------------------------------------------------------- \cssNewLengthKey[1sp]{css}{text-indent}{\cssTextIndent} \cssNewKey{css}{text-align}{\cssTextAlign}{justify} \cssNewLengthKey{css}{line-height}{\cssLineHeight} \cssNewKey{css}{float}{\cssFloat}{} \DeclareRobustCommand{\@robustColor}[1]{% \cssDefNormalizeColor{@fcolor}{#1}\color{\@fcolor}% } \DeclareRobustCommand{\@robustColorbox}[2]{% \cssDefNormalizeColor{@bcolor}{#1}\colorbox{\@bcolor}{#2}% } \newcommand{\@cssProcessText}{% \eifstrequal{\cssDisplay}{block}% {\@cssBlockText}% {\eifstrequal{\cssDisplay}{block-inline}% {\@cssBlockText}% {\eifstrequal{\cssDisplay}{table-cell}% {\@cssBlockText}% {\@cssInlineText}% }}} \newcommand{\@cssBlockText}{% \eifstrequal{\cssId}{}{}{\label{\cssId}}% set label \eifstrequal{\cssTextAlign}{left}% {\cssDoBefore{\protect\raggedright}}% {\eifstrequal{\cssTextAlign}{right}% {\cssDoBefore{\protect\raggedleft}}% {\eifstrequal{\cssTextAlign}{center}% {\cssDoBefore{\protect\centering}}% {}}}% \ifdim\cssLineHeight=0pt\else\setlength{\baselineskip}{\cssLineHeight}\fi \ifdim\cssTextIndent=1sp\else\noindent\hspace*{\cssTextIndent}\fi } \newcommand{\@cssInlineText}{% \eifstrequal{\cssId}{}{}{\label{\cssId}}% set label \eifstrequal{\cssFloat}{left}% {\cssDoAfter{\hspace*{\fill}}}% {\eifstrequal{\cssFloat}{right}% {\cssDoBefore{\hspace*{\fill}}}% {\eifstrequal{\cssFloat}{center}% {\cssDoAfter{\hspace*{\fill}}\cssDoBefore{\hspace*{\fill}}}% {}}}% \ifdim\cssLineHeight=0pt\else\cssDoBefore{\rule{0pt}{\cssLineHeight}}\fi } %------------------------------------------------------------- % css: Font attributes %------------------------------------------------------------- \cssNewKey{css}{font-weight}{\cssFontWeight}{} \cssNewKey{css}{font-variant}{\cssFontVariant}{} \cssNewKey{css}{font-style}{\cssFontStyle}{} \cssNewKey{css}{font-size}{\cssFontSize}{} \cssNewKey{css}{font-family}{\cssFontFamily}{} \cssNewKey{css}{color}{\cssColor}{} \cssNewKey{css}{penalty}{\cssPenalty}{} \newcommand{\@cssProcessFont}{% % font family \edef\@fontFamily{\cssFontFamily}% \@for\@ii:=\cssFontFamily\do{% find the last argument in a comma separated list \edef\@fontFamily{\@ii}% }% \eifstrequal{\@fontFamily}{}{}% quick test {\eifstrequal{\@fontFamily}{monospace}% {\cssDoBefore\ttfamily}% {\eifstrequal{\@fontFamily}{serif}% {\cssDoBefore\rmfamily}% {\eifstrequal{\@fontFamily}{sans-serif}% {\cssDoBefore\sffamily}% {\eifstrequal{\@fontFamily}{normal}% {\cssDoBefore\rmfamily}% {\cssDoBefore{\fontspec{\@fontFamily}}}% }}}}% % \eifstrequal{\cssFontWeight}{bold}% {\cssDoBefore\bfseries}% {\eifstrequal{\cssFontWeight}{normal}% {\cssDoBefore\mdseries}% {}}% \eifstrequal{\cssFontVariant}{small-caps}% {\cssDoBefore\scshape}% {\eifstrequal{\cssFontVariant}{normal}% {\cssDoBefore\upshape}% {}}% \eifstrequal{\cssFontStyle}{italic}% {\cssDoBefore\itshape}% {\eifstrequal{\cssFontStyle}{oblique}% {\cssDoBefore\slshape}% {\eifstrequal{\cssFontStyle}{normal}% {\cssDoBefore\upshape}% {}}}% \eifstrequal{\cssFontSize}{}{}% quick test {\eifstrequal{\cssFontSize}{xx-small}% {\cssDoBefore\tiny}% {\eifstrequal{\cssFontSize}{x-small}% {\cssDoBefore\scriptsize}% {\eifstrequal{\cssFontSize}{small}% {\cssDoBefore\small}% {\eifstrequal{\cssFontSize}{medium}% {\cssDoBefore\normalsize}% {\eifstrequal{\cssFontSize}{large}% {\cssDoBefore\large}% {\eifstrequal{\cssFontSize}{x-large}% {\cssDoBefore\Large}% {\eifstrequal{\cssFontSize}{xx-large}% {\cssDoBefore\LARGE}% {\cssDoBefore{\fontsize{\cssFontSize}{1em}\selectfont}% }}}}}}}}% % \eifstrequal{\cssColor}{}{}% {\strsplit{\cssColor}% \eifstrequal{\strhead}{\#}% {\cssDoBefore{\protect\color[HTML]{\strtail}}}% {\cssDoBefore{\@robustColor{\cssColor}}}% }% % \eifstrequal{\cssPenalty}{}{}% {\penalty \cssPenalty\relax}% } %------------------------------------------------------------- % Generic css rules for certain classes, ids, or elements %------------------------------------------------------------- \newcommand{\cssRule}[3]{% \@for\@ii:=#2\do{% \csappto{@rule@#1@\@ii}{,#3}% }% }% \newcommand{\cssRuleDo}[3]{% \@for\@ii:=#2\do{% \csappto{@ruleDo@#1@\@ii}{#3}% }% }% \newcommand{\@cssApplyRulesFor}[3]{% \@for\@ii:=#3\do{% \ifcsmacro{@rule@#1@\@ii}{% \edef\@args{\csname @rule@#1@\@ii\endcsname}% \expandnext{\setkeys{#2}}{\@args}% }{}% }% } \newcommand{\@cssApplyDoRulesFor}[3]{% \@for\@ii:=#3\do{% \ifcsmacro{@ruleDo@#1@\@ii}{% \csname @ruleDo@#1@\@ii\endcsname% }{}% }% } \newcommand{\cssIfHasClass}[3]{% \def\@found{}% \@for\@ii:=\cssClass\do{% \@for\@cname:=#1\do{% \eeifstrequal{\@ii}{\@cname}{% \def\@found{true}% }{}% }% }% \ifdefvoid{\@found}{#3}{#2}% } \newcommand{\cssClassRule}[2]{\cssRule{class}{#1}{#2}} \newcommand{\cssElemRule}[2]{\cssRule{elem}{#1}{#2}} \newcommand{\cssIdRule}[2]{\cssRule{id}{#1}{#2}} \cssNewListKeyX{cssx}{class}{\cssClass}{}{\@cssApplyRulesFor{class}{css}} \cssNewKeyX{cssx}{elem}{\cssElem}{}{\@cssApplyRulesFor{elem}{css}} \cssNewKeyX{cssx}{id}{\cssId}{}{\@cssApplyRulesFor{id}{css}} \newcommand{\cssClassRuleDo}[2]{\cssRuleDo{class}{#1}{#2}} \newcommand{\cssClassRuleCmd}[2]{\cssClassRuleDo{#1}{\cssWrapCmd{#2}}} \newcommand{\cssClassRuleDoBefore}[2]{\cssClassRuleDo{#1}{\cssDoBefore{#2}}} \newcommand{\cssClassRuleDoAfter}[2]{\cssClassRuleDo{#1}{\cssDoAfter{#2}}} \newcommand{\cssClassRuleEnv}[2]{\cssClassRuleDoBefore{#1}{\begin{#2}}\cssClassRuleDoAfter{#1}{#2}} \newcommand{\cssElemRuleDo}[2]{\cssRuleDo{class}{#1}{#2}} \newcommand{\cssElemRuleCmd}[2]{\cssElemRuleDo{#1}{\cssWrapCmd{#2}}} \newcommand{\cssElemRuleDoBefore}[2]{\cssElemRuleDo{#1}{\cssDoBefore{#2}}} \newcommand{\cssElemRuleDoAfter}[2]{\cssElemRuleDo{#1}{\cssDoAfter{#2}}} \newcommand{\cssElemRuleEnv}[2]{\cssElemRuleDo{#1}{\cssDoEnv{#2}}} \newcommand{\@cssClassDoRules}{\@cssApplyDoRulesFor{class}{css}{\cssClass}} \newcommand{\@cssElemDoRules}{% \@cssApplyDoRulesFor{elem}{css}{\cssElem}% \@cssApplyDoRulesFor{id}{css}{\cssId}% } \newcommand{\cssParentClass}{} \newcommand{\cssParentClassRule}[2]{\cssRule{parentclass}{#1}{#2}} %------------------------------------------------------------- % %------------------------------------------------------------- \newenvironment{cssBlockX}[2]% {\@cssReset\@cssUseEnv\@cssProcessAttrs{#1}{#2}% \@cssElemDoRules% \@cssProcessMargins\@cssProcessPadding% \@cssClassDoRules% \@cssProcessText% \@cssProcessFont% \@cssApplyBefore}% {\@cssApplyAfter}% \newenvironment{cssBlock}[1][]% {\begin{cssBlockX}{}{#1}}{\end{cssBlockX}} \newcommand{\cssInlineX}[4]% {\begingroup\@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline,#1}{#2}% \@cssElemDoRules% \@cssProcessMargins\@cssProcessPadding% \@cssClassDoRules% #3% \@cssProcessText\@cssProcessFont% \@cssApplyCmd{#4}\@cssApplyAfter\endgroup% }% \newcommand{\cssInline}[2][]{\cssInlineX{}{#1}{}{#2}} \newcommand{\cssInlineCmd}[3][]{\cssInlineX{}{#1}{\cssWrapCmd{#2}}{#3}} \newcommand{\cssNewBlockElem}[3]{% \newenvironment{#1}[1][]{\begin{cssBlockX}{elem=#2,#3}{##1}}{\end{cssBlockX}}} \newcommand{\cssNewInlineElem}[3]{% \newcommand{#1}[2][]{\cssInlineX{elem=#2,#3}{##1}{}{##2}}} \newcommand{\cssNewInlineElemCmd}[4]{% \newcommand{#1}[2][]{\cssInlineX{elem=#2,#3}{##1}{\cssWrapCmd{#4}}{##2}}} \newcommand{\cssInitKeys}[1]{% \@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline}{#1}% } % cssText is just for font attributes; no padding or margins \newcommand{\cssTextX}[2]% {\@cssReset\@cssUseCmd\@cssProcessAttrs{display=inline}{#1}% \@cssElemDoRules% %\@cssProcessMargins\@cssProcessPadding% \@cssClassDoRules% \@cssProcessText\@cssProcessFont% \@cssApplyCmd{#2}% }% \newcommand{\cssText}[2][]{\cssTextX{#1}{#2}} ================================================ FILE: marktoberdorf_paper/forPublisher/dse.tex ================================================ \documentclass{IOS-Book-Article} % generated by Madoko, version 0.9.3-beta %mdk-data-line={1} \usepackage[heading-base=2]{madoko} \begin{document} %mdk-begin-texraw %mdk-data-line={25} \begin{frontmatter} % The preamble begins here. %\pretitle{Pretitle} \title{Deconstructing Dynamic Symbolic Execution} %\runningtitle{IOS Press Style Sample} %\subtitle{Subtitle} \author[A]{\fnms{Thomas} \snm{Ball}} and \author[B]{\fnms{Jakub} \snm{Daniel}} \runningauthor{Thomas Ball et al.} \address[A]{Microsoft Research} \address[B]{Charles University} \begin{mdDiv}[class={abstract},elem={abstract},data-line={39}]% \begin{mdP}[data-line={40}]% %mdk-data-line={40} {}Dynamic symbolic execution (DSE) is a well-known technique for automatically generating tests to achieve higher levels of coverage in a program. Two keys ideas of DSE are to: (1) seed symbolic execution by executing a program on an initial input; (2) use concrete values from the program execution in place of symbolic expressions whenever symbolic reasoning is hard or not desired. We describe DSE for a simple core language and then present a minimalist implementation of DSE for Python (in Python) that follows this basic recipe. The code is available at https://www.github.com/thomasjball/PyExZ3/ (tagged %mdk-data-line={50} {}{\textquotedblleft}v1.0{\textquotedblright}%mdk-data-line={50} {}) and has been designed to make it easy to experiment with and extend.% \end{mdP}%% \end{mdDiv}% %mdk-begin-texraw %mdk-data-line={56} \begin{keyword} Symbolic Execution, Automatic Test Generation, White-box Testing, Automated Theorem Provers \end{keyword} \end{frontmatter} \thispagestyle{empty} \pagestyle{empty} \mdHxx[id=sec-intro,label={[1]\{.heading-label\}},toc={},data-line={70},caption={[[1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Introduction},bookmark={1.{\hspace{0.5em}}Introduction}]{%mdk-data-line={70} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1}.{\hspace{0.5em}}}%mdk-data-line={70} {}Introduction}%mdk-data-line={73} \defcommand{\mathkw}[1]{\textbf{#1}} \begin{mdP}[data-line={78}]% %mdk-data-line={78} {}Static, path-based symbolic execution explores one control-flow path at a time through a (sequential) program %mdk-data-line={79} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={79} {}, using an automated theorem prover (ATP) to determine if the current path %mdk-data-line={80} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={80} {} is feasible%mdk-data-line={80} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{clarke76}{}{\mdSpan[class={bibitem-label}]{4}}, \mdA[class={bibref,localref},target-element={bibitem}]{king76}{}{\mdSpan[class={bibitem-label}]{11}}]}%mdk-data-line={80} {}. Ideally, symbolic execution of a path %mdk-data-line={81} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={81} {} through program %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={82} {} yields a logic formula %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={82} {} that describes the set of inputs %mdk-data-line={82} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={82} {} (possibly empty) to program %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={83} {} such that for any %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$i \in I$}%mdk-data-line={83} {}, the execution %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={83} {} follows path %mdk-data-line={83} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={83} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={85}]% %mdk-data-line={85} {}If the formula %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={85} {} is unsatisfiable then %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={85} {} is empty and so path %mdk-data-line={85} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={85} {} is not feasible; if the formula is satisfiable then %mdk-data-line={86} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={86} {} is not empty and so path %mdk-data-line={86} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={86} {} is feasible. In this case, a model of %mdk-data-line={87} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={87} {} provides a witness %mdk-data-line={87} {}\mdSpan[class={math-inline},elem={math-inline}]{$i \in I$}%mdk-data-line={87} {}. Thus, a model-generating ATP can be used in conjunction with symbolic execution to automatically generate tests to cover paths in a program. Combined with a search strategy, one gets, in the limit, an exhaustive white-box testing procedure, for which there are many applications%mdk-data-line={92} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{cadars13}{}{\mdSpan[class={bibitem-label}]{2}}, \mdA[class={bibref,localref},target-element={bibitem}]{cadargpde06}{}{\mdSpan[class={bibitem-label}]{3}}, \mdA[class={bibref,localref},target-element={bibitem}]{godefroidlm12}{}{\mdSpan[class={bibitem-label}]{9}}]}%mdk-data-line={92} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={94}]% %mdk-data-line={94} {}The formula %mdk-data-line={94} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={94} {} is called a %mdk-data-line={94} {}\mdEm{path-condition}%mdk-data-line={94} {} of the path %mdk-data-line={94} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={94} {}. We will see that a given path %mdk-data-line={95} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={95} {} can induce many different path-conditions. A path-condition %mdk-data-line={96} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={96} {} for path %mdk-data-line={96} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={96} {} is %mdk-data-line={96} {}\mdEm{sound}%mdk-data-line={96} {} if every input assignment satisfying %mdk-data-line={97} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={97} {} defines an execution of program %mdk-data-line={98} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={98} {} that follows path %mdk-data-line={98} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={98} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{godefroid11}{}{\mdSpan[class={bibitem-label}]{7}}]}%mdk-data-line={98} {}. By its definition, the formula %mdk-data-line={99} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={99} {} is sound and the best representation of %mdk-data-line={99} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={99} {} (as for all sound path-conditions %mdk-data-line={100} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={100} {}, we have that %mdk-data-line={100} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p \implies \phi_p$}%mdk-data-line={100} {}). In practice, we attempt to compute sound under-approximations of %mdk-data-line={101} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={101} {} such as %mdk-data-line={102} {}\mdSpan[class={math-inline},elem={math-inline}]{$\psi_p$}%mdk-data-line={102} {}. However, we also find it necessary (and useful) to compute unsound path-conditions.% \end{mdP}% \begin{mdP}[class={indent},data-line={105}]% %mdk-data-line={105} {}A path-condition can be translated into the input language of an ATP, such as%mdk-data-line={106} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={106} {}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{demourab08}{}{\mdSpan[class={bibitem-label}]{5}}]}%mdk-data-line={106} {}, which provides an answer of %mdk-data-line={107} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={107} {}, %mdk-data-line={107} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={107} {} or %mdk-data-line={107} {}{\textquotedblleft}unknown{\textquotedblright}%mdk-data-line={107} {}, due to theoretical or practical limitations in automatically deciding satisfiability of various logics. In the case that the ATP is able to prove %mdk-data-line={109} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={109} {} we can query it for satisfying model in order to generate test inputs. A path-condition for %mdk-data-line={111} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={111} {} can be thought of as function from a program%mdk-data-line={112} {}{'}%mdk-data-line={112} {}s primary inputs to a Boolean output representing whether or not %mdk-data-line={113} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={113} {} is executed under a given input. Thus, we are asking the ATP to invert a function when we ask it to decide the satisfiability/unsatisfiability of a path-condition.% \end{mdP}% \begin{mdP}[class={indent},data-line={117}]% %mdk-data-line={117} {}The static translation of a path %mdk-data-line={117} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={117} {} through a program %mdk-data-line={117} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={117} {} into the most precise path-condition %mdk-data-line={118} {}\mdSpan[class={math-inline},elem={math-inline}]{$\phi_p$}%mdk-data-line={118} {} is not a simple task, as programming languages and their semantics are very complex. Completely characterizing the set of inputs %mdk-data-line={120} {}\mdSpan[class={math-inline},elem={math-inline}]{$I$}%mdk-data-line={120} {} that follow path %mdk-data-line={121} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={121} {} means providing a symbolic interpretation of every operation in the language so that the ATP can reason about it. For example, consider a method call in Python. Python%mdk-data-line={124} {}{'}%mdk-data-line={124} {}s algorithm for method resolution order (see%mdk-data-line={124} {}{\mdNbsp}\mdA[data-linkid={mro}]{https://www.python.org/download/releases/2.3/mro/}{}{MRO}%mdk-data-line={124} {}) depends on the inheritance hierarchy of the program, a directed, acyclic graph that can evolve during program execution. Symbolically encoding Python%mdk-data-line={127} {}{'}%mdk-data-line={127} {}s method resolution order is possible but non-trivial. There are other reasons it is hard or undesirable to symbolically execute various operations, as will be explained in detail later.% \end{mdP}% \mdHxxx[id=sec-dynamic-symbolic-execution,label={[1.1]\{.heading-label\}},toc={},data-line={131},caption={[[1.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Dynamic symbolic execution},bookmark={1.1.{\hspace{0.5em}}Dynamic symbolic execution}]{%mdk-data-line={131} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.1}.{\hspace{0.5em}}}%mdk-data-line={131} {}Dynamic symbolic execution}\begin{mdP}[data-line={133}]% %mdk-data-line={133} {}\mdEm{Dynamic}%mdk-data-line={133} {} symbolic execution (DSE) is a form of path-based symbolic execution based on two insights. First, the approach starts by executing program %mdk-data-line={135} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={135} {} on some input %mdk-data-line={136} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={136} {}, seeding the symbolic execution process with a feasible path%mdk-data-line={137} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{gupta00}{}{\mdSpan[class={bibitem-label}]{10}}, \mdA[class={bibref,localref},target-element={bibitem}]{korel90}{}{\mdSpan[class={bibitem-label}]{12}}, \mdA[class={bibref,localref},target-element={bibitem}]{korel92}{}{\mdSpan[class={bibitem-label}]{13}}]}%mdk-data-line={137} {}. Second, DSE uses concrete values from the execution %mdk-data-line={139} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={139} {} in place of symbolic expressions whenever symbolic reasoning is not possible or desired%mdk-data-line={140} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{cadare05}{}{\mdSpan[class={bibitem-label}]{1}}, \mdA[class={bibref,localref},target-element={bibitem}]{godefroidks05}{}{\mdSpan[class={bibitem-label}]{8}}]}%mdk-data-line={140} {}. The major benefit of DSE is to simplify the construction of a symbolic execution tool by leveraging concrete execution behavior (given by actually running the program). As DSE combines both concrete and symbolic reasoning, it also has been called %mdk-data-line={146} {}{\textquotedblleft}concolic{\textquotedblright}%mdk-data-line={146} {} execution%mdk-data-line={147} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{senacav06}{}{\mdSpan[class={bibitem-label}]{14}}]}%mdk-data-line={147} {}.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-dse,label={[1]\{.figure-label\}},elem={figure},toc-line={[1]\{.figure-label\}. Pseudo-code for dynamic symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Pseudo-code for dynamic symbolic execution},data-line={149}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={150},data-line-code={151}]% \mdPrecode[data-line={151}]{{\preindent{2}}\mdToken{Identifier,Python}{i}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{an}{\prespace{1}}\mdToken{Identifier,Python}{input}{\prespace{1}}\mdToken{Identifier,Python}{to}{\prespace{1}}\mdToken{Identifier,Python}{program}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{P}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{while}{\prespace{1}}\mdToken{Identifier,Python}{defined}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{i}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{p}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{path}{\prespace{1}}\mdToken{Identifier,Python}{covered}{\prespace{1}}\mdToken{Identifier,Python}{by}{\prespace{1}}\mdToken{Identifier,Python}{execution}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{P}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{i}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{cond}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{pathCondition}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{p}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{s}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Constructor,Identifier,Python}{ATP}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Namespace,Identifier,Python}{Not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{cond}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\prebr{} {\preindent{5}}\mdToken{Identifier,Python}{i}{\prespace{1}}\mdToken{Keyword,Python}{=}{\prespace{1}}\mdToken{Identifier,Python}{s}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{model}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={158}]{}\begin{mdDiv}[data-line={159}]% %mdk-data-line={159} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{1}.} }Pseudo-code for dynamic symbolic execution}%mdk-data-line={159} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={160}]% %mdk-data-line={160} {}The pseudo-code of Figure%mdk-data-line={160} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-dse}{}{\mdSpan[class={figure-label}]{1}}%mdk-data-line={160} {} shows the high level process of DSE. The variable %mdk-data-line={161} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{i}}%mdk-data-line={161} {} represents an input to program %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Constructor,Identifier,Python}{P}}%mdk-data-line={162} {}. Execution of program %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Constructor,Identifier,Python}{P}}%mdk-data-line={162} {} on the input %mdk-data-line={162} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{i}}%mdk-data-line={162} {} traces a path %mdk-data-line={163} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{p}}%mdk-data-line={163} {}, from which a logical formula %mdk-data-line={164} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{pathCondition}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{p}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={164} {} is constructed. Finally, the ATP is called with the negation of the path-condition to find a new input (that hopefully will cover a new path). This pseudo-code elides a number of details that we will deal with later.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-easy-dse,label={[2]\{.figure-label\}},elem={figure},toc-line={[2]\{.figure-label\}. Easy example: computing the maximum of four numbers in Python.},toc={tof},float-env={figure},float-name={Figure},caption={Easy example: computing the maximum of four numbers in Python.},data-line={169}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={170},data-line-code={171}]% \mdPrecode[data-line={171}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{s}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{t}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{s}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{t}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{8}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{t}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{else}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{8}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{s}\prebr{} \prebr{} \mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{max4}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{4}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{max2}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={180}]{}\begin{mdDiv}[data-line={181}]% %mdk-data-line={181} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{2}.} }Easy example: computing the maximum of four numbers in Python.}%mdk-data-line={181} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent,para-continue},data-line={182}]% %mdk-data-line={182} {}Consider the Python function %mdk-data-line={182} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={182} {} in Figure%mdk-data-line={182} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-easy-dse}{}{\mdSpan[class={figure-label}]{2}}%mdk-data-line={182} {}, which computes the maximum of four numbers via three calls to the function %mdk-data-line={184} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max2}}%mdk-data-line={184} {}. Suppose we execute %mdk-data-line={184} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={184} {} with values of zero for all four arguments. In this case, the execution path %mdk-data-line={186} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={186} {} contains three comparisons (in the order %mdk-data-line={186} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={186} {}, %mdk-data-line={187} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={187} {}, %mdk-data-line={187} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={187} {}), all of which evaluate false. Thus, the path-condition for path %mdk-data-line={188} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={188} {} is %mdk-data-line={188} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={188} {}. Negating this condition yields %mdk-data-line={189} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{or}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{or}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={189} {}. Taking the execution ordering of the three comparisons into account, we derive three expressions from the negated path-condition to generate new inputs that will explore execution prefixes of path %mdk-data-line={192} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={192} {} of increasing length:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={194}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={194}]% %mdk-data-line={194} {}\mdEm{length 0}%mdk-data-line={194} {}: %mdk-data-line={194} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={194} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={195}]% %mdk-data-line={195} {}\mdEm{length 1}%mdk-data-line={195} {}: %mdk-data-line={195} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={195} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={196}]% %mdk-data-line={196} {}\mdEm{length 2}%mdk-data-line={196} {}: %mdk-data-line={196} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={196} {}% \end{mdLi}%% \end{mdUl}% \begin{mdP}[class={para-continue},data-line={198}]% %mdk-data-line={198} {}The purpose of taking execution order into account should be clear, as the comparison %mdk-data-line={199} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={199} {} only executes in the case where %mdk-data-line={199} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={199} {} holds. Integer solutions to the above three systems of constraints are:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={202}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={202}]% %mdk-data-line={202} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{2}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}}%mdk-data-line={202} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={203}]% %mdk-data-line={203} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{3}}%mdk-data-line={203} {}% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={204}]% %mdk-data-line={204} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{a}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{c}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{2}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{d}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{0}}%mdk-data-line={204} {}% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={206}]% %mdk-data-line={206} {}In the three cases above, we sought solutions that kept as many of the variables as possible equal to the original input (in which all variables are equal to 0). Execution of the %mdk-data-line={208} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{max4}}%mdk-data-line={208} {} function on the input corresponding to the first solution produces the path-condition %mdk-data-line={210} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{a}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{b}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{c}\mdToken{Operator,Python}{{\textless}}\mdToken{Identifier,Python}{d}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Keyword,Python}{not}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{b}{\prespace{1}}\mdToken{Operator,Python}{{\textless}}{\prespace{1}}\mdToken{Identifier,Python}{c}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={210} {}, from which we can produce more inputs. For this (loop-free function), there are a finite number of path-conditions. We leave it as an exercise to the reader to enumerate them all.% \end{mdP}% \mdHxxx[id=sec-leveraging-concrete-values-in-dse,label={[1.2]\{.heading-label\}},toc={},data-line={215},caption={[[1.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Leveraging concrete values in DSE},bookmark={1.2.{\hspace{0.5em}}Leveraging concrete values in DSE}]{%mdk-data-line={215} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.2}.{\hspace{0.5em}}}%mdk-data-line={215} {}Leveraging concrete values in DSE}\begin{mdP}[data-line={217}]% %mdk-data-line={217} {}We now consider several situations where we can make use of concrete values in DSE. In the realm of (unbounded-precision) integer arithmetic (e.g., bignum integer arithmetic, as in Python 3.0 onwards), it is easy to come up with tiny programs that will be %mdk-data-line={220} {}\mdEm{very difficult}%mdk-data-line={220} {}, if not %mdk-data-line={221} {}\mdEm{impossible}%mdk-data-line={221} {}, for any symbolic execution tool to deal with, such as the function %mdk-data-line={222} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={222} {} in Figure%mdk-data-line={223} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-fermat3}{}{\mdSpan[class={figure-label}]{3}}%mdk-data-line={223} {}.%mdk-data-line={223} {} %mdk-data-line={223} {}% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-fermat3,label={[3]\{.figure-label\}},elem={figure},toc-line={[3]\{.figure-label\}. Hard example for symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Hard example for symbolic execution},data-line={226}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={227},data-line-code={228}]% \mdPrecode[data-line={228}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{fermat3}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{3}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Identifier,Python}{z}{\prespace{1}}\mdToken{Operator,Python}{{\textgreater}}{\prespace{1}}\mdToken{Number,Python}{0}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{6}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{+}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{10}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{String,Delim,Python,BracketOpen}{{"}}\mdToken{String,Python}{Fermat\prespace{1}and\prespace{1}Wiles\prespace{1}were\prespace{1}wrong!?!}\mdToken{String,Delim,Python,BracketClose}{{"}}\prebr{} {\preindent{3}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{0}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={234}]{}\begin{mdDiv}[data-line={235}]% %mdk-data-line={235} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{3}.} }Hard example for symbolic execution}%mdk-data-line={235} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={237}]% %mdk-data-line={237} {}Fermat%mdk-data-line={237} {}{'}%mdk-data-line={237} {}s Last Theorem, proved by Andrew Wiles in the late 20th century, states that no three positive integers %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={239} {}, %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={239} {}, and %mdk-data-line={239} {}\mdSpan[class={math-inline},elem={math-inline}]{$z$}%mdk-data-line={239} {} can satisfy the equation %mdk-data-line={240} {}\mdSpan[class={math-inline},elem={math-inline}]{$x^n + y^n = z^n$}%mdk-data-line={240} {} for any integer value of %mdk-data-line={240} {}\mdSpan[class={math-inline},elem={math-inline}]{$n$}%mdk-data-line={240} {} greater than two. The function %mdk-data-line={241} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={241} {} encodes this statement for %mdk-data-line={241} {}\mdSpan[class={math-inline},elem={math-inline}]{$n=3$}%mdk-data-line={241} {}. It is not reasonable to have a computer waste time trying to find a solution that would cause %mdk-data-line={243} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={243} {} to print the string %mdk-data-line={244} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{String,Delim,Python,BracketOpen}{{"}}\mdToken{String,Python}{Fermat\prespace{1}and\prespace{1}Wiles\prespace{1}were\prespace{1}wrong!?!}\mdToken{String,Delim,Python,BracketClose}{{"}}}%mdk-data-line={244} {}. In cases of complex (non-linear) arithmetic operations, such as %mdk-data-line={246} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}}%mdk-data-line={246} {}, we might choose to handle the operation concretely.% \end{mdP}% \begin{mdP}[class={indent},data-line={248}]% %mdk-data-line={248} {}There are a number of ways to deal with the above issue: one is to recognize all non-linear terms in a symbolic expression and replace them with their concrete counterparts during execution. For the %mdk-data-line={250} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fermat3}}%mdk-data-line={250} {} example, this would mean that during DSE the symbolic expression %mdk-data-line={252} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{+}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{y}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Operator,Python}{*}\mdToken{Identifier,Python}{z}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={252} {} would be reduced to the constant %mdk-data-line={252} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{False}}%mdk-data-line={252} {} by evaluation on the concrete values of variables %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={253} {}, %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{y}}%mdk-data-line={253} {} and %mdk-data-line={253} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{z}}%mdk-data-line={253} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={255}]% %mdk-data-line={255} {}Besides difficult operations (such as non-linear arithmetic), other examples of code that we might treat concretely instead of symbolically include functions that are hard to invert, such as cryptographic hash functions, or low-level functions that we do not wish to test (such as operating system functions). Consider the code in Figure%mdk-data-line={261} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-hash}{}{\mdSpan[class={figure-label}]{4}}%mdk-data-line={261} {}, which applies the function %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={262} {} to argument %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={262} {} and compares it to argument %mdk-data-line={262} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{y}}%mdk-data-line={262} {}. By using the name %mdk-data-line={263} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={263} {} we simply mean to say that we wish to model this function as a black box, with no knowledge of how it operates internally.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-hash,label={[4]\{.figure-label\}},elem={figure},toc-line={[4]\{.figure-label\}. Another hard example for symbolic execution},toc={tof},float-env={figure},float-name={Figure},caption={Another hard example for symbolic execution},data-line={267}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-python,lang-python,python,highlighted},language={python},data-line={268},data-line-code={269}]% \mdPrecode[data-line={269}]{\mdToken{Keyword,Python}{def}{\prespace{1}}\mdToken{Identifier,Python}{dart}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Python}{,}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{if}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}\mdToken{Keyword,Python,BracketOpen}{:}\prebr{} {\preindent{5}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{1}\prebr{} {\preindent{2}}\mdToken{Keyword,Python}{return}{\prespace{1}}\mdToken{Number,Python}{0}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={274}]{}\begin{mdDiv}[data-line={275}]% %mdk-data-line={275} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{4}.} }Another hard example for symbolic execution}%mdk-data-line={275} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent},data-line={276}]% %mdk-data-line={276} {}In such a case, we can use DSE to execute the function %mdk-data-line={276} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={276} {} on a specific input (say %mdk-data-line={277} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{5013}}%mdk-data-line={277} {}) and observe its output (say %mdk-data-line={278} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{42}}%mdk-data-line={278} {}). That is, rather than execute %mdk-data-line={278} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={278} {} symbolically and invoke an ATP to invert the function%mdk-data-line={279} {}{'}%mdk-data-line={279} {}s path-condition, we simply treat the call to %mdk-data-line={280} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}}%mdk-data-line={280} {} concretely, substituting its return value (in this case %mdk-data-line={281} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Number,Python}{42}}%mdk-data-line={281} {}) for the specialized expression %mdk-data-line={282} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}}%mdk-data-line={282} {} to get the predicate %mdk-data-line={282} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={282} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={284}]% %mdk-data-line={284} {}Adding the constraint %mdk-data-line={284} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={284} {} yields the sound but rather specific path-condition %mdk-data-line={286} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Number,Python}{5013}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Keyword,Python}{and}{\prespace{1}}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={286} {}. Note that the path-condition %mdk-data-line={287} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Number,Python}{42}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={287} {} is not sound, as it admits any value for the variable %mdk-data-line={288} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{x}}%mdk-data-line={288} {}, which likely includes many values for which %mdk-data-line={289} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{unknown}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{x}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Python}{==}{\prespace{1}}\mdToken{Identifier,Python}{y}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={289} {} is false.% \end{mdP}% \mdHxxx[id=sec-overview,label={[1.3]\{.heading-label\}},toc={},data-line={291},caption={[[1.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Overview},bookmark={1.3.{\hspace{0.5em}}Overview}]{%mdk-data-line={291} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{1.3}.{\hspace{0.5em}}}%mdk-data-line={291} {}Overview}\begin{mdP}[class={para-continue},data-line={293}]% %mdk-data-line={293} {}This introduction elides many important issues that arise in implementing DSE for a real language, which we will focus on in the remainder of the paper. These include how to:% \end{mdP}% \begin{mdUl}[class={ul,list-star,compact},elem={ul},data-line={297}]% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={297}]% %mdk-data-line={297} {}Identify the code under test %mdk-data-line={297} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={297} {} and the symbolic inputs to %mdk-data-line={297} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={297} {};% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={298}]% %mdk-data-line={298} {}Trace the control flow path %mdk-data-line={298} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={298} {} taken by execution %mdk-data-line={298} {}\mdSpan[class={math-inline},elem={math-inline}]{$P(i)$}%mdk-data-line={298} {};% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(3)]\{.ul-li-label\}},elem={li},data-line={299}]% %mdk-data-line={299} {}Reinterpret program operations to compute symbolic expressions;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(4)]\{.ul-li-label\}},elem={li},data-line={300}]% %mdk-data-line={300} {}Generate a path-condition from %mdk-data-line={300} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={300} {} and the symbolic expressions;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(5)]\{.ul-li-label\}},elem={li},data-line={301}]% %mdk-data-line={301} {}Generate a new input %mdk-data-line={301} {}\mdSpan[class={math-inline},elem={math-inline}]{$i'$}%mdk-data-line={301} {} by negating (part of) the path-condition, translating the path-condition to the input language of an ATP, invoking the ATP, and lifting a satisfying model (if any) back up to the source level;% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,compact-li},label={[(6)]\{.ul-li-label\}},elem={li},data-line={304}]% %mdk-data-line={304} {}Guide the search to expose new paths.% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={306}]% %mdk-data-line={306} {}The rest of this paper is organized as follows. Section%mdk-data-line={306} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={306} {} describes an instrumented typing discipline where we lift each type (representing a set of concrete values) to a symbolic type (representing a set of pairs of concrete and symbolic values). Section%mdk-data-line={310} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-sp2dse}{}{\mdSpan[class={heading-label}]{3}}%mdk-data-line={310} {} shows how strongest postconditions defines a symbolic semantics for a small programming language and how strongest postconditions can be refined to model DSE. Section%mdk-data-line={313} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-impl}{}{\mdSpan[class={heading-label}]{4}}%mdk-data-line={313} {} describes an implementation of DSE for the Python language in the Python language that follows the instrumented semantics pattern closely (full implementation and tests available at%mdk-data-line={315} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={315} {}, tagged %mdk-data-line={315} {}{\textquotedblleft}v1.0{\textquotedblright}%mdk-data-line={315} {}). Section%mdk-data-line={316} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={316} {} describes the symbolic encoding of Python integer operations using two decision procedures of Z3: linear arithmetic with uninterpreted functions in place of non-linear operations; fixed-width bit-vectors with precise encodings of most operations. Section%mdk-data-line={320} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-extensions}{}{\mdSpan[class={heading-label}]{6}}%mdk-data-line={320} {} offers a number of ideas for projects to extend the capabilities of%mdk-data-line={321} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={321} {}.% \end{mdP}% \mdHxx[id=sec-semantics,label={[2]\{.heading-label\}},toc={},data-line={323},caption={[[2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Instrumented Types},bookmark={2.{\hspace{0.5em}}Instrumented Types}]{%mdk-data-line={323} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{2}.{\hspace{0.5em}}}%mdk-data-line={323} {}Instrumented Types}\begin{mdP}[data-line={325}]% %mdk-data-line={325} {}We are given a universe of classes/types %mdk-data-line={325} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={325} {}; a type %mdk-data-line={325} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={325} {} carries along a set of operations that apply to values of type %mdk-data-line={326} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={326} {}, where an operation %mdk-data-line={327} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={327} {} takes an argument list of typed values as input (the first being of type %mdk-data-line={328} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={328} {}) and produces a single typed value as output. Nullary (static) operations of type %mdk-data-line={329} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={329} {} can be used to create values of type %mdk-data-line={330} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={330} {} (such as constants, objects, etc.)% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={332}]% %mdk-data-line={332} {}A program %mdk-data-line={332} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={332} {} has typed input variables %mdk-data-line={333} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 : T_1 \ldots v_k : T_k$}%mdk-data-line={333} {} and a body from the language of statements %mdk-data-line={333} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={333} {}:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={335}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={336} \begin{mdMathprearray}%mdk \mathid{S}\mdMathspace{1}\rightarrow &\mdMathspace{1}\mathid{v}\mdMathspace{1}:=\mdMathspace{1}\mathid{E}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathid{S}_1\mdMathspace{1};\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end}\mdMathbr{} \mdMathindent{3}|\mdMathspace{1}&\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end} \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={343}]% %mdk-data-line={343} {}The language of expressions (%mdk-data-line={343} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={343} {}) is defined by the application of operations to values, where constants (nullary operations) and program variables form the leaves of the expression tree and non-nullary operators form the interior nodes of the tree. For now, we will consider all values to be immutable. That is, the only source of mutation in the language is the assignment statement.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={352}]% %mdk-data-line={352} {}To introduce symbolic execution into the picture, we can imagine that a type %mdk-data-line={353} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={353} {} has (one or more) counterparts in a symbolic universe %mdk-data-line={354} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={354} {}. A type %mdk-data-line={354} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' \in U'$}%mdk-data-line={354} {} is a subtype of %mdk-data-line={355} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={355} {} with two purposes:% \end{mdP}% \begin{mdUl}[class={ul,list-star,loose},elem={ul},data-line={357}]% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={357}]% \begin{mdP}[data-line={357}]% %mdk-data-line={357} {}First, a value of type %mdk-data-line={357} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={357} {} represents a pair of values: a concrete value %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={358} {} of (super)type %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={358} {} and a symbolic expression %mdk-data-line={358} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={358} {}. A symbolic expression is a tree whose leaves are either nullary operators (i.e., constants) of a type in %mdk-data-line={360} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={360} {} or are Skolem constants representing the (symbolic) inputs (%mdk-data-line={361} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 \ldots v_k$}%mdk-data-line={361} {}) to the program %mdk-data-line={362} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={362} {}, and whose interior nodes represent operations from types in %mdk-data-line={363} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={363} {}. We refer to Skolem constants as %mdk-data-line={363} {}{\textquotedblleft}symbolic constants{\textquotedblright}%mdk-data-line={363} {} from this point on. Note that symbolic expressions do not contain references to program variables.% \end{mdP}%% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={367}]% \begin{mdP}[data-line={367}]% %mdk-data-line={367} {}Second, the type %mdk-data-line={367} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={367} {} redefines some of the operations %mdk-data-line={367} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={367} {}, namely those for which we wish to compute symbolic expressions. An operation %mdk-data-line={369} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={369} {} has the same parameter list as %mdk-data-line={369} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={369} {}, allowing it to take inputs with types from both %mdk-data-line={370} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={370} {} and %mdk-data-line={370} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={370} {}. The return type of %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={371} {} generally is from %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={371} {} (though it can be from %mdk-data-line={371} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={371} {}). Thus, %mdk-data-line={372} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={372} {} is a proper function subtype of %mdk-data-line={372} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={372} {}. The purpose of %mdk-data-line={373} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T'$}%mdk-data-line={373} {} is to: (1) perform operation %mdk-data-line={374} {}\mdSpan[class={math-inline},elem={math-inline}]{$o \in T$}%mdk-data-line={374} {} on the concrete values associated with its inputs; (2) build a symbolic expression tree rooted at operation %mdk-data-line={376} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={376} {} whose children are the trees associated with the inputs to %mdk-data-line={377} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={377} {}.% \end{mdP}%% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={379}]% %mdk-data-line={379} {}Figure%mdk-data-line={379} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={379} {} presents pseudo code for the instrumentation of a type %mdk-data-line={380} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={380} {} via a type %mdk-data-line={380} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={380} {}. The class %mdk-data-line={381} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={381} {} is used to hold an expression tree (%mdk-data-line={381} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Expr}}%mdk-data-line={381} {}). Given a class %mdk-data-line={382} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={382} {}, a symbolic type %mdk-data-line={382} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' \in U'$}%mdk-data-line={382} {} is defined by inheriting from both %mdk-data-line={383} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={383} {} and %mdk-data-line={383} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={383} {}. This ensures that a %mdk-data-line={383} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={383} {} can be used wherever a %mdk-data-line={384} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={384} {} is expected.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-subtype,label={[5]\{.figure-label\}},elem={figure},toc-line={[5]\{.figure-label\}. Type instrumentation to carry both concrete values and symbolic expressions.},toc={tof},float-env={figure},float-name={Figure},caption={Type instrumentation to carry both concrete values and symbolic expressions.},data-line={386}]% \begin{mdPre}[class={para-block,pre-fenced,pre-fenced3,language-cpp2,lang-cpp2,cpp2,highlighted},data-line={387},data-line-code={388},language={cpp2}]% \mdPrecode[data-line={388}]{{\preindent{2}}\mdToken{Keyword,Cpp}{class}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T'$}}}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\prebr{} {\preindent{4}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T'$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{e}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{Expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Source,Cpp}{S}\mdToken{Identifier,Cpp}{ymbolic}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} \prebr{} {\preindent{4}}\mdToken{Keyword,Extra,Cpp}{override}{\prespace{1}}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Keyword,Cpp}{this}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{f1}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T_1$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{fk}\mdToken{Operator,Cpp}{:}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T_k$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}\prebr{} {\preindent{6}}\mdToken{Keyword,Extra,Cpp}{var}{\prespace{1}}\mdToken{Identifier,Cpp}{c}{\prespace{1}}:={\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Keyword,Cpp}{this}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{f1}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{fk}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\prebr{} {\preindent{6}}\mdToken{Keyword,Extra,Cpp}{var}{\prespace{1}}\mdToken{Identifier,Cpp}{e}{\prespace{1}}:={\prespace{1}}\mdToken{Keyword,Cpp}{new}{\prespace{1}}\mdToken{Source,Cpp}{E}\mdToken{Identifier,Cpp}{xpr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$T$}}}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{o}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{self}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{f1}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{fk}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}\prebr{} {\preindent{6}}\mdToken{Keyword,Cpp}{return}{\prespace{1}}\mdToken{Keyword,Cpp}{new}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\prebr{} {\preindent{4}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{4}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\prebr{} {\preindent{2}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{2}}\prebr{} {\preindent{2}}\mdToken{Keyword,Cpp}{class}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R$}}}\mdToken{Delimiter,Cpp}{,}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketOpen}{\{}{\prespace{1}}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}\mdToken{Delimiter,Cpp}{.}{\prespace{1}}\mdToken{Delimiter,Curly,Cpp,BracketClose}{\}}\prebr{} {\preindent{2}}\prebr{} {\preindent{2}}\mdToken{Keyword,Extra,Cpp}{function}{\prespace{1}}\mdToken{Identifier,Cpp}{expr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{v}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{=}{\prespace{1}}\mdToken{Identifier,Cpp}{v}{\prespace{1}}\mdToken{Keyword,Extra,Cpp}{instanceof}{\prespace{1}}\mdToken{Type,Identifier,Cpp}{Symbolic}{\prespace{1}}\mdToken{Operator,Cpp}{?}{\prespace{1}}\mdToken{Identifier,Cpp}{v}\mdToken{Delimiter,Cpp}{.}\mdToken{Identifier,Cpp}{getExpr}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}{\prespace{1}}\mdToken{Operator,Cpp}{:}{\prespace{1}}\mdToken{Identifier,Cpp}{v}}% \end{mdPre}% \mdHr[class={figureline,madoko},data-line={403}]{}\begin{mdDiv}[data-line={404}]% %mdk-data-line={404} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{5}.} }Type instrumentation to carry both concrete values and symbolic expressions.}%mdk-data-line={404} {}% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={indent,para-continue},data-line={405}]% %mdk-data-line={405} {}A type such as %mdk-data-line={405} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={405} {} only can be constructed by providing a concrete value %mdk-data-line={405} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={405} {} of type %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={406} {} and a symbolic expression %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={406} {} to the constructor for %mdk-data-line={406} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={406} {}. This will be done in exactly two places:% \end{mdP}% \begin{mdUl}[class={ul,list-star,loose},elem={ul},data-line={409}]% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(1)]\{.ul-li-label\}},elem={li},data-line={409}]% \begin{mdP}[data-line={409}]% %mdk-data-line={409} {}by the creation of symbolic constants associated with the primary inputs (%mdk-data-line={410} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_1 \ldots v_k$}%mdk-data-line={410} {}) to the program;% \end{mdP}%% \end{mdLi}% \begin{mdLi}[class={li,ul-li,list-star-li,loose-li},label={[(2)]\{.ul-li-label\}},elem={li},data-line={412}]% \begin{mdP}[data-line={412}]% %mdk-data-line={412} {}by the instrumented operations as shown in Figure%mdk-data-line={412} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={412} {}.% \end{mdP}%% \end{mdLi}%% \end{mdUl}% \begin{mdP}[data-line={414}]% %mdk-data-line={414} {}An instrumented operation %mdk-data-line={414} {}\mdSpan[class={math-inline},elem={math-inline}]{$o$}%mdk-data-line={414} {} on arguments (%mdk-data-line={414} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={414} {}, %mdk-data-line={414} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={414} {}, %mdk-data-line={414} {}{\dots}%mdk-data-line={414} {}, %mdk-data-line={414} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={414} {}) first invokes its corresponding underlying operator %mdk-data-line={416} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={416} {} on arguments (%mdk-data-line={416} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={416} {}, %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={416} {}, %mdk-data-line={416} {}{\dots}%mdk-data-line={416} {}, %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={416} {}) to get concrete value %mdk-data-line={416} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{c}}%mdk-data-line={416} {}. It then constructs a new expression tree %mdk-data-line={417} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{e}}%mdk-data-line={417} {} rooted at operator %mdk-data-line={418} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={418} {}, whose children are the result of mapping the function %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expr}}%mdk-data-line={419} {} over (%mdk-data-line={419} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Keyword,Cpp}{this}}%mdk-data-line={419} {}, %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{f1}}%mdk-data-line={419} {}, %mdk-data-line={419} {}{\dots}%mdk-data-line={419} {}, %mdk-data-line={419} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{fk}}%mdk-data-line={419} {}). The helper function %mdk-data-line={420} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expr}\mdToken{Delimiter,Parenthesis,Python,BracketOpen}{(}\mdToken{Identifier,Python}{v}\mdToken{Delimiter,Parenthesis,Python,BracketClose}{)}}%mdk-data-line={420} {} evaluates to an expression tree in the case that %mdk-data-line={421} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{v}}%mdk-data-line={421} {} is of %mdk-data-line={421} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdToken{Type,Identifier,Cpp}{Symbolic}}%mdk-data-line={421} {} type (representing a type in %mdk-data-line={422} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={422} {}) and evaluates to %mdk-data-line={422} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{v}}%mdk-data-line={422} {} itself, a concrete value of some type in %mdk-data-line={423} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={423} {}, otherwise. Finally, having computed the values %mdk-data-line={424} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{c}}%mdk-data-line={424} {} and %mdk-data-line={424} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{e}}%mdk-data-line={424} {}, the instrumented operator returns %mdk-data-line={425} {}\mdCode[class={code,code2,language-cpp2,lang-cpp2,cpp2,highlighted},language={cpp2}]{\mdSpan[class={code-escaped}]{\mdSpan[class={math-inline},elem={math-inline}]{$R'$}}\mdToken{Delimiter,Parenthesis,Cpp,BracketOpen}{(}\mdToken{Identifier,Cpp}{c}\mdToken{Delimiter,Cpp}{,}\mdToken{Identifier,Cpp}{e}\mdToken{Delimiter,Parenthesis,Cpp,BracketClose}{)}}%mdk-data-line={425} {}, where %mdk-data-line={425} {}\mdSpan[class={math-inline},elem={math-inline}]{$R$}%mdk-data-line={425} {} is the return type of operator %mdk-data-line={425} {}\mdSpan[class={math-inline},elem={math-inline}]{$T.o$}%mdk-data-line={425} {}, and %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$R'$}%mdk-data-line={426} {} is a subtype of %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$R$}%mdk-data-line={426} {} from universe %mdk-data-line={426} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={426} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={428}]% %mdk-data-line={428} {}Looked at another way, the universe %mdk-data-line={428} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={428} {} represents the %mdk-data-line={428} {}{\textquotedblleft}tainting{\textquotedblright}%mdk-data-line={428} {} of types from %mdk-data-line={429} {}\mdSpan[class={math-inline},elem={math-inline}]{$U$}%mdk-data-line={429} {}. Tainted values flow from program inputs to the operands of operators. If an operator has been redefined (as above) then the taint propagates from its inputs to its outputs. On the other hand, if the operator has not been redefined, then it will not propagate the taint. In the context of DSE, %mdk-data-line={433} {}{\textquotedblleft}taint{\textquotedblright}%mdk-data-line={433} {} means that the instrumented semantics carries along a symbolic expression tree %mdk-data-line={434} {}\mdSpan[class={math-inline},elem={math-inline}]{$e$}%mdk-data-line={434} {} along with a concrete value %mdk-data-line={435} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={435} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={437}]% %mdk-data-line={437} {}The choice of types from the universe %mdk-data-line={437} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={437} {} determines how symbolic expressions are constructed. For each %mdk-data-line={438} {}\mdSpan[class={math-inline},elem={math-inline}]{$T \in U$}%mdk-data-line={438} {}, the %mdk-data-line={438} {}{\textquotedblleft}most symbolic{\textquotedblright}%mdk-data-line={438} {} (least concrete) choice is the %mdk-data-line={439} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'$}%mdk-data-line={439} {} that redefines every operator of %mdk-data-line={439} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={439} {} (as shown in Figure%mdk-data-line={440} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-subtype}{}{\mdSpan[class={figure-label}]{5}}%mdk-data-line={440} {}). The %mdk-data-line={441} {}{\textquotedblleft}least symbolic{\textquotedblright}%mdk-data-line={441} {} (most concrete) choice is %mdk-data-line={441} {}\mdSpan[class={math-inline},elem={math-inline}]{$T' = T$}%mdk-data-line={441} {} which redefines no operators. Let %mdk-data-line={442} {}\mdSpan[class={math-inline},elem={math-inline}]{$symbolic(T)$}%mdk-data-line={442} {} be the set of types in %mdk-data-line={443} {}\mdSpan[class={math-inline},elem={math-inline}]{$U'$}%mdk-data-line={443} {} that are subtypes of %mdk-data-line={443} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={443} {}. The types in %mdk-data-line={444} {}\mdSpan[class={math-inline},elem={math-inline}]{$symbolic(T)$}%mdk-data-line={444} {} are partially ordered by subset inclusion on the set of operators from %mdk-data-line={445} {}\mdSpan[class={math-inline},elem={math-inline}]{$T$}%mdk-data-line={445} {} they redefine.% \end{mdP}% \mdHxx[id=sec-sp2dse,label={[3]\{.heading-label\}},toc={},data-line={449},caption={[[3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From Strongest Postconditions to DSE},bookmark={3.{\hspace{0.5em}}From Strongest Postconditions to DSE}]{%mdk-data-line={449} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3}.{\hspace{0.5em}}}%mdk-data-line={449} {}From Strongest Postconditions to DSE}\begin{mdP}[data-line={451}]% %mdk-data-line={451} {}The previous section showed how symbolic expressions can be computed via a set of instrumented types, where the expressions are computed as a side-effect of the execution of program operations. This section shows how these symbolic expressions can be used to form a %mdk-data-line={455} {}\mdEm{path-condition}%mdk-data-line={455} {} (which then can be compiled into a logic formula and passed to an automated theorem prover to find new inputs to drive a program%mdk-data-line={457} {}{'}%mdk-data-line={457} {}s execution along new paths). We derive a %mdk-data-line={457} {}\mdEm{path-condition}%mdk-data-line={457} {} directly from the %mdk-data-line={458} {}\mdEm{strongest postcondition}%mdk-data-line={458} {} (symbolic) semantics of our programming language, refining it to model the basic operations of an interpreter.% \end{mdP}% \mdHxxx[id=sec-strongest-postconditions,label={[3.1]\{.heading-label\}},toc={},data-line={462},caption={[[3.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Strongest Postconditions},bookmark={3.1.{\hspace{0.5em}}Strongest Postconditions}]{%mdk-data-line={462} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.1}.{\hspace{0.5em}}}%mdk-data-line={462} {}Strongest Postconditions}\begin{mdP}[class={para-continue},data-line={464}]% %mdk-data-line={464} {}The strongest postcondition transformer %mdk-data-line={464} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={464} {}{\mdNbsp}\mdSpan[class={citations},target-element={bibitem}]{[\mdA[class={bibref,localref},target-element={bibitem}]{dijkstra76}{}{\mdSpan[class={bibitem-label}]{6}}]}%mdk-data-line={464} {} is defined over a predicate %mdk-data-line={465} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={465} {} representing a set of pre-states and a statement %mdk-data-line={466} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={466} {} from our language. The transformer %mdk-data-line={466} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP(P,S)$}%mdk-data-line={466} {} yields a predicate %mdk-data-line={467} {}\mdSpan[class={math-inline},elem={math-inline}]{$Q$}%mdk-data-line={467} {} such that for any state %mdk-data-line={467} {}\mdSpan[class={math-inline},elem={math-inline}]{$s$}%mdk-data-line={467} {} satisfying predicate %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={468} {}, the execution of statement %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$S$}%mdk-data-line={468} {} from state %mdk-data-line={468} {}\mdSpan[class={math-inline},elem={math-inline}]{$s$}%mdk-data-line={468} {}, if it does not go wrong or diverge, yields a state %mdk-data-line={469} {}\mdSpan[class={math-inline},elem={math-inline}]{$s'$}%mdk-data-line={469} {} satisfying predicate %mdk-data-line={469} {}\mdSpan[class={math-inline},elem={math-inline}]{$Q$}%mdk-data-line={469} {}. The strongest postcondition for the statements in our language is defined by the following five rules:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={473}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={474} \begin{mdMathprearray}%mdk 1.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\exists \mathid{y}\mdMathspace{1}.\mdMathspace{1}(\mathid{x}\mdMathspace{1}=\mdMathspace{1}\mathid{E}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}])\mdMathspace{1}\wedge \mathid{P}\mdMathspace{1}[\mdMathspace{1}\mathid{x}\mdMathspace{1}\rightarrow \mathid{y}\mdMathspace{1}]\mdMathbr{} 2.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mdMathspace{1}\mathkw{skip})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{P}\mdMathbr{} 3.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathid{S}_{1};\mathid{S}_{2})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}\mathid{SP}(\mathid{SP}(\mathid{P},\mathid{S}_{1}),\mdMathspace{1}\mathid{S}_{2})\mdMathbr{} 4.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{} \mdMathindent{4}&\mdMathspace{7}\mathid{SP}(\mathid{P}\wedge \mathid{E},\mathid{S}_1)\mdMathspace{1}\vee \mathid{SP}(\mathid{P}\mdMathspace{1}\wedge \neg \mathid{E},\mathid{S}_2)\mdMathbr{} 5.\mdMathspace{2}&\mdMathspace{1}\mathid{SP}(\mathid{P},\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathbr{} \mdMathindent{4}&\mdMathspace{6}\mathid{SP}(\mathid{P},\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S};\mdMathspace{1}\mathkw{while}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{do}\mdMathspace{1}\mathid{S}\mdMathspace{1}\mathkw{end}\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathkw{skip}\mdMathspace{1}\mathkw{end}) \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={483}]% %mdk-data-line={483} {}Rule (1) defines the strongest postcondition for the assignment statement. The assignment is modeled logically by the equality %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$x = E$}%mdk-data-line={485} {} where any free occurrence of %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={485} {} in %mdk-data-line={485} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={485} {} is replaced by the existentially quantified variable %mdk-data-line={486} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={486} {}, which represents the value of %mdk-data-line={487} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={487} {} in the pre-state. The same substitution (%mdk-data-line={487} {}\mdSpan[class={math-inline},elem={math-inline}]{$[x \rightarrow y ]$}%mdk-data-line={487} {}) is applied to the pre-state predicate %mdk-data-line={488} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={488} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={490}]% %mdk-data-line={490} {}Rules (2)-(5) define the strongest postcondition for the four control-flow statements. The rules for the %mdk-data-line={491} {}\mdStrong{skip}%mdk-data-line={491} {} statement and sequencing (;) are straightforward. Of particular interest, note that the rule for the %mdk-data-line={493} {}\mdStrong{if-then-else}%mdk-data-line={493} {} statement splits cases on the expression %mdk-data-line={494} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={494} {}. It is here that DSE will choose one of the cases for us, as the concrete execution will evaluate %mdk-data-line={496} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={496} {} either to be true or false. This gives rise to the path-condition (either %mdk-data-line={497} {}\mdSpan[class={math-inline},elem={math-inline}]{$P \wedge E$}%mdk-data-line={497} {} or %mdk-data-line={497} {}\mdSpan[class={math-inline},elem={math-inline}]{$P \wedge \neg E$}%mdk-data-line={497} {}). The recursive rule for the %mdk-data-line={498} {}\mdStrong{while}%mdk-data-line={498} {} loop unfolds as many times as the expression %mdk-data-line={499} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={499} {} evaluates true, adding to the path-condition.% \end{mdP}% \mdHxxx[id=sp-refined,label={[3.2]\{.heading-label\}},toc={},data-line={501},caption={[[3.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From \$SP\$ to DSE},bookmark={3.2.{\hspace{0.5em}}From \$SP\$ to DSE}]{%mdk-data-line={501} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.2}.{\hspace{0.5em}}}%mdk-data-line={501} {}From %mdk-data-line={501} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={501} {} to DSE}\begin{mdP}[data-line={503}]% %mdk-data-line={503} {}Assume that an execution begins with the assignment of initial values %mdk-data-line={503} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_1 \ldots c_k$}%mdk-data-line={503} {} to the program %mdk-data-line={503} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={503} {}{'}%mdk-data-line={503} {}s inputs %mdk-data-line={504} {}\mdSpan[class={math-inline},elem={math-inline}]{$V = \{ v_1 : T_1 \ldots v_k : T_k \}$}%mdk-data-line={504} {}. To seed symbolic execution, some of the types %mdk-data-line={504} {}\mdSpan[class={math-inline},elem={math-inline}]{$T_i$}%mdk-data-line={504} {} are replaced by symbolic counterparts %mdk-data-line={505} {}\mdSpan[class={math-inline},elem={math-inline}]{$T'_i$}%mdk-data-line={505} {}, in which case %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_i$}%mdk-data-line={506} {} is initialized to the value %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$sc_i = T'_i (c_i,SC(v_i))$}%mdk-data-line={506} {} instead of the value %mdk-data-line={506} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={506} {}, where %mdk-data-line={507} {}\mdSpan[class={math-inline},elem={math-inline}]{$SC(v_i)$}%mdk-data-line={507} {} is the symbolic constant representing the initial value of variable %mdk-data-line={507} {}\mdSpan[class={math-inline},elem={math-inline}]{$v_i$}%mdk-data-line={507} {}. The symbolic constant %mdk-data-line={508} {}\mdSpan[class={math-inline},elem={math-inline}]{$SC(v_i)$}%mdk-data-line={508} {} can be thought of as representing any value of type %mdk-data-line={509} {}\mdSpan[class={math-inline},elem={math-inline}]{$T_i$}%mdk-data-line={509} {}, which includes the value %mdk-data-line={509} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={509} {}.%mdk-data-line={509} {} %mdk-data-line={509} {}% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={511}]% %mdk-data-line={511} {}Let %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_s$}%mdk-data-line={511} {} and %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_c$}%mdk-data-line={511} {} partition the variables of %mdk-data-line={511} {}\mdSpan[class={math-inline},elem={math-inline}]{$V$}%mdk-data-line={511} {} into those variables that are treated symbolically (%mdk-data-line={512} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_s$}%mdk-data-line={512} {}) and those that are treated concretely (%mdk-data-line={513} {}\mdSpan[class={math-inline},elem={math-inline}]{$V_c$}%mdk-data-line={513} {}). The initial state of the program is characterized by the formula% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(1)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={515}]% %mdk-data-line={515} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(1)}}%mdk-data-line={515} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={516}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={516} Init = (\bigwedge_{v_i \in V_s} v_i = sc_i) ~\wedge~ (~\bigwedge_{v_i \in V_c} v_i = c_i) \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={519}]% %mdk-data-line={519} {}Thus, we see that the initial value of every input variable is characterized by a symbolic constant %mdk-data-line={520} {}\mdSpan[class={math-inline},elem={math-inline}]{$sc_i$}%mdk-data-line={520} {} or constant %mdk-data-line={520} {}\mdSpan[class={math-inline},elem={math-inline}]{$c_i$}%mdk-data-line={520} {}. We assume that every non-input variable in the program is initialized before being used.% \end{mdP}% \begin{mdP}[class={indent},data-line={523}]% %mdk-data-line={523} {}The strongest postcondition is formulated to deal with open programs, programs in which some variables are used before being assigned to. This surfaces in Rule (1) for assignment, which uses existential quantification to refer to the value of variable %mdk-data-line={526} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={526} {} in the pre-state.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={528}]% %mdk-data-line={528} {}By construction, we have that every variable is defined before being used. This means that the precondition %mdk-data-line={530} {}\mdSpan[class={math-inline},elem={math-inline}]{$P$}%mdk-data-line={530} {} can be reformulated as a pair %mdk-data-line={530} {}\mdSpan[class={math-inline},elem={math-inline}]{$<\sigma,P_c>$}%mdk-data-line={530} {}, where %mdk-data-line={531} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={531} {} is a store mapping variables to values and %mdk-data-line={531} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c$}%mdk-data-line={531} {} is the path-condition, a list of symbolic expressions (predicates) corresponding to the expressions %mdk-data-line={534} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={534} {} evaluated in the context of an %mdk-data-line={534} {}\mdStrong{if-then-else}%mdk-data-line={534} {} statement. Initially, we have that :% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(2)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={537}]% %mdk-data-line={537} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(2)}}%mdk-data-line={537} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={538}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={538} \sigma = \{ (v_i,sc_i) | v_i \in V_s \} \cup \{ (v_i,c_i) | v_i \in V_c \} \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[class={para-continue},data-line={541}]% %mdk-data-line={541} {}representing the initial condition %mdk-data-line={541} {}\mdSpan[class={math-inline},elem={math-inline}]{$Init$}%mdk-data-line={541} {}, and %mdk-data-line={541} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c = []$}%mdk-data-line={541} {}, the empty list. We use %mdk-data-line={542} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma'$}%mdk-data-line={542} {} to refer to the formula that the store %mdk-data-line={542} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={542} {} induces:% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(3)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={545}]% %mdk-data-line={545} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(3)}}%mdk-data-line={545} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={546}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={546} \sigma ' = \bigwedge_{(v,V) \in \sigma} (v = V) \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={549}]% %mdk-data-line={549} {}Thus, the pair %mdk-data-line={549} {}\mdSpan[class={math-inline},elem={math-inline}]{$<\sigma,P_c>$}%mdk-data-line={549} {} represents the predicate %mdk-data-line={550} {}\mdSpan[class={math-inline},elem={math-inline}]{$P = \sigma' \wedge (\bigwedge_{c \in P_c} c)$}%mdk-data-line={550} {}. A store %mdk-data-line={551} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={551} {} supports two operations: %mdk-data-line={551} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[x]$}%mdk-data-line={551} {} which denotes the value that %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={552} {} maps to under %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={552} {}; %mdk-data-line={552} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[x \mapsto V]$}%mdk-data-line={552} {}, which produces a new store in which %mdk-data-line={553} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={553} {} maps to value %mdk-data-line={553} {}\mdSpan[class={math-inline},elem={math-inline}]{$V$}%mdk-data-line={553} {} and is everywhere else the same as %mdk-data-line={554} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={554} {}.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={556}]% %mdk-data-line={556} {}Now, we can redefine strongest postcondition for assignment to eliminate the use of existential quantification and model the operation of an interpreter, by separating out the notion of the store:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={560}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={561} \begin{mdMathprearray}%mdk 1.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathid{x}\mdMathspace{1}:=\mdMathspace{1}\mathid{E})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{1}<\sigma[\mathid{x}\mdMathspace{1}\mapsto \mathid{eval}(\sigma,\mathid{E})],\mdMathspace{1}\mathid{P}_\mathid{c}>\\ \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={564}]% %mdk-data-line={564} {}where %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$eval(\sigma,E)$}%mdk-data-line={564} {} evaluates expression %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={564} {} under the store %mdk-data-line={564} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma$}%mdk-data-line={564} {} (where every occurrence of a free variable %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$v$}%mdk-data-line={566} {} in %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$E$}%mdk-data-line={566} {} is replaced by the value %mdk-data-line={566} {}\mdSpan[class={math-inline},elem={math-inline}]{$\sigma[v]$}%mdk-data-line={566} {}). This is the standard substitution rule of a standard operational semantics.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={569}]% %mdk-data-line={569} {}We also redefine the rule for the %mdk-data-line={569} {}\mdStrong{if-then-else}%mdk-data-line={569} {} statement so that it chooses which branch to take and appends the appropriate symbolic expression (predicate) to the path-condition %mdk-data-line={571} {}\mdSpan[class={math-inline},elem={math-inline}]{$P_c$}%mdk-data-line={571} {}:% \end{mdP}% \begin{mdDiv}[class={mathpre,para-block,input-mathpre},elem={mathpre},data-line={573}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={574} \begin{mdMathprearray}%mdk 4.\mdMathspace{1}&\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}>,\mdMathspace{1}\mathkw{if}\mdMathspace{1}\mathid{E}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{S}_1\mdMathspace{1}\mathkw{else}\mdMathspace{1}\mathid{S}_2\mdMathspace{1}\mathkw{end})\mdMathspace{1}{~\buildrel\triangle\over=~}\mdMathspace{2}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{let}\mdMathspace{1}\mathid{choice}\mdMathspace{1}=\mdMathspace{1}\mathid{eval}(\sigma,\mathid{E})\mdMathspace{1}\mathkw{in}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{if}\mdMathspace{1}\mathid{choice}\mdMathspace{1}\mathkw{then}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_1)\mdMathspace{1}\mdMathbr{} \mdMathindent{3}&\mdMathspace{3}\mathkw{else}\mdMathspace{1}\mathid{SP}(<\sigma,\mdMathspace{1}\mathid{P}_\mathid{c}\mdMathspace{1}::\mdMathspace{1}\neg \mathid{expr}(\mathid{choice})\mdMathspace{1}>,\mathid{S}_2) \end{mdMathprearray}%mdk \]% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={580}]% %mdk-data-line={580} {}The other strongest postcondition rules remain unchanged.% \end{mdP}% \mdHxxx[id=sec-summing-it-up,label={[3.3]\{.heading-label\}},toc={},data-line={582},caption={[[3.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Summing it up},bookmark={3.3.{\hspace{0.5em}}Summing it up}]{%mdk-data-line={582} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{3.3}.{\hspace{0.5em}}}%mdk-data-line={582} {}Summing it up}\begin{mdP}[data-line={584}]% %mdk-data-line={584} {}We have shown how the symbolic predicate transformer %mdk-data-line={584} {}\mdSpan[class={math-inline},elem={math-inline}]{$SP$}%mdk-data-line={584} {} can be refined into a symbolic interpreter operating over the symbolic types defined in the previous section. In the case when every input variable is symbolic and every operator is redefined, the path-condition is equivalent to the %mdk-data-line={589} {}\mdEm{strongest postcondition}%mdk-data-line={589} {} of the execution path %mdk-data-line={589} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={589} {}. This guarantees that the path-condition for %mdk-data-line={590} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={590} {} is %mdk-data-line={590} {}\mdEm{sound}%mdk-data-line={590} {}. In the case where a subset of the input variables are symbolic and/or not all operators are redefined, the path-condition of %mdk-data-line={592} {}\mdSpan[class={math-inline},elem={math-inline}]{$p$}%mdk-data-line={592} {} is not guaranteed to be sound. We leave it as an exercise to the reader to establish sufficient conditions under which the use of concrete values in place of symbolic expressions is guaranteed to result in sound path-conditions.% \end{mdP}% \begin{mdP}[class={indent},data-line={598}]% %mdk-data-line={598} {}This section does not address the compilation of a symbolic expression to the (logic) language of an underlying ATP, nor the lifting of a satisfying assignment to a formula back to the level of the source language. This is best done for a particular source language and ATP, as detailed in the next section.% \end{mdP}% \mdHxx[id=sec-impl,label={[4]\{.heading-label\}},toc={},data-line={605},caption={[[4]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Architecture of PyExZ3},bookmark={4.{\hspace{0.5em}}Architecture of PyExZ3}]{%mdk-data-line={605} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4}.{\hspace{0.5em}}}%mdk-data-line={605} {}Architecture of PyExZ3}\begin{mdP}[data-line={607}]% %mdk-data-line={607} {}In this section we present the high-level architecture of a simple DSE tool for the Python language, written in Python, called%mdk-data-line={608} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={608} {}. Figure%mdk-data-line={609} {}{\mdNbsp}\mdA[class={localref},target-element={figure}]{fig-arch}{}{\mdSpan[class={figure-label}]{6}}%mdk-data-line={609} {} shows the class diagram (dashed edges are %mdk-data-line={610} {}{\textquotedblleft}has-a{\textquotedblright}%mdk-data-line={610} {} relationships; solid edges are %mdk-data-line={611} {}{\textquotedblleft}is-a{\textquotedblright}%mdk-data-line={611} {} relationships) of the tool.% \end{mdP}% \begin{mdDiv}[class={figure,floating,align-center},id=fig-arch,label={[6]\{.figure-label\}},elem={figure},toc-line={[6]\{.figure-label\}. Classes in PyExZ3},toc={tof},float-env={figure},float-name={Figure},caption={Classes in PyExZ3},page-align={here},data-line={613}]% \begin{mdP}[data-line={614}]% %mdk-data-line={614} {}\mdImg[width={1.00\linewidth},data-linkid={arch}]{arch.png}%mdk-data-line={614} {}% \end{mdP}% \mdHr[class={figureline,madoko},data-line={615}]{}\begin{mdDiv}[data-line={616}]% %mdk-data-line={616} {}\mdSpan[class={figure-caption}]{\mdSpan[class={caption-before}]{\mdStrong{Figure{\mdNbsp}\mdSpan[class={figure-label}]{6}.} }Classes in PyExZ3}%mdk-data-line={616} {}% \end{mdDiv}%% \end{mdDiv}% \mdHxxx[id=sec-loading-the-code-under-test,label={[4.1]\{.heading-label\}},toc={},data-line={619},caption={[[4.1]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Loading the code under test},bookmark={4.1.{\hspace{0.5em}}Loading the code under test}]{%mdk-data-line={619} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.1}.{\hspace{0.5em}}}%mdk-data-line={619} {}Loading the code under test}\begin{mdP}[data-line={621}]% %mdk-data-line={621} {}The %mdk-data-line={621} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Loader}}%mdk-data-line={621} {} class takes as input the name of a Python file (e.g., %mdk-data-line={621} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={621} {}) to import. The loader expects to find a function named %mdk-data-line={623} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={623} {} inside the file %mdk-data-line={623} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={623} {}, which will serve as the starting point for symbolic execution. The %mdk-data-line={624} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={624} {} class wraps this starting point. By default, each parameter to %mdk-data-line={625} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={625} {} is a %mdk-data-line={626} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={626} {} unless there is decorator %mdk-data-line={626} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Delimiter,Python}{@}\mdToken{Identifier,Python}{symbolic}}%mdk-data-line={626} {} specifying the type to use for a particular argument.% \end{mdP}% \begin{mdP}[class={indent},data-line={629}]% %mdk-data-line={629} {}The loader provides the capability to reload the module %mdk-data-line={630} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={630} {} so that the function %mdk-data-line={630} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={630} {} can be reexecuted within the same process from the same initial state with different inputs (see the class %mdk-data-line={632} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={632} {}) via the %mdk-data-line={633} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={633} {} class.% \end{mdP}% \begin{mdP}[class={indent},data-line={635}]% %mdk-data-line={635} {}Finally, the loader looks for specially named functions %mdk-data-line={635} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result}}%mdk-data-line={635} {} (%mdk-data-line={636} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result\_set}}%mdk-data-line={636} {}) in file %mdk-data-line={636} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}\mdToken{Delimiter,Python}{.}\mdToken{Identifier,Python}{py}}%mdk-data-line={636} {} to use as a test oracle after the path exploration (by %mdk-data-line={637} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={637} {}) has completed. These functions are expected to return a list of values to check against the list of return values collected from the executions of the %mdk-data-line={640} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{foo}}%mdk-data-line={640} {} function. The presence of the function %mdk-data-line={641} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result}}%mdk-data-line={641} {} (%mdk-data-line={641} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{expected\_result\_set}}%mdk-data-line={641} {}) yields a comparison of the two lists as bags (sets). We use such weaker tests, rather than list equality, because the order in which paths are explored by the %mdk-data-line={644} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={644} {} can easily change due to small differences in the input programs.% \end{mdP}% \mdHxxx[id=sec-symbolic-types,label={[4.2]\{.heading-label\}},toc={},data-line={647},caption={[[4.2]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Symbolic types},bookmark={4.2.{\hspace{0.5em}}Symbolic types}]{%mdk-data-line={647} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.2}.{\hspace{0.5em}}}%mdk-data-line={647} {}Symbolic types}\begin{mdP}[data-line={649}]% %mdk-data-line={649} {}Python supports multiple inheritance and, more importantly, allows user-defined classes to inherit from its built-in types (such as %mdk-data-line={651} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={651} {} and %mdk-data-line={651} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={651} {}). We use these two features two implement symbolic versions of Python objects and integers, following the instrumented type approach defined in Section%mdk-data-line={654} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={654} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={656}]% %mdk-data-line={656} {}The abstract class %mdk-data-line={656} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={656} {} contains the symbolic expression tree and provides basic functions for constructing and accessing the tree. This class does double duty, as it is used to represent the (typed) symbolic constants associated with the parameters to the function, as well as the expression trees (per Section%mdk-data-line={660} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-semantics}{}{\mdSpan[class={heading-label}]{2}}%mdk-data-line={660} {}). Recall that the symbolic constants only appear as leaves of expression trees. This means that the expression tree stored in a %mdk-data-line={662} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={662} {} will have instances of a %mdk-data-line={663} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={663} {} as some of its leaves, namely those leaves representing the symbolic constants. %mdk-data-line={665} {}%mdk-data-line={665} {} The abstract class provides an %mdk-data-line={666} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{unwrap}}%mdk-data-line={666} {} method which returns the pair of concrete value and expression tree associated with the %mdk-data-line={668} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={668} {}, as well as a %mdk-data-line={668} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{wrap}}%mdk-data-line={668} {} method that takes a pair of concrete value and expression tree and creates a %mdk-data-line={669} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={669} {} encapsulating them.% \end{mdP}% \begin{mdP}[class={indent},data-line={672}]% %mdk-data-line={672} {}The class %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={672} {} inherits from both %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={672} {} and %mdk-data-line={672} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={672} {} and overrides the basic comparison operations (%mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_eq\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_neq\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_lt\_\_}}%mdk-data-line={673} {}, %mdk-data-line={673} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_le\_\_}}%mdk-data-line={673} {}, %mdk-data-line={674} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_gt\_\_}}%mdk-data-line={674} {}, and %mdk-data-line={674} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_ge\_\_}}%mdk-data-line={674} {}). The class %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={675} {} inherits from both %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={675} {} and %mdk-data-line={675} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={675} {} and overrides a number of %mdk-data-line={676} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{int}}%mdk-data-line={676} {}{'}%mdk-data-line={676} {}s arithmetic methods (%mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_add\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_sub\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_mul\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_mod\_\_}}%mdk-data-line={677} {}, %mdk-data-line={677} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_floordiv\_}}%mdk-data-line={677} {}) and bitwise methods (%mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_and\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_or\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_xor\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_lshift\_\_}}%mdk-data-line={679} {}, %mdk-data-line={679} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_rshift\_\_}}%mdk-data-line={679} {}).% \end{mdP}% \mdHxxx[id=sec-tracing-control-flow,label={[4.3]\{.heading-label\}},toc={},data-line={682},caption={[[4.3]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Tracing control-flow},bookmark={4.3.{\hspace{0.5em}}Tracing control-flow}]{%mdk-data-line={682} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.3}.{\hspace{0.5em}}}%mdk-data-line={682} {}Tracing control-flow}\begin{mdP}[data-line={684}]% %mdk-data-line={684} {}As Python interprets a program, it will evaluate expressions, substituting the value of a variable in its place in an expression, applying operators (methods) to parameter values and assigning the return values of methods to variables. Value of type %mdk-data-line={688} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={688} {} will simply flow through this interpretation, without necessitating any change to the program or the interpreter. This takes care of the case of the strongest-postcondition rule for assignment, as elaborated in Section%mdk-data-line={692} {}{\mdNbsp}\mdA[class={localref},target-element={h2}]{sp-refined}{}{\mdSpan[class={heading-label}]{3.2}}%mdk-data-line={692} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={694}]% %mdk-data-line={694} {}The strong-postcondition rule for a conditional test requires a little more work. In Python, any object can be tested in an %mdk-data-line={696} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{if}}%mdk-data-line={696} {} or %mdk-data-line={696} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{while}}%mdk-data-line={696} {} condition or as the operand of a Boolean operation (%mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{and}}%mdk-data-line={697} {}, %mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{or}}%mdk-data-line={697} {}, %mdk-data-line={697} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Keyword,Python}{not}}%mdk-data-line={697} {}) The Python base class %mdk-data-line={698} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{object}}%mdk-data-line={698} {} provides a method named %mdk-data-line={698} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_bool\_\_}}%mdk-data-line={698} {} that the Python runtime calls whenever it needs to perform such a conditional test. This hook provides us what we need to trace the conditional control-flow of a Python execution. We override this method in the class %mdk-data-line={702} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={702} {} in order to inform the %mdk-data-line={702} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={702} {} object (defined later) of the symbolic expression for the conditional (as captured by the %mdk-data-line={704} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={704} {} subclass).% \end{mdP}% \begin{mdP}[class={indent},data-line={706}]% %mdk-data-line={706} {}Note that the use of this hook in combination with the tainted types will only trace those conditionals in a Python execution whose values inherit from %mdk-data-line={708} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={708} {}; by definition, %mdk-data-line={709} {}{\textquotedblleft}untainted{\textquotedblright}%mdk-data-line={709} {} conditionals do not depend on symbolic inputs so there is no value in adding them to the path-condition.% \end{mdP}% \mdHxxx[id=sec-recording-path-conditions,label={[4.4]\{.heading-label\}},toc={},data-line={712},caption={[[4.4]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Recording path-conditions},bookmark={4.4.{\hspace{0.5em}}Recording path-conditions}]{%mdk-data-line={712} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.4}.{\hspace{0.5em}}}%mdk-data-line={712} {}Recording path-conditions}\begin{mdP}[data-line={714}]% %mdk-data-line={714} {}A %mdk-data-line={714} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={714} {} records a conditional (more precisely the symbolic expression found in %mdk-data-line={715} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicInteger}}%mdk-data-line={715} {}) and which way it evaluated in an execution. A %mdk-data-line={716} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={716} {} has a %mdk-data-line={717} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={717} {}, a parent %mdk-data-line={717} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={717} {} and a set of %mdk-data-line={718} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={718} {} children. %mdk-data-line={718} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraints}}%mdk-data-line={718} {} form a tree, where each path starting from the root of the tree represents a path-condition. The tree represents all path-conditions that have been explored so far.% \end{mdP}% \begin{mdP}[class={indent},data-line={723}]% %mdk-data-line={723} {}The class %mdk-data-line={723} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={723} {} has a reference to the root of the tree of %mdk-data-line={724} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={724} {}s and is responsible for installing a new %mdk-data-line={725} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={725} {} in the tree when notified by the overridden %mdk-data-line={726} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Predefined,Python}{\_\_bool\_\_}}%mdk-data-line={726} {} method of %mdk-data-line={726} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicObject}}%mdk-data-line={726} {}. %mdk-data-line={727} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={727} {} also tracks whether or not the current execution is following an existing path in the tree and grows the tree as needed. In fact, it actually tracks whether or not the current execution follows a particular %mdk-data-line={731} {}\mdEm{expected path}%mdk-data-line={731} {} in the tree.% \end{mdP}% \begin{mdP}[class={indent},data-line={733}]% %mdk-data-line={733} {}The expected path is the result of the %mdk-data-line={734} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={734} {} picking a constraint %mdk-data-line={734} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={734} {} in the tree, and asking the ATP if the path-condition consisting of the prefix of predicates up to but not including %mdk-data-line={736} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={736} {} in the tree, followed by the negation of %mdk-data-line={737} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={737} {}{'}%mdk-data-line={737} {}s predicate is satisfiable. If the ATP returns %mdk-data-line={738} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={738} {} (with a new input %mdk-data-line={738} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={738} {}), then the assumption is that path-condition prefix is sound (that is, the execution of the program on input %mdk-data-line={740} {}\mdSpan[class={math-inline},elem={math-inline}]{$i$}%mdk-data-line={740} {} will follow the prefix).% \end{mdP}% \begin{mdP}[class={indent},data-line={742}]% %mdk-data-line={742} {}However, it is possible for the path-condition to be unsound and for the executed path to diverge early from the expected path, due to the fact that not every operation has a symbolic encoding. The tool simply reports the divergence and continues to process the execution as usual (as a diverging path may lead to some other interesting part of the code).% \end{mdP}% \mdHxxx[id=sec-from-symbolic-types-to-z3,label={[4.5]\{.heading-label\}},toc={},data-line={750},caption={[[4.5]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From symbolic types to Z3},bookmark={4.5.{\hspace{0.5em}}From symbolic types to Z3}]{%mdk-data-line={750} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.5}.{\hspace{0.5em}}}%mdk-data-line={750} {}From symbolic types to Z3}\begin{mdP}[data-line={752}]% %mdk-data-line={752} {}As we have explained DSE, the symbolic expressions are represented at the level of the source language. As detailed later in Section%mdk-data-line={754} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={754} {}, we must translate from the source language to the input language of an automated theorem prover (ATP), in this case%mdk-data-line={756} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={756} {}. This separation of languages is quite useful, as we may have the need to translate a given symbolic expression to the ATP%mdk-data-line={759} {}{'}%mdk-data-line={759} {}s language multiple times, to make use of different features of the underlying ATP. Furthermore, this separation of concerns allows us to easily retarget the DSE tool to a different ATP.% \end{mdP}% \begin{mdP}[class={indent},data-line={765}]% %mdk-data-line={765} {}The base class %mdk-data-line={765} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Expression}}%mdk-data-line={765} {} represents a Z3 formula. The two subclasses %mdk-data-line={766} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={766} {} and %mdk-data-line={766} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3BitVector}}%mdk-data-line={766} {} represent different ways to model arithmetic reasoning about integers in Z3. We will describe the details of these encodings in Section%mdk-data-line={768} {}{\mdNbsp}\mdA[class={localref},target-element={h1}]{sec-int2z3}{}{\mdSpan[class={heading-label}]{5}}%mdk-data-line={768} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={770}]% %mdk-data-line={770} {}The class %mdk-data-line={770} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Wrapper}}%mdk-data-line={770} {} is responsible for performing the translation from the source language (Python) to Z3%mdk-data-line={771} {}{'}%mdk-data-line={771} {}s input language, invoking Z3, and lifting a Z3 answer back to the level of Python. The %mdk-data-line={773} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{findCounterexample}}%mdk-data-line={773} {} method does all the work, taking as input a list of %mdk-data-line={774} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={774} {}s (called %mdk-data-line={774} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{assertions}}%mdk-data-line={774} {}) as well as a single %mdk-data-line={775} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={775} {} (called the %mdk-data-line={776} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={776} {}). The %mdk-data-line={776} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{assertions}}%mdk-data-line={776} {} represent a path-condition prefix derived from the %mdk-data-line={777} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={777} {} tree that we wish the next execution to follow, while %mdk-data-line={778} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={778} {} represents the predicate following the prefix in the tree that we will negate.% \end{mdP}% \begin{mdP}[class={indent,para-continue},data-line={781}]% %mdk-data-line={781} {}The method constructs the formula% \end{mdP}% \begin{mdDiv}[class={equation,para-block},label={[(4)]\{.equation-label\}},elem={equation},line-adjust={0},data-line={783}]% %mdk-data-line={783} {}\mdSpan[class={equation-before}]{\mdSpan[class={equation-label}]{(4)}}%mdk-data-line={783} {} \begin{mdDiv}[class={mathdisplay,para-block,input-math},elem={mathdisplay},color={},math-needpdf={},line-adjust={0},data-line={784}]% \begin{mdDiv}[class={math-display}]% \[%mdk-data-line={784} (\bigwedge_{a \in asserts} a) \wedge \neg query \]% \end{mdDiv}%% \end{mdDiv}%% \end{mdDiv}% \begin{mdP}[data-line={787}]% %mdk-data-line={787} {}and asks Z3 if it is satisfiable. The method performs a standard syntactic %mdk-data-line={788} {}{\textquotedblleft}cone of influence{\textquotedblright}%mdk-data-line={788} {} (CIF) reduction on the %mdk-data-line={789} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={789} {} with respect to the %mdk-data-line={790} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={790} {} to shrink the size of the formula. For example, if %mdk-data-line={791} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={791} {} is the set of predicates %mdk-data-line={791} {}\mdSpan[class={math-inline},elem={math-inline}]{$\{ (x0) \}$}%mdk-data-line={791} {} and the query is %mdk-data-line={792} {}\mdSpan[class={math-inline},elem={math-inline}]{$(x=0)$}%mdk-data-line={792} {}, then the CIF yields the set %mdk-data-line={793} {}\mdSpan[class={math-inline},elem={math-inline}]{$\{ (x0)$}%mdk-data-line={793} {}, as the variable %mdk-data-line={794} {}\mdSpan[class={math-inline},elem={math-inline}]{$y$}%mdk-data-line={794} {} is not in the set of variables (transitively) related to variable %mdk-data-line={795} {}\mdSpan[class={math-inline},elem={math-inline}]{$x$}%mdk-data-line={795} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={797}]% %mdk-data-line={797} {}If the formula is satisfiable a model is requested from Z3 and lifted back to Python%mdk-data-line={798} {}{'}%mdk-data-line={798} {}s type universe. Note that because of the CIF reduction, the model may not mention certain input variables, in which case we simply keep their values from the execution from which the %mdk-data-line={801} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{asserts}}%mdk-data-line={801} {} and %mdk-data-line={801} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Identifier,Python}{query}}%mdk-data-line={801} {} were derived.% \end{mdP}% \mdHxxx[id=sec-putting-it-all-together,label={[4.6]\{.heading-label\}},toc={},data-line={803},caption={[[4.6]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Putting it all together},bookmark={4.6.{\hspace{0.5em}}Putting it all together}]{%mdk-data-line={803} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{4.6}.{\hspace{0.5em}}}%mdk-data-line={803} {}Putting it all together}\begin{mdP}[data-line={805}]% %mdk-data-line={805} {}The class %mdk-data-line={805} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={805} {} ties everything together. It kicks off an execution of the Python code under test using %mdk-data-line={806} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{FunctionInvocation}}%mdk-data-line={806} {}. As the Python code executes, building symbolic expressions via %mdk-data-line={807} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{SymbolicType}}%mdk-data-line={807} {} and its subclasses, callbacks to %mdk-data-line={808} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{PathToConstraint}}%mdk-data-line={808} {} create a path-condition, represented by %mdk-data-line={809} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={809} {} and %mdk-data-line={809} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Predicate}}%mdk-data-line={809} {}. Newly discovered %mdk-data-line={810} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraints}}%mdk-data-line={810} {} are added to the end of a deque maintained by %mdk-data-line={811} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={811} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={813}]% %mdk-data-line={813} {}Given the first seed execution, %mdk-data-line={813} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{ExplorationEngine}}%mdk-data-line={813} {} starts the work of exploring paths in a breadth-first fashion. It removes a %mdk-data-line={814} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={814} {} %mdk-data-line={814} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={814} {} from the front of its deque and, if %mdk-data-line={815} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={815} {} has not been already %mdk-data-line={815} {}{\textquotedblleft}processed{\textquotedblright}%mdk-data-line={815} {}, uses %mdk-data-line={816} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Wrapper}}%mdk-data-line={816} {} to find a new input (as discussed in the previous section) where %mdk-data-line={817} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={817} {} is the query (to be negated) and the path to %mdk-data-line={817} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={817} {} in the %mdk-data-line={818} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={818} {} tree forms the assertions.% \end{mdP}% \begin{mdP}[class={indent},data-line={820}]% %mdk-data-line={820} {}A %mdk-data-line={820} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Constraint}}%mdk-data-line={820} {} %mdk-data-line={820} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={820} {} in the tree is considered %mdk-data-line={820} {}{\textquotedblleft}processed{\textquotedblright}%mdk-data-line={820} {} if an execution has covered %mdk-data-line={821} {}\mdSpan[class={math-inline},elem={math-inline}]{$c'$}%mdk-data-line={821} {}, a sibling of %mdk-data-line={821} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={821} {} in the tree that represents the negation of the predicate associated with %mdk-data-line={822} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={822} {}, or if constraint %mdk-data-line={822} {}\mdSpan[class={math-inline},elem={math-inline}]{$c$}%mdk-data-line={822} {} has been removed from the deque.% \end{mdP}% \mdHxx[id=sec-int2z3,label={[5]\{.heading-label\}},toc={},data-line={825},caption={[[5]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}From Python Integers to Z3 Arithmetic},bookmark={5.{\hspace{0.5em}}From Python Integers to Z3 Arithmetic}]{%mdk-data-line={825} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{5}.{\hspace{0.5em}}}%mdk-data-line={825} {}From Python Integers to Z3 Arithmetic}\begin{mdP}[data-line={827}]% %mdk-data-line={827} {}In languages such as C and Java, integers are finite-precision, generally limited to the size of a machine word (32 or 64 bits, for example). For such languages, satisfiability of finite-precision integer arithmetic is decidable and can be reduced to Z3%mdk-data-line={830} {}{'}%mdk-data-line={830} {}s theory of bit-vectors, where each arithmetic operation is encoded by a circuit. This translation permits reasoning about non-linear arithmetic problems, such as %mdk-data-line={833} {}\mdSpan[class={math-inline},elem={math-inline}]{$\exists x,y,z : x*z + y \leq (z/y)+5$}%mdk-data-line={833} {}.% \end{mdP}% \begin{mdP}[class={indent},data-line={835}]% %mdk-data-line={835} {}Python (3.0) integers, however, are not finite-precision. They are only limited by the size of machine memory. This means, for example, that Python integers don%mdk-data-line={837} {}{'}%mdk-data-line={837} {}t overflow or underflow. It also means that we can%mdk-data-line={838} {}{'}%mdk-data-line={838} {}t hope to decide algorithmically whether or not a given equation over integer variables has a solution in general. Hilbert%mdk-data-line={839} {}{'}%mdk-data-line={839} {}s famous 10th problem and its solution by Matiyasevich tells us that it is undecidable whether or not a polynomial equation of the form %mdk-data-line={842} {}\mdSpan[class={math-inline},elem={math-inline}]{$p(x_1, \ldots, x_n) = 0$}%mdk-data-line={842} {} with integer coefficients has an solution in the integers.% \end{mdP}% \begin{mdP}[class={indent},data-line={845}]% %mdk-data-line={845} {}This means that we will resort to heuristic approaches in our use of the%mdk-data-line={846} {}{\mdNbsp}\mdA[data-linkid={z3}]{http://z3.codeplex.org/}{}{Z3}%mdk-data-line={846} {} ATP. The special case of linear integer arithmetic (LIA) is decidable and supported by Z3. In order to deal with non-linear operations, we use uninterpreted functions (UF). Thus, if Z3 returns %mdk-data-line={849} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={849} {} we know that there is no solution, but if the Z3 %mdk-data-line={850} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={850} {}, we must treat the answer as a %mdk-data-line={850} {}{\textquotedblleft}don{'}t know{\textquotedblright}%mdk-data-line={850} {}. The class %mdk-data-line={851} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={851} {} is used to translate a symbolic expression into the theory LIA+UF and check for unsatisfiability. We leave it as an implementation exercise to check if a symbolic expression can be converted to LIA (without the use of UF) in order to make use of %mdk-data-line={855} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={855} {} answers from the LIA solver.% \end{mdP}% \begin{mdP}[class={indent},data-line={857}]% %mdk-data-line={857} {}If the translation to %mdk-data-line={857} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3Integer}}%mdk-data-line={857} {} does not return %mdk-data-line={857} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={857} {}, we use Z3%mdk-data-line={858} {}{'}%mdk-data-line={858} {}s bit-vector decision procedure (via the class %mdk-data-line={859} {}\mdCode[class={code,code1,language-python,lang-python,python,highlighted},language={python}]{\mdToken{Namespace,Identifier,Python}{Z3BitVector}}%mdk-data-line={859} {}) to heuristically try to find satisfiable answers, even in the presence of non-linear arithmetic. We start with bit-vectors of size %mdk-data-line={861} {}\mdSpan[class={math-inline},elem={math-inline}]{$N=32$}%mdk-data-line={861} {} and %mdk-data-line={861} {}\mdEm{bound}%mdk-data-line={861} {} the values of the symbolic constants to fit within 8 bits in order to find satisfiable solutions with small values. Also, because Python integers do not overflow/underflow, the bound helps us reserve space in the bit-vector to allow the results of operations to exceed the bound while not overflowing the bit-vector. As long as Z3 returns %mdk-data-line={867} {}{\textquotedblleft}unsatisfiable{\textquotedblright}%mdk-data-line={867} {} we increase the bound. If the bound reaches %mdk-data-line={868} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={868} {}, we increase %mdk-data-line={868} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={868} {} by 8 bits, leaving the bound where it is and continue.% \end{mdP}% \begin{mdP}[class={indent},data-line={871}]% %mdk-data-line={871} {}If Z3 returns %mdk-data-line={872} {}{\textquotedblleft}satisfiable{\textquotedblright}%mdk-data-line={872} {}, it may be the case that Z3 found a solution that involved overflow in the bit-vector world of arithmetic (modulo %mdk-data-line={874} {}\mdSpan[class={math-inline},elem={math-inline}]{$2^N-1$}%mdk-data-line={874} {}). Therefore, the solution is validated back in the Python world by evaluating the formula under that solution using Python semantics. If the formula does not evaluate to the same value in both worlds, then we increase %mdk-data-line={879} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={879} {} by 8 bits (to create a gap between the bound and %mdk-data-line={880} {}\mdSpan[class={math-inline},elem={math-inline}]{$N$}%mdk-data-line={880} {}) and continue to search for a solution.% \end{mdP}% \begin{mdP}[class={indent},data-line={883}]% %mdk-data-line={883} {}The process terminates when we find a valid satisfying solution or %mdk-data-line={884} {}\mdSpan[class={math-inline},elem={math-inline}]{$N=64$}%mdk-data-line={884} {} and the bound reaches 64 (in which case, we return %mdk-data-line={884} {}{\textquotedblleft}don{'}t know{\textquotedblright}%mdk-data-line={884} {}).% \end{mdP}% \mdHxx[id=sec-extensions,label={[6]\{.heading-label\}},toc={},data-line={886},caption={[[6]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Extensions},bookmark={6.{\hspace{0.5em}}Extensions}]{%mdk-data-line={886} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{6}.{\hspace{0.5em}}}%mdk-data-line={886} {}Extensions}\begin{mdP}[data-line={888}]% %mdk-data-line={888} {}We have presented the basics of dynamic symbolic execution (for Python). A more thorough treatment would deal with other data types besides integers, such as Python dictionaries, strings and lists, each of which presents their own challenges for symbolic reasoning. There are many other interesting challenges in DSE, such as dealing with user-defined classes (rather than built-in types as done here) and multi-threaded execution.% \end{mdP}% \mdHxx[id=sec-acknowledgements,label={[7]\{.heading-label\}},toc={},data-line={897},caption={[[7]\{.heading-label\}.{\hspace{0.5em}}]\{.heading-before\}Acknowledgements},bookmark={7.{\hspace{0.5em}}Acknowledgements}]{%mdk-data-line={897} {}\mdSpan[class={heading-before}]{\mdSpan[class={heading-label}]{7}.{\hspace{0.5em}}}%mdk-data-line={897} {}Acknowledgements}\begin{mdP}[data-line={899}]% %mdk-data-line={899} {}Many thanks to the students of the 2014 Marktoberdorf Summer School on Dependable Software Systems Engineering for their questions and feedback about the first author%mdk-data-line={901} {}{'}%mdk-data-line={901} {}s lectures on dynamic symbolic execution. The following students of the summer school helpfully provided tests for the%mdk-data-line={903} {}{\mdNbsp}\mdA[data-linkid={pyexz3}]{https://github.com/thomasjball/PyExZ3/}{}{PyExZ3}%mdk-data-line={903} {} tool: Daniel Darvas, Damien Rusinek, Christian Dehnert and Thomas Pani. Thanks also to Peter Chapman for his contributions.% \end{mdP}% \mdHxx[id=sec-references,label={8},toc={},data-line={963},caption={References},bookmark={References}]{%mdk-data-line={963} {}References}\begin{mdBibliography}[class={bibliography,bib-numeric},elem={bibliography},bibstyle={plainnat},bibdata={dse},caption={14},data-line={964;out{\textbackslash}DSE-bib.bbl:2}]% \begin{mdBibitem}[class={bibitem},id=cadare05,label={[1]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar and Engler(2005)},caption={Cristian Cadar and Dawson{\textbackslash} R. Engler. \\Execution generated test cases: How to make systems code crash itself. \\In \_Proceedings of 12th International SPIN Workshop\_{\textbackslash}/, pages 2--23, 2005.},searchterm={Cristian+Cadar+Dawson+Engler+Execution+generated+test+cases+make+systems+code+crash+itself+\_Proceedings+International+SPIN+Workshop\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:5}]% %mdk-data-line={964;out\DSE-bib.bbl:6} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{1}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:6} {}Cristian Cadar and Dawson%mdk-data-line={964;out\DSE-bib.bbl:6} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:6} {}R. Engler. %mdk-data-line={964;out\DSE-bib.bbl:7} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:7} {} Execution generated test cases: How to make systems code crash itself. %mdk-data-line={964;out\DSE-bib.bbl:9} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:9} {} In %mdk-data-line={964;out\DSE-bib.bbl:9} {}\mdEm{Proceedings of 12th International SPIN Workshop}%mdk-data-line={964;out\DSE-bib.bbl:9} {}%mdk-data-line={964;out\DSE-bib.bbl:9} {}, pages 2%mdk-data-line={964;out\DSE-bib.bbl:10} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:10} {}23, 2005.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=cadars13,label={[2]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar and Sen(2013)},caption={Cristian Cadar and Koushik Sen. \\Symbolic execution for software testing: three decades later.},searchterm={Symbolic+execution+software+testing+three+decades+later++Cristian+Cadar+Koushik+},data-line={964;out{\textbackslash}DSE-bib.bbl:13}]% %mdk-data-line={964;out\DSE-bib.bbl:14} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{2}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:14} {}Cristian Cadar and Koushik Sen. %mdk-data-line={964;out\DSE-bib.bbl:15} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:15} {} Symbolic execution for software testing: three decades later. %mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} %mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:16} {}%mdk-data-line={964;out\DSE-bib.bbl:16} {}, 56%mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} (2):%mdk-data-line={964;out\DSE-bib.bbl:16} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:16} {} 82%mdk-data-line={964;out\DSE-bib.bbl:16} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:16} {}90, 2013.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=cadargpde06,label={[3]\{.bibitem-label\}},elem={bibitem},cite-label={Cadar et{\textbackslash} al.(2006)Cadar, Ganesh, Pawlowski, Dill, and\\ Engler},caption={Cristian Cadar, Vijay Ganesh, Peter{\textbackslash} M. Pawlowski, David{\textbackslash} L. Dill, and Dawson{\textbackslash} R. Engler. \\EXE: automatically generating inputs of death. \\In \_Proceedings of the 13th ACM Conference on Computer and Communications Security\_{\textbackslash}/, pages 322--335, 2006.},searchterm={Cristian+Cadar+Vijay+Ganesh+Peter+Pawlowski+David+Dill+Dawson+Engler+automatically+generating+inputs+death+\_Proceedings+Conference+Computer+Communications+Security\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:20}]% %mdk-data-line={964;out\DSE-bib.bbl:21} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{3}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:21} {}Cristian Cadar, Vijay Ganesh, Peter%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}M. Pawlowski, David%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}L. Dill, and Dawson%mdk-data-line={964;out\DSE-bib.bbl:21} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:21} {}R. Engler. %mdk-data-line={964;out\DSE-bib.bbl:23} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:23} {} EXE: automatically generating inputs of death. %mdk-data-line={964;out\DSE-bib.bbl:24} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:24} {} In %mdk-data-line={964;out\DSE-bib.bbl:24} {}\mdEm{Proceedings of the 13th ACM Conference on Computer and Communications Security}%mdk-data-line={964;out\DSE-bib.bbl:25} {}%mdk-data-line={964;out\DSE-bib.bbl:25} {}, pages 322%mdk-data-line={964;out\DSE-bib.bbl:25} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:25} {}335, 2006.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=clarke76,label={[4]\{.bibitem-label\}},elem={bibitem},cite-label={Clarke(1976)},caption={Lori{\textbackslash} A. Clarke. \\A system to generate test data and symbolically execute programs.},searchterm={+system+generate+test+data+symbolically+execute+programs++Lori+Clarke+},data-line={964;out{\textbackslash}DSE-bib.bbl:28}]% %mdk-data-line={964;out\DSE-bib.bbl:29} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{4}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:29} {}Lori%mdk-data-line={964;out\DSE-bib.bbl:29} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:29} {}A. Clarke. %mdk-data-line={964;out\DSE-bib.bbl:30} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:30} {} A system to generate test data and symbolically execute programs. %mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:31} {} %mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdEm{IEEE Transactions on Software Engineering}%mdk-data-line={964;out\DSE-bib.bbl:31} {}%mdk-data-line={964;out\DSE-bib.bbl:31} {}, 2%mdk-data-line={964;out\DSE-bib.bbl:31} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:31} {} (3):%mdk-data-line={964;out\DSE-bib.bbl:32} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:32} {} 215%mdk-data-line={964;out\DSE-bib.bbl:32} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:32} {}222, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=demourab08,label={[5]\{.bibitem-label\}},elem={bibitem},cite-label={de{\textbackslash} Moura and Bj{\o}rner(2008)},caption={Leonardo{\textbackslash} Mendon{\c{c}}a de{\textbackslash} Moura and Nikolaj Bj{\o}rner. \\Z3: an efficient SMT solver.},searchterm={+efficient+solver++Leonardo+Mendon+Moura+Nikolaj+rner+},data-line={964;out{\textbackslash}DSE-bib.bbl:35}]% %mdk-data-line={964;out\DSE-bib.bbl:36} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{5}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Leonardo%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Mendon%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\c{c}}%mdk-data-line={964;out\DSE-bib.bbl:36} {}a de%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:36} {}Moura and Nikolaj Bj%mdk-data-line={964;out\DSE-bib.bbl:36} {}{\o}%mdk-data-line={964;out\DSE-bib.bbl:36} {}rner. %mdk-data-line={964;out\DSE-bib.bbl:37} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:37} {} Z3: an efficient SMT solver. %mdk-data-line={964;out\DSE-bib.bbl:38} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:38} {} In %mdk-data-line={964;out\DSE-bib.bbl:38} {}\mdEm{Proceedings of the 14th International Conference of Tools and Algorithms for the Construction and Analysis of Systems}%mdk-data-line={964;out\DSE-bib.bbl:39} {}%mdk-data-line={964;out\DSE-bib.bbl:39} {}, pages 337%mdk-data-line={964;out\DSE-bib.bbl:39} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:39} {}340, 2008.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=dijkstra76,label={[6]\{.bibitem-label\}},elem={bibitem},cite-label={Dijkstra(1976)},caption={Edsger{\textbackslash} W. Dijkstra. \\\_A Discipline of Programming\_{\textbackslash}/.},searchterm={+Discipline+Programming\_++Edsger+Dijkstra+},data-line={964;out{\textbackslash}DSE-bib.bbl:43}]% %mdk-data-line={964;out\DSE-bib.bbl:44} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{6}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:44} {}Edsger%mdk-data-line={964;out\DSE-bib.bbl:44} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:44} {}W. Dijkstra. %mdk-data-line={964;out\DSE-bib.bbl:45} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:45} {} %mdk-data-line={964;out\DSE-bib.bbl:45} {}\mdEm{A Discipline of Programming}%mdk-data-line={964;out\DSE-bib.bbl:45} {}%mdk-data-line={964;out\DSE-bib.bbl:45} {}. %mdk-data-line={964;out\DSE-bib.bbl:46} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:46} {} Prentice-Hall, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroid11,label={[7]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid(2011)},caption={Patrice Godefroid. \\Higher-order test generation.},searchterm={Higher+order+test+generation++Patrice+Godefroid+},data-line={964;out{\textbackslash}DSE-bib.bbl:49}]% %mdk-data-line={964;out\DSE-bib.bbl:50} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{7}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:50} {}Patrice Godefroid. %mdk-data-line={964;out\DSE-bib.bbl:51} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:51} {} Higher-order test generation. %mdk-data-line={964;out\DSE-bib.bbl:52} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:52} {} In %mdk-data-line={964;out\DSE-bib.bbl:52} {}\mdEm{Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation}%mdk-data-line={964;out\DSE-bib.bbl:53} {}%mdk-data-line={964;out\DSE-bib.bbl:53} {}, pages 258%mdk-data-line={964;out\DSE-bib.bbl:53} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:53} {}269, 2011.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroidks05,label={[8]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid et{\textbackslash} al.(2005)Godefroid, Klarlund, and Sen},caption={Patrice Godefroid, Nils Klarlund, and Koushik Sen. \\DART: directed automated random testing.},searchterm={DART+directed+automated+random+testing++Patrice+Godefroid+Nils+Klarlund+Koushik+},data-line={964;out{\textbackslash}DSE-bib.bbl:56}]% %mdk-data-line={964;out\DSE-bib.bbl:57} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{8}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:57} {}Patrice Godefroid, Nils Klarlund, and Koushik Sen. %mdk-data-line={964;out\DSE-bib.bbl:58} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:58} {} DART: directed automated random testing. %mdk-data-line={964;out\DSE-bib.bbl:59} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:59} {} In %mdk-data-line={964;out\DSE-bib.bbl:59} {}\mdEm{Proceedings of the ACM SIGPLAN Conference on Programming Language Design and Implementation}%mdk-data-line={964;out\DSE-bib.bbl:60} {}%mdk-data-line={964;out\DSE-bib.bbl:60} {}, pages 213%mdk-data-line={964;out\DSE-bib.bbl:60} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:60} {}223, 2005.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=godefroidlm12,label={[9]\{.bibitem-label\}},elem={bibitem},cite-label={Godefroid et{\textbackslash} al.(2012)Godefroid, Levin, and Molnar},caption={Patrice Godefroid, Michael{\textbackslash} Y. Levin, and David{\textbackslash} A. Molnar. \\SAGE: whitebox fuzzing for security testing.},searchterm={SAGE+whitebox+fuzzing+security+testing++Patrice+Godefroid+Michael+Levin+David+Molnar+},data-line={964;out{\textbackslash}DSE-bib.bbl:63}]% %mdk-data-line={964;out\DSE-bib.bbl:64} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{9}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:64} {}Patrice Godefroid, Michael%mdk-data-line={964;out\DSE-bib.bbl:64} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:64} {}Y. Levin, and David%mdk-data-line={964;out\DSE-bib.bbl:64} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:64} {}A. Molnar. %mdk-data-line={964;out\DSE-bib.bbl:65} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:65} {} SAGE: whitebox fuzzing for security testing. %mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} %mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:66} {}%mdk-data-line={964;out\DSE-bib.bbl:66} {}, 55%mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} (3):%mdk-data-line={964;out\DSE-bib.bbl:66} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:66} {} 40%mdk-data-line={964;out\DSE-bib.bbl:66} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:66} {}44, 2012.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=gupta00,label={[10]\{.bibitem-label\}},elem={bibitem},cite-label={Gupta et{\textbackslash} al.(2000)Gupta, Mathur, and Soffa},caption={Neelam Gupta, Aditya{\textbackslash} P. Mathur, and Mary{\textbackslash} Lou Soffa. \\Generating test data for branch coverage.},searchterm={Generating+test+data+branch+coverage++Neelam+Gupta+Aditya+Mathur+Mary+Soffa+},data-line={964;out{\textbackslash}DSE-bib.bbl:70}]% %mdk-data-line={964;out\DSE-bib.bbl:71} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{10}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:71} {}Neelam Gupta, Aditya%mdk-data-line={964;out\DSE-bib.bbl:71} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:71} {}P. Mathur, and Mary%mdk-data-line={964;out\DSE-bib.bbl:71} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:71} {}Lou Soffa. %mdk-data-line={964;out\DSE-bib.bbl:72} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:72} {} Generating test data for branch coverage. %mdk-data-line={964;out\DSE-bib.bbl:73} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:73} {} In %mdk-data-line={964;out\DSE-bib.bbl:73} {}\mdEm{Proceedings of the Automate Software Engineering Conference}%mdk-data-line={964;out\DSE-bib.bbl:74} {}%mdk-data-line={964;out\DSE-bib.bbl:74} {}, pages 219%mdk-data-line={964;out\DSE-bib.bbl:74} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:74} {}228, 2000.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=king76,label={[11]\{.bibitem-label\}},elem={bibitem},cite-label={King(1976)},caption={James{\textbackslash} C. King. \\Symbolic execution and program testing.},searchterm={Symbolic+execution+program+testing++James+King+},data-line={964;out{\textbackslash}DSE-bib.bbl:77}]% %mdk-data-line={964;out\DSE-bib.bbl:78} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{11}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:78} {}James%mdk-data-line={964;out\DSE-bib.bbl:78} {}{\mdNbsp}%mdk-data-line={964;out\DSE-bib.bbl:78} {}C. King. %mdk-data-line={964;out\DSE-bib.bbl:79} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:79} {} Symbolic execution and program testing. %mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} %mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdEm{Communications of the ACM}%mdk-data-line={964;out\DSE-bib.bbl:80} {}%mdk-data-line={964;out\DSE-bib.bbl:80} {}, 19%mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} (7):%mdk-data-line={964;out\DSE-bib.bbl:80} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:80} {} 385–394, 1976.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=korel90,label={[12]\{.bibitem-label\}},elem={bibitem},cite-label={Korel(1990)},caption={Bogdan Korel. \\Automated software test data generation.},searchterm={Automated+software+test+data+generation++Bogdan+Korel+},data-line={964;out{\textbackslash}DSE-bib.bbl:84}]% %mdk-data-line={964;out\DSE-bib.bbl:85} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{12}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:85} {}Bogdan Korel. %mdk-data-line={964;out\DSE-bib.bbl:86} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:86} {} Automated software test data generation. %mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:87} {} %mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdEm{IEEE Transactions on Software Engineering}%mdk-data-line={964;out\DSE-bib.bbl:87} {}%mdk-data-line={964;out\DSE-bib.bbl:87} {}, 16%mdk-data-line={964;out\DSE-bib.bbl:87} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:87} {} (8):%mdk-data-line={964;out\DSE-bib.bbl:88} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:88} {} 870%mdk-data-line={964;out\DSE-bib.bbl:88} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:88} {}879, 1990.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=korel92,label={[13]\{.bibitem-label\}},elem={bibitem},cite-label={Korel(1992)},caption={Bogdan Korel. \\Dynamic method of software test data generation.},searchterm={Dynamic+method+software+test+data+generation++Bogdan+Korel+},data-line={964;out{\textbackslash}DSE-bib.bbl:91}]% %mdk-data-line={964;out\DSE-bib.bbl:92} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{13}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:92} {}Bogdan Korel. %mdk-data-line={964;out\DSE-bib.bbl:93} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:93} {} Dynamic method of software test data generation. %mdk-data-line={964;out\DSE-bib.bbl:94} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:94} {} %mdk-data-line={964;out\DSE-bib.bbl:94} {}\mdEm{Journal of Software Testing, Verification and Reliability}%mdk-data-line={964;out\DSE-bib.bbl:94} {}%mdk-data-line={964;out\DSE-bib.bbl:94} {}, 2%mdk-data-line={964;out\DSE-bib.bbl:95} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:95} {} (4):%mdk-data-line={964;out\DSE-bib.bbl:95} {}\mdSpan[penalty={0}]{}%mdk-data-line={964;out\DSE-bib.bbl:95} {} 203%mdk-data-line={964;out\DSE-bib.bbl:95} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:95} {}213, 1992.% \end{mdBibitem}% \begin{mdBibitem}[class={bibitem},id=senacav06,label={[14]\{.bibitem-label\}},elem={bibitem},cite-label={Sen and Agha(2006)},caption={Koushik Sen and Gul Agha. \\CUTE and jcute: Concolic unit testing and explicit path model-checking tools. \\In \_Proceedings of 18th Computer Aided Verification Conference\_{\textbackslash}/, pages 419--423, 2006.},searchterm={Koushik+Agha+CUTE+jcute+Concolic+unit+testing+explicit+path+model+checking+tools+\_Proceedings+Computer+Aided+Verification+Conference\_+pages++},data-line={964;out{\textbackslash}DSE-bib.bbl:98}]% %mdk-data-line={964;out\DSE-bib.bbl:99} {}\mdSpan[class={bibitem-before}]{[\mdSpan[class={bibitem-label}]{14}]{\mdNbsp}{\mdNbsp}}%mdk-data-line={964;out\DSE-bib.bbl:99} {}Koushik Sen and Gul Agha. %mdk-data-line={964;out\DSE-bib.bbl:100} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:100} {} CUTE and jcute: Concolic unit testing and explicit path model-checking tools. %mdk-data-line={964;out\DSE-bib.bbl:102} {}\mdSpan[class={newblock}]{}%mdk-data-line={964;out\DSE-bib.bbl:102} {} In %mdk-data-line={964;out\DSE-bib.bbl:102} {}\mdEm{Proceedings of 18th Computer Aided Verification Conference}%mdk-data-line={964;out\DSE-bib.bbl:102} {}%mdk-data-line={964;out\DSE-bib.bbl:102} {}, pages 419%mdk-data-line={964;out\DSE-bib.bbl:103} {}{\textendash}%mdk-data-line={964;out\DSE-bib.bbl:103} {}423, 2006.% \end{mdBibitem}%% \end{mdBibliography}% \end{document} ================================================ FILE: marktoberdorf_paper/forPublisher/madoko.sty ================================================ %--------------------------------------------------------------------------- % Copyright 2013 Microsoft Corporation. % % This is free software; you can redistribute it and/or modify it under the % terms of the Apache License, Version 2.0. A copy of the License can be % found in the file "license.txt" at the root of this distribution. %--------------------------------------------------------------------------- \NeedsTeXFormat{LaTeX2e}[1995/12/01] \RequirePackage{css} \RequirePackage{array} \RequirePackage{longtable} \RequirePackage{enumitem} \RequirePackage{booktabs} \RequirePackage{pdfcomment} %\RequirePackage[bookmarks=true]{hyperref} % loaded by pdfcomment \RequirePackage{amsmath} \RequirePackage{amsfonts} \RequirePackage{amssymb} \RequirePackage{stmaryrd} \RequirePackage{textcomp} \RequirePackage{pifont} \RequirePackage{wrapfig} %------------------------------------------------------------- % Process options %------------------------------------------------------------- \newcommand{\mdHeadingBase}{1} \DeclareOptionX{heading-base}[1]{\gdef\mdHeadingBase{#1}} \ProcessOptionsX %------------------------------------------------------------- % Conditionals %------------------------------------------------------------- % conditionals \newif\ifmathmode \newif\ifbeamer \@ifclassloaded{beamer}{\beamertrue}{\beamerfalse} \ifdef\mathmode{\mathmodetrue}{\mathmodefalse} %------------------------------------------------------------- % Setup packages %------------------------------------------------------------- % hyperref \hypersetup{ colorlinks=true,linkcolor=Navy,urlcolor=Blue,filecolor=Maroon,bookmarksdepth=3,bookmarksopenlevel=1 } % booktabs \setlength{\aboverulesep}{0pt} \setlength{\belowrulesep}{0pt} \setlength{\doublerulesep}{\heavyrulewidth} %------------------------------------------------------------- % Character commands %------------------------------------------------------------- \providecommand{\lt}{\ensuremath{<}} \providecommand{\gt}{\ensuremath{>}} \providecommand{\abs}[1]{\ensuremath{\left\vert #1\right\vert}} %\providecommand{\bigstrut}{-0.5\baselineskip}{0pt}{1.5\baselineskip} %\providecommand{\deepstrut}{-0.5\baselineskip}{0pt}{0.5\baselineskip} %\providecommand{\highstrut}{0pt}{0pt}{\baselineskip} % inserted for unknown html entities \newcommand{\mdUnknownEntity}[1]{\} \newcommand{\mdEntity}[1]{\protect\mdUnknownEntity{#1}} % allow the definition of new entities: \mdDefineEntity{bar}{\|} \newcommand{\mdDefineEntity}[2]{% \protected@edef\mdEntity##1{\protect\eifstrequal{##1}{#1}{#2}{\mdEntity{##1}}}% } % inserted for unknown unicode entities \newcommand{\mdUnicodeUnknown}[1]{% \ifXeTeX\mdUnicodeChar{#1}\else% \ifLuaTeX\mdUnicodeChar{#1}\else% \&\##1;\fi\fi } \newcommand{\mdUnicodeChar}[1]{\char#1} % directly insert the unicode glyph \newcommand{\mdUnicode}[1]{\protect\mdUnicodeUnknown{#1}} % allow the definition of new unicode entities: \mdDefineUnicode{10214}{\ensuremath{\llbracket}} \newcommand{\mdDefineUnicode}[2]{% \protected@edef\mdUnicode##1{\protect\ifnum##1=#1{#2}\protect\else{\mdUnicode{##1}}\protect\fi}% } % ballot boxes \mdDefineUnicode{9745}{\rlap{$\square$}\protect\raisebox{.15ex}{\kern 0.1em\ding{51}}} \mdDefineUnicode{9746}{\rlap{$\square$}{\kern 0.1em\ding{55}}} % magnifying glass \mdDefineUnicode{128270}{\kern -0.75ex\protect\raisebox{-0.25ex}{$\arrownot$}\kern 1.05ex\protect\raisebox{0.5ex}{$\circ$}\hspace{-0.25ex}} % short underscore \mdDefineUnicode{818}{\leavevmode\kern 0.06em\vbox{\hrule width 0.3em}} % qed \providecommand{\qedsymbol}{\ensuremath{\Box}} \providecommand{\qed}{\hfill\qedsymbol} % break and nbsp \newcommand{\mdBr}{\ifvmode\leavevmode\fi\\{}} \newcommand{\mdNbsp}{\nobreak\rule{0pt}{0pt}~} \newcommand{\mdBrSep}[2]{% \expandafter\ifx#1\relax\relax #2\else \expandafter\ifx#2\relax\relax #1\else #1\mdBr #2\fi\fi } % fix nobreakspace in case the user loads a T1 encoding in LaTeX \DeclareTextCommandDefault{\nobreakspace}{\leavevmode\nobreak\ } % logo \cssClassRuleDoBefore{madokologo}{\vfill} % We need to call \mdLabeltarget for any structure that can set label \newcounter{@mdTargetCount} \newcommand{\mdLabeltarget}{\refstepcounter{@mdTargetCount}} %------------------------------------------------------------- % Title and subtitle %------------------------------------------------------------- \providecommand{\@doi}{?} \ifdef\titlerunning% {\newcommand{\mdTitlerunning}[1]{\titlerunning{#1}}}% llncs {\newcommand{\mdTitlerunning}[1]{\global\def\titlerunning{#1}}}% eptcs \ifdef\authorrunning% {\newcommand{\mdAuthorrunning}[1]{\authorrunning{#1}}}% llncs {\newcommand{\mdAuthorrunning}[1]{\global\def\authorrunning{#1}}}% eptcs % LLNCS: \author{ \and ...}, \institute{ \email \and ...} % EPTCS: \author{ \institute \email \and ... } % LATEX: \author{ ... } \date \ifdef\date{\date{}}{} \providecommand{\email}[1]{\normalsize\textsf{#1}}% \providecommand{\affaddr}[1]{\normalsize{#1}}% \providecommand{\alignauthor}{\\[2ex]} \providecommand{\aufnt}[1]{{\large #1}} \providecommand{\numberofauthors}[1]{} \ifbeamer\providecommand{\inst}[1]{$^{\mbox{#1}}$}\fi% % If there is no \authorinfo, we provide a simple one that works % with some other common styles \newcounter{mdAuthorCount} \newcommand{\@mdauthors}{} % fancy list of authors \newcommand{\@mdinsts}{} \providerobustcmd{\@and}{\and} \providerobustcmd{\authorinfo}[3]{% \stepcounter{mdAuthorCount}% \ifdef{\institute}{% \ifnum\value{mdAuthorCount}>1% \gappto\@mdauthors{\@and}% \ifx\relax#2\relax\else\gappto\@mdinsts{\@and}\fi% \fi% \ifdef{\inst}% {%LLNCS, Beamer \gappto\@mdauthors{#1}% \ifx\relax#2\relax\else\gappto\@mdinsts{#2}\fi% \ifx\relax#3\relax\else\gappto\@mdinsts{\mdBr\email{#3}}\fi }% {% EPTCS \gappto\@mdauthors{#1% \ifx\relax#2\relax\else\protect\institute{#2}\fi% \ifx\relax#3\relax\else\protect\email{#3}\fi}% }% }% {% Our own simple style (similar to sigplanconf) \ifnum\value{mdAuthorCount}>1% \gappto\@mdauthors{\alignauthor}% \fi% \gappto\@mdauthors{\aufnt{#1}}% \protected@edef\@more{#2#3}% \expandafter\ifx\@more\relax\relax \else \gappto\@mdauthors{\\[0.25ex]\mdBrSep{#2}{#3}}% \fi }% \ifnum\value{mdAuthorCount}>1% \gappto\@mdauthorsx{, #1}% \else \global\def\@mdauthorsx{#1}% \fi \mdAuthorrunning{\@mdauthorsx}% } % support \inst \newcommand{\mdInst}[1]{% \ifdef{\inst}{\inst{#1}}{\ensuremath{^{\mbox{#1}}}}% } \cssClassRuleCmd{inst}{\mdInst} \newcommand{\mdTitle}[1]{\gdef\@mdTitle{#1}\title{\@mdTitle}\mdTitlerunning{#1}} \newcommand{\mdSubtitle}[1]{\gappto\@mdTitle{\\{\Large #1}}\title{\@mdTitle}} % legacy \newcommand{\mdAuthor}[4]{% \authorinfo{#1}{\mdBrSep{#2}{#4}}{#3}% } % and finally maketitle \newcommand{\mdMaketitle}[1]{% \ifnum\value{mdAuthorCount}>0% \expandnext{\numberofauthors}{\arabic{mdAuthorCount}}% \author{\@mdauthors}% \ifdef\inst{\ifdef\institute{\institute{\@mdinsts}}{}}{}% \fi \ifx#1\relax\else% %\ifdef\titlenote% some styles disregard the date command... {%\gappto\@mdTitle{\titlenote{#1}}\title{\@mdTitle}} \mdSubtitle{\normalfont\normalsize #1}}% % {\date{#1}}% \fi% \maketitle% } % Use the pre-defined abstract environment \cssElemRuleEnv{abstract}{abstract} % and define it if not yet defined \ifdef{\abstract}{}{ \newenvironment{abstract}% {\list{}{\small \leftmargin=2.65em% \labelwidth=0em% \listparindent=0em% \itemindent\listparindent \rightmargin\leftmargin}\item[\hskip\labelsep\bfseries Abstract.]} {\endlist} } %------------------------------------------------------------- % Hooks to use maketitle from standard title blocks %------------------------------------------------------------- \def\@mdTitleNote{} \newcounter{mdxAuthorCount} \defcommand{\mdxTitle}[2][]{\mdTitle{\mdSpan[#1]{#2}}} \defcommand{\mdxTitleNote}[2][]{\gdef\@mdTitleNote{\mdSpan[#1]{#2}}} \defcommand{\mdxTitleFooter}[2][]{\gappto{\@mdauthors}{\\[1ex]\mdSpan[#1]{#2}}} \defcommand{\mdxSubTitle}[2][]{\mdSubtitle{\mdSpan[#1]{#2}}} \defcommand{\mdxAuthorName}[2][]{\csgdef{@mdAuthorName\the\value{mdxAuthorCount}}{\mdSpan[#1]{#2}}} \defcommand{\mdxAuthorAddress}[2][]{\csgdef{@mdAuthorAff\the\value{mdxAuthorCount}}{\mdSpan[#1]{#2}}} \defcommand{\mdxAuthorEmail}[2][]{\csgdef{@mdAuthorEmail\the\value{mdxAuthorCount}}{\mdSpan[#1]{\email{#2}}}} \defcommand{\mdxAuthorNote}[2][]{% \ifcsdef{@mdAuthorAff\the\value{mdxAuthorCount}}% {\csgappto{@mdAuthorAff\the\value{mdxAuthorCount}}{\mdBr\mdSpan[#1]{#2}}} {\csgdef{@mdAuthorAff\the\value{mdxAuthorCount}}{\mdSpan[#1]{#2}}} } \cssClassRuleDoBefore{titleblockmaketitle}{% \setcounter{mdxAuthorCount}{0}% } \cssClassRuleDoBefore{authormaketitle}{% \global\stepcounter{mdxAuthorCount}% } \cssClassRuleDoAfter{authormaketitle}{% \providecsgdef{@mdAuthorName\the\value{mdxAuthorCount}}{}% \providecsgdef{@mdAuthorAff\the\value{mdxAuthorCount}}{}% \providecsgdef{@mdAuthorEmail\the\value{mdxAuthorCount}}{}% \expandnextiii{\authorinfo}% {\csname @mdAuthorName\the\value{mdxAuthorCount}\endcsname}% {\csname @mdAuthorAff\the\value{mdxAuthorCount}\endcsname}% {\csname @mdAuthorEmail\the\value{mdxAuthorCount}\endcsname}% } \cssClassRuleDoAfter{titleblockmaketitle}{% \mdMaketitle{\@mdTitleNote}% } %------------------------------------------------------------- % Paragraphs and indentation %------------------------------------------------------------- \newcommand{\mdParIndent}{\parindent} \cssClassRule{indent}{text-indent=\mdParIndent} \cssClassRule{para-block}{text-indent=0pt} \cssNewBlockElem{mdP}{p}{} \cssParentClassRule{align-center}{text-align=center,margin-left=auto,margin-right=auto} \cssClassRule{hidden}{display=hidden} %------------------------------------------------------------- % Common Inline elements %------------------------------------------------------------- \cssNewInlineElem{\mdEm}{em}{font-style=italic} \cssNewInlineElem{\mdStrong}{strong}{font-weight=bold} \cssNewInlineElem{\mdDel}{del}{color=gray} % not great but strike-out is just not well supported on LaTeX... \cssNewKey{css}{label}{\cssLabel}{} \newcommand{\mdFootnote}[2][]{% \mdSpan[#1]{\gdef\@thefnmark{\cssLabel}\@footnotemark}\@footnotetext{#2}% %\footnote{#2}} % no cssInline since footnotes can contain block elements } \newcommand{\mdSub}[2][]{\ensuremath{_{\mbox{\scriptsize\cssInline[elem=sub,#1]{#2}}}}} \newcommand{\mdSup}[2][]{\ensuremath{^{\mbox{\scriptsize\cssInline[elem=sup,#1]{#2}}}}} \cssClassRule{footnote-backref}{display=hidden} \cssClassRule{footnote-before}{display=hidden} \newcommand{\mdTooltip}[2]{% #2% \eifstrequal{#1}{}{}{% \hbox to 0pt{\raisebox{1ex}{\tiny% \pdfmarkupcomment[color=White,author=Title]{}{#1}% }}% }% } \newcommand{\@mdHyperref}[2]{\hyperref[#1]{#2}} \newcommand{\@mdMakeA}[2]{% \cssIfHasClass{localref}% {\@mdHyperref{#1}{#2}% \cssIfHasClass{bibref}{\write\@mainaux{\string\citation{#1}}}{}}% {\href{#1}{#2}}% } \newcommand{\mdA}[4][]{\mdTooltip{#3}{\cssInlineCmd[#1]{\@mdMakeA{#2}}{#4}}} %------------------------------------------------------------- % Headers %------------------------------------------------------------- \cssNewKey{css}{bookmark}{\cssBookmark}{} \newcommand{\mdBookmark}[3]{\eifstrequal{#2}{}{}{\pdfbookmark[#1]{#2}{#3}}} \newcommand{\mdHBookmark}[2]{% \ifnum#1<\mdHeadingBase\edef\@mdlevel{#1}\else\edef\@mdlevel{\the\numexpr#1-\mdHeadingBase}\fi% \cssInitKeys{#2}\mdBookmark{\@mdlevel}{\cssBookmark}{\cssId}% } \cssNewKey{css}{starform}{\cssStarForm}{} \newcommand{\mdCommandStar}[3][]{% \cssInitKeys{#1}% \eifstrequal{\cssStarForm}{true}{\csname #2\endcsname*{#3}}{\csname #2\endcsname{#3}}% } \newcommand{\mdCommandUnStar}[3][]{% \cssInitKeys{#1}% \eifstrequal{\cssStarForm}{false}{\csname #2\endcsname{#3}}{\csname #2\endcsname*{#3}}% } \newcommand{\mdH}[2][]{\mdHBookmark{0}{#1}\mdCommandUnStar[#1]{part}{\cssInline[elem=h0,#1]{#2}}} \newcommand{\mdHx}[2][]{\mdHBookmark{1}{#1}\mdCommandUnStar[#1]{chapter}{\cssInline[elem=h1,#1]{#2}}} \newcommand{\mdHxx}[2][]{\mdHBookmark{2}{#1}\mdCommandUnStar[#1]{section}{\cssInline[elem=h2,#1]{#2}}} \newcommand{\mdHxxx}[2][]{\mdHBookmark{3}{#1}\mdCommandUnStar[#1]{subsection}{\cssInline[elem=h3,#1]{#2}}} \newcommand{\mdHxxxx}[2][]{\mdHBookmark{4}{#1}\mdCommandUnStar[#1]{subsubsection}{\cssInline[elem=h4,#1]{#2}}} \newcommand{\mdHxxxxx}[2][]{\mdCommandUnStar[#1]{paragraph}{\cssInline[elem=h5,#1]{#2}}} \newcommand{\mdHxxxxxx}[2][]{\mdCommandUnStar[#1]{paragraph}{\cssInline[elem=h6,#1]{#2}}} \newenvironment{mdSection}[1][]{\mdHBookmark{2}{#1}\begin{mdDiv}[#1]}{\end{mdDiv}} %\patchcmd{\@startsection}% % {\@ssect{#3}{#4}{#5}{#6}}% % {\@dblarg{\@sect{#1}{\@m}{#3}{#4}{#5}{#6}}}% % {}% % {\PackageError{madoko}{Unable to patch \string\@startsection}\@ehd} %------------------------------------------------------------- % Common block elements %------------------------------------------------------------- \cssNewInlineElem{\mdSpan}{span}{} \cssNewBlockElem{mdDiv}{div}{} \cssNewBlockElem{mdDivInline}{divinline}{display=block-inline} \newenvironment{mdBlockquote}[1][]% {\begin{mdDiv}[#1]\begin{quote}}% {\end{quote}\end{mdDiv}} %------------------------------------------------------------- % Images %------------------------------------------------------------- \newcommand{\@imgInclude}[4]{% \begin{minipage}[#1]{#2}% \eifstrequal{#1}{c}% {$\vcenter{\hbox{\protect\includegraphics[#4]{#3}}}$}% {\eifstrequal{#1}{t}{\vspace{-0.7\baselineskip}}{}% \protect\includegraphics[#4]{#3}}% \end{minipage}% } \newcommand{\@imgArgs}{} \newcommand{\mdImg}[2][]{% \begingroup% \cssNewLengthKey{csspre}{width}{\cssImageWidth} % capture width and height \cssNewLengthKey{csspre}{height}{\cssImageHeight} \cssInline[elem=img,#1]{% \renewcommand{\@imgArgs}{keepaspectratio=true}% \ifdim\cssImageWidth=2sp\def\cssImageWidth{\linewidth}\fi% \ifdim\cssImageWidth<3sp\else\appto{\@imgArgs}{,width=\cssImageWidth}\fi% \ifdim\cssImageHeight<3sp\else\appto{\@imgArgs}{,height=\cssImageHeight}\fi \eifstrequal{\@imgArgs}{}% {\includegraphics{#2}}% {\eifstrequal{\cssVerticalAlign}{top}% {\expandnext{\@imgInclude{t}{\cssImageWidth}{#2}}{\@imgArgs}}% {\eifstrequal{\cssVerticalAlign}{middle}% {\expandnext{\@imgInclude{c}{\cssImageWidth}{#2}}{\@imgArgs}}% {\expandnext{\@imgInclude{b}{\cssImageWidth}{#2}}{\@imgArgs}}}% }% }% \endgroup% }% %------------------------------------------------------------- % Math %------------------------------------------------------------- \newenvironment{mdMathprearray}% {\setlength{\arraycolsep}{0pt}\begin {array}{llllllll}}% {\end{array}\hspace*{\linewidth minus \linewidth}} % flush left \defcommand{\mathkw}[1]{\mathsf{{#1}}} \defcommand{\mathid}[1]{\mathit{#1}} \defcommand{\smallstrut}{\mbox{\rule{0ex}{1ex}}} \newcommand{\mdMathspace}[1]{\mskip\numexpr4*#1\relax mu plus #1mu minus #1mu\smallstrut} \newcommand{\mdMathindent}[1]{\mskip\numexpr8*#1\relax mu\smallstrut} \newcommand{\mdMathbr}{\\} % Equation tags are stored in mdTag (which resets automatically after each math display) \newcommand{\mdTag}{} \preto{\]}{\mdTag\global\def\mdTag{}} % hookup in math displays \newcommand{\mdEquationbefore}[1]{% \global\def\mdTag{\tag*{#1}}% use the amsmath tag command to set the label \mdLabeltarget% } \cssClassRuleCmd{equation-before}{\mdEquationbefore} %------------------------------------------------------------- % Helper to allow use of standard math environments %------------------------------------------------------------- \cssNewKey{css}{env}{\cssEnv}{theorem} \newsavebox{\mdThmBox} \newenvironment{mdThmCaption}[1][] {\global\setbox\mdThmBox\hbox\bgroup\ignorespaces} {\egroup} \newenvironment{mdThm}[1][]% {\cssInitKeys{#1}\begin{\cssEnv}% \global\setbox\mdThmBox\hbox{}}% {\end{\cssEnv}} %------------------------------------------------------------- % Lists %------------------------------------------------------------- \newlength{\xtopsep} \newenvironment{mdUl}[1][]% {\begin{mdDiv}[#1]% \setlength{\xtopsep}{\topsep}% \addtolength{\topsep}{-\cssMarginTop}% \eifstrequal{\cssListStyleType}{}% {\def\@endlist{\end{itemize}}\begin{itemize}[topsep=\xtopsep]}% {\@mdSetListLabel% \def\@endlist{\end{enumerate}}\expandnext{\begin{enumerate}[topsep=\xtopsep,start=\cssStart,}{\@label}]}% \cssIfHasClass{compact}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}{}% }% {\strut\@endlist\end{mdDiv}} \cssNewKey{css}{start}{\cssStart}{1} \cssNewKey{css}{list-style-type}{\cssListStyleType}{} \newcommand{\@mdSetListLabel}{% \cssIfHasClass{list-sep-paren}% {\def\@labelsep{)}% \eifstrequal{\cssListStyleType}{}{\def\cssListStyleType{decimal}}{}}% {\def\@labelsep{.}} \eifstrequal{\cssListStyleType}{lower-roman}% {\def\@label{label=\roman*\@labelsep}}% {\eifstrequal{\cssListStyleType}{upper-roman}% {\def\@label{label=\Roman*\@labelsep}}% {\eifstrequal{\cssListStyleType}{lower-alpha}% {\def\@label{label=\alph*\@labelsep}}% {\eifstrequal{\cssListStyleType}{upper-alpha}% {\def\@label{label=\Alph*\@labelsep}}% {\eifstrequal{\cssListStyleType}{decimal}% {\def\@label{label=\arabic*\@labelsep}}% {\eifstrequal{\cssListStyleType}{disc}% {\def\@label{label=\textbullet}}% {\eifstrequal{\cssListStyleType}{circle}% {\def\@label{label=$\circ$}}% {\eifstrequal{\cssListStyleType}{square}% {\def\@label{label=$\blacksquare$}}% {\eifstrequal{\cssListStyleType}{dash}% {\def\@label{label={--}}}% {\eifstrequal{\cssListStyleType}{none}% {\def\@label{label=}}% {\def\@label{}}}}}}}}}}}% } \newenvironment{mdOl}[1][]% {\ifdef\@enhook{\PackageError{madoko}{You cannot use the package "enumerate" in madoko;\MessageBreak use the "enumitem" package instead\MessageBreak (which is available by default)}{}}{}% \begin{mdDiv}[#1]% \setlength{\xtopsep}{\topsep}% \addtolength{\topsep}{-\cssMarginTop}% \@mdSetListLabel% \expandnext{\begin{enumerate}[topsep=\xtopsep,start=\cssStart,}{\@label}]% \cssIfHasClass{compact}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}{}% }% {\strut\end{enumerate}\end{mdDiv}} \newenvironment{mdLi}[1][]{\item\mdLabeltarget\begin{mdDivInline}[#1]}{\end{mdDivInline}} \newenvironment{mdDl}[1][]% {\begin{mdDiv}[#1]% \setlength{\xtopsep}{\topsep}% \addtolength{\topsep}{-\cssMarginTop}% \begin{itemize}[leftmargin=0pt,topsep=\xtopsep]% \vspace{-\itemsep}% \cssIfHasClass{compact}{\setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}{}% }% {\end{itemize}\end{mdDiv}}% \newenvironment{mdDt}[1][]% {\item[]\begin{mdDiv}[#1]}% {\end{mdDiv}}% \newenvironment{mdDd}[1][]% {\begin{mdDiv}[#1]}% {\end{mdDiv}}% % --------------------------------------------------- % Bibliography % --------------------------------------------------- \cssNewKey{css}{caption}{\cssCaption}{?} \newKey{css}{bibstyle}{% \eifstrequal{#1}{}% {\write\@mainaux{\string\bibstyle{plain}}}% {\write\@mainaux{\string\bibstyle{#1}}} } \newKey{css}{bibdata}{\write\@mainaux{\string\bibdata{#1}}} \newcommand{\mdBibDisplay}{inline} \newcommand{\mdBibBefore}{\ifdef\inst{\vspace{-4ex}}{}} \newcommand{\@ignore}[2][]{} % ignore argument (and optional argument) \newenvironment{mdBibliography}[1][]{% \begin{mdDiv}[#1]% \ifdef\section{\def\section{\@ifstar\@ignore\@ignore}}{}% suppress bibliography header \ifdef\chapter{\def\chapter{\@ifstar\@ignore\@ignore}}{}% suppress bibliography header \providecommand{\markboth}[2]{}% \cssIfHasClass{bib-authoryear}{\def\mdBibDisplay{hidden}}{}% \begin{thebibliography}{\cssCaption}\setlength{\topsep}{0pt}\mdBibBefore}% {\markboth{}{}\end{thebibliography}\end{mdDiv}} \cssNewKey{css}{cite-label}{\cssCiteLabel}{} \newenvironment{mdBibitem}[1][]{% \item[]\mdLabeltarget\begin{mdDivInline}[#1]\hspace*{-\leftmargin}}% {\end{mdDivInline}\par} \cssClassRule{bibitem-before}{display=\mdBibDisplay,width=\leftmargin,text-align=right} \providecommand{\newblock}{\hskip .11em plus .33em minus .07em} \cssClassRuleDoBefore{newblock}{\protect\newblock} % --------------------------------------------------- % Table of contents % --------------------------------------------------- % until this level, the entry is bold \newcommand{\mdTocLevelBold}{1} % until this level, no dots are used \newcommand{\mdTocLevelNodots}{1} \newlength{\mdTocIndent} \setlength{\mdTocIndent}{1.3em} \cssNewKeyNoReset{css}{toclevel}{\cssTocLevel}{1} \cssNewKeyNoReset{css}{toctarget}{\cssTocTarget}{no-toc-target} \cssElemRule{tocitem}{display=block-inline} \cssClassRuleDoBefore{tocitem}{% \ifnum\cssTocLevel>\mdTocLevelBold\relax\else\bfseries\fi% \noindent\hspace*{-\mdTocIndent}\hspace*{\cssTocLevel\mdTocIndent}}% \cssClassRuleDoAfter{tocitem}{% \hspace{1ex}% \ifnum\cssTocLevel>\mdTocLevelNodots\dotfill\else\hfill\fi% \hspace{1ex}\pageref{\cssTocTarget}}% % --------------------------------------------------- % Tables % --------------------------------------------------- \newcommand{\mdCellstrut}{}%\mbox{\rule{-0.1ex}{1.8ex}}} \newlength{\mdLineWidth} \setlength{\mdLineWidth}{\linewidth} \newlength{\mdDefaultColumnWidth} \newcommand{\mdTableInit}[1]{% \setlength{\tabcolsep}{0.5ex}% \setlength{\mdLineWidth}{\dimexpr\linewidth-\tabcolsep*2*#1-\tabcolsep\relax}% the line length minus table spacing \setlength{\mdDefaultColumnWidth}{\dimexpr\mdLineWidth/#1\relax}% \setlength{\linewidth}{\mdLineWidth} } \newenvironment{mdTable}[3][]{% [attributes]{column-count}{column-specifiers} \begin{mdDiv}[#1]% \mdTableInit{#2}% \begin{tabular}{#3}}{\end{tabular}\end{mdDiv}} \newenvironment{mdLongTable}[3][]{% [attributes]{column-count}{column-specifiers} \begin{mdDiv}[#1]% \mdTableInit{#2}% \begin{longtable}{#3}}{\end{longtable}\end{mdDiv}} \newenvironment{mdThead}[1][]{}{} \newenvironment{mdTbody}[1][]{}{} \cssNewBlockElem{mdColumn}{column}{width=\mdDefaultColumnWidth} \newcommand{\mdTr}[2][]{\mdSpan[#1]{#2}} \newcommand{\mdTd}[2][]{\mdSpan[#1]{\mdCellstrut #2}} \newcommand{\mdTh}[2][]{\mdSpan[font-weight=bold,#1]{#2}} \newlength{\mdTablelineskip} \setlength{\mdTablelineskip}{2.4ex} % --------------------------------------------------- % Figures % --------------------------------------------------- \cssNewKey{css}{page-align}{\cssPageAlign}{} \cssNewKey{css}{float-env}{\cssFloatEnv}{figure} \newcommand{\mdFloating}{% \eifstrequal{\cssPageAlign}{top}% {\def\@pagealign{t}}% {\eifstrequal{\cssPageAlign}{bottom}% {\def\@pagealign{b}}% {\eifstrequal{\cssPageAlign}{here}% {\def\@pagealign{ht}}% {\eifstrequal{\cssPageAlign}{page}% {\def\@pagealign{p}}% {\eifstrequal{\cssPageAlign}{forcehere}% {\def\@pagealign{!ht}}% {\def\@pagealign{tbp}}}}}}% default tbp %\cssDoAfter{\cssRestoreFootnotes}% \eifstrequal{\cssFloat}{left}% {}% {\eifstrequal{\cssFloat}{right}% {}% {\cssIfHasClass{wide}% {\cssDoBefore{\expandnext{\begin{\cssFloatEnv*}[}{\@pagealign}]}\cssDoAfter{\end{\cssFloatEnv*}}}% {\cssDoBefore{\expandnext{\begin{\cssFloatEnv}[}{\@pagealign}]}\cssDoAfter{\end{\cssFloatEnv}}}% }}% %\cssDoBefore{\cssSaveFootnotes}% } \cssElemRuleDo{floating}{\mdFloating} \newlength{\mdCaptionlen} \newcommand{\mdCaption}[1]{% \settowidth{\mdCaptionlen}{#1}% \ifnum\mdCaptionlen<\linewidth% \parbox{\linewidth}{\noindent\centering #1}% \else% \parbox{\linewidth}{\noindent #1}% \fi% } \cssClassRuleCmd{figure-caption}{\mdCaption} \cssClassRule{figure-caption}{text-align=justify}% prevents insertion of hspace{\fill} due to outer align-center % participate in listoffigures and listoftables \newcommand{\mdCaptionText}[1]{% \addcontentsline{\csname ext@\@captype\endcsname}{\@captype}% {\protect\numberline{\@mdCaptionLabel}{\ignorespaces #1}}% #1 } \cssClassRuleCmd{caption-text}{\mdCaptionText} \newcommand{\mdCaptionLabel}[1]{% \global\gdef\@mdCaptionLabel{#1}% #1 } \cssClassRuleCmd{figure-label}{\mdCaptionLabel} \cssClassRuleCmd{table-label}{\mdCaptionLabel} \newcommand{\mdHr}[2][]{% \begingroup% \cssNewLengthKey{csspre}{width}{\cssHrWidth}% capture width %\relax\ifhmode\par\fi% \begin{mdDiv}[height=1ex,vertical-align=center,text-align=center,#1]{% \ifdim\cssHrWidth=0pt\setlength{\cssHrWidth}{\linewidth}\fi% \rule{\cssHrWidth}{\cssPixel}#2}% \end{mdDiv}% \endgroup} \cssClassRule{block}{margin-top=\topsep,margin-bottom=\topsep} %------------------------------------------------------------- % Float boxes (should this be in css.sty?) %------------------------------------------------------------- \newlength{\@sideheight} \newsavebox{\@sidebox} \newcommand{\mdFloatBox}[3]{ \savebox{\@sidebox}{#3}% \ifdim\ht\@sidebox>0pt\relax% \savebox{\@sidebox}{\raisebox{-\ht\@sidebox}{\usebox{\@sidebox}}}% top-align the box \fi% \ifnum 0=0#2\relax% \setlength{\@sideheight}{\dp\@sidebox}% \addtolength{\@sideheight}{\ht\@sidebox}% \def\@hangafter{\the\numexpr(0 - \@sideheight - \baselineskip/2)/\baselineskip\relax}% \else% \def\@hangafter{-#2}% \fi% \eifstrequal{#1}{right}% {\hangindent=-\wd\@sidebox% \hangafter=\@hangafter% \smash{\hspace*{\dimexpr\textwidth - \wd\@sidebox}\usebox{\@sidebox}}% }% {\hangindent=\wd\@sidebox% \hangafter=\@hangafter% \smash{\usebox{\@sidebox}}% }% } %------------------------------------------------------------- % Code and syntax highlighting %------------------------------------------------------------- \newcommand{\mdPrettyFont}{serif} \newenvironment{mdPre}[1][]% {\begin{cssBlockX}{elem=pre,margin-top=1ex,margin-bottom=1ex,text-indent=0pt,font-family=monospace}{text-align=left,#1}}% text-align must come after defaults due to parent rules.. {\end{cssBlockX}}% \cssNewInlineElem{\mdCode}{code}{font-family=monospace} \cssNewInlineElem{\mdPrecode}{precode}{} \cssClassRule{pretty}{font-family=\mdPrettyFont} \cssClassRuleDo{pretty}{\def\@tokenPostfix{Pretty}} \newlength{\presp} \settowidth{\presp}{\texttt{ }} \newcommand{\prespace}[1]{\hspace*{#1\presp}} \newcommand{\preindent}[1]{\hspace*{#1\presp}} \newcommand{\prebr}{\strut\\} % pretty layout \newenvironment{mdCodeTable}[3][]{% [attributes]{column-count}{column-specifiers} \begin{mdDiv}[#1]% \mdTableInit{#2}% \mdPrettyInit% \begin{tabular}{#3}}{\end{tabular}\end{mdDiv}} \newenvironment{mdCodeLongTable}[3][]{% [attributes]{column-count}{column-specifiers} \begin{mdDiv}[#1]% \mdTableInit{#2}% \mdPrettyInit% \begin{longtable}{#3}}{\end{longtable}\end{mdDiv}} \newcommand\mdPrettyInit{% \setlength{\tabcolsep}{0pt}% \def\prespace{\pprespace}% \def\preindent{\ppreindent}% \def\prebr{\pprebr}% } \newlength{\ppresp} \setlength{\ppresp}{0.5ex} \newcommand{\ppreindent}[1]{\hspace*{3\ppresp}}%{\hspace*{#1\ppresp}} \newcommand{\pprespace}[1]{\hspace*{\ppresp}} \newcommand{\pprebr}[1]{ } % Tokens for highlighting \cssNewKey{css}{language}{\cssLanguage}{} \newcommand{\@tokenPostfix}{} \newcommand{\@tokencmd}[1]{#1} \newcommand{\mdToken}[2]{% \renewcommand{\@tokencmd}[1]{##1}% \@for\@tname:=#1\do{% \ifcsdef{mdToken\@tokenPostfix\@tname}{\apptox{\@tokencmd}{\csname mdToken\@tokenPostfix\@tname\endcsname}}{}% }% \@tokencmd{#2}% } %------------------------------------------------------------- % Standard token classes for syntax highlighting %------------------------------------------------------------- \newcommand{\mdTokenIdentifier}[1]{#1} \newcommand{\mdTokenKeyword}[1]{\textcolor{Navy}{#1}} \newcommand{\mdTokenPredefined}[1]{\textcolor{Navy}{#1}} \newcommand{\mdTokenString}[1]{\textcolor{Maroon}{#1}} \newcommand{\mdTokenStringEscape}[1]{\textcolor{Gray}{#1}} \newcommand{\mdTokenComment}[1]{\textcolor{Green}{#1}} \newcommand{\mdTokenSpecial}[1]{\textcolor{Navy}{#1}} \newcommand{\mdTokenDoc}[1]{\textcolor{Gray}{#1}} \newcommand{\mdTokenConstant}[1]{\textcolor{Purple}{#1}} \newcommand{\mdTokenTag}[1]{\textcolor{Navy}{#1}} \newcommand{\mdTokenError}[1]{\textcolor{Red}{#1}} \newcommand{\mdTokenAttribute}[1]{\textcolor{Purple}{#1}} \newcommand{\mdTokenConstructor}[1]{\textcolor{Purple}{#1}} \newcommand{\mdTokenNamespace}[1]{\textcolor{Navy}{#1}} \newcommand{\mdTokenType}[1]{\textcolor{Teal}{#1}} \newcommand{\mdTokenEmphasis}[1]{\itshape #1} \newcommand{\mdTokenStrong}[1]{\bfseries #1} \newcommand{\mdTokenTitle}[1]{\bfseries #1} \newcommand{\mdTokenMeta}[1]{\textcolor{Gray}{#1}} \newcommand{\mdTokenEntity}[1]{{#1}} \newcommand{\mdTokenDelimiter}[1]{{#1}} \newcommand{\mdTokenNumber}[1]{\mdTokenConstant{#1}} \newcommand{\mdTokenLiteral}[1]{\mdTokenConstant{#1}} \newcommand{\mdTokenItalic}[1]{\mdTokenEmphasis{#1}} \newcommand{\mdTokenBold}[1]{\mdTokenStrong{#1}} \newcommand{\mdTokenRegexp}[1]{\mdTokenString{#1}} \newcommand{\mdTokenInvalid}[1]{\mdTokenError{#1}} \newcommand{\mdTokenValue}[1]{\mdTokenString{#1}} % Pretty tokens \newcommand{\mdTokenPrettyIdentifier}[1]{\textit{#1}} \newcommand{\mdTokenPrettyConstructor}[1]{\textit{#1}} \newcommand{\mdTokenPrettyKeyword}[1]{\textsf{#1}} \newcommand{\mdTokenPrettyOperator}[1]{\,#1\,} % --------------------------------------------------- % Support the Beamer class % --------------------------------------------------- \ifbeamer% \renewcommand{\@mdHyperref}[2]{\hyperlink{#1}{#2}}% \renewcommand{\mdH}[2][]{\frametitle{\cssInline[elem=h0,#1]{#2}}}% \renewcommand{\mdHx}[2][]{\frametitle{\cssInline[elem=h1,#1]{#2}}}% \renewcommand{\mdHxx}[2][]{\frametitle{\cssInline[elem=h2,#1]{#2}}}% \renewenvironment{mdSection}[1][]{\begin{mdDiv}[#1]\begin{frame}\stepcounter{beamerpauses}}{\end{frame}\end{mdDiv}}% % handle fragments \cssClassRuleDo{fragment}{% \eifstrequal{\cssDisplay}{inline}% {\cssWrapCmd{\only<+->}}% {\cssDoBefore{\begin{onlyenv}<+->}\cssDoAfter{\end{onlyenv}}}% } \cssClassRuleDoBefore{pause}{\pause{}}% % item appearance on a list defined with a fragmented class \let\old@mdLi\mdLi% \let\old@endmdLi\endmdLi% \def\mdLi{% \begingroup\def\@fragmentend{}% use fragmented class from the parent (ie. ul or ol) \cssIfHasClass{fragmented}{\def\@fragmentend{\end{onlyenv}}\begin{onlyenv}<+->}{}% \old@mdLi}% \def\endmdLi{% \old@endmdLi\@fragmentend\endgroup% }% \fi % --------------------------------------------------- % Math snippets for static image generation % --------------------------------------------------- % re-define some symbols \renewcommand{\notin}{\not\in} %turns out the baseline for 'notin' is wrong % boxes and lengths \newsavebox{\@snippetBox} \newlength{\@snippetWidth} \newlength{\@snippetHeight} \newlength{\@snippetDepth} \newcounter{snippets} \newcommand{\@savedepth}{% \setlength{\@snippetWidth}{\wd\@snippetBox}% \setlength{\@snippetHeight}{\ht\@snippetBox}% \setlength{\@snippetDepth}{\dp\@snippetBox}% \addtolength{\@snippetHeight}{\@snippetDepth}% \immediate\write\foo{\arabic{snippets},\@snippetName,\the\@snippetWidth,\the\@snippetHeight,\the\@snippetDepth}% \noindent\usebox\@snippetBox% } \newenvironment{mdDisplaySnippet}[1][\arabic{snippets}]% {\stepcounter{snippets}\edef\@snippetName{#1}% \begin{lrbox}{\@snippetBox}\vbox\bgroup}% {\egroup\end{lrbox}\@savedepth\newpage} \newenvironment{mdInlineSnippet}[1][\arabic{snippets}]% {\stepcounter{snippets}\def\@snippetName{#1}% \begin{lrbox}{\@snippetBox}}% {\end{lrbox}\@savedepth\newpage} \newenvironment{mdSnippets}% {\pagestyle{empty}% \abovedisplayskip=0pt% \belowdisplayskip=0pt% \abovedisplayshortskip=0pt% \belowdisplayshortskip=0pt% \newwrite\foo\immediate\openout\foo=\jobname.dim% \immediate\write\foo{\%ordinal,(hash)name,width,(total) height,depth,image width,image height,dpi,base64 encoding}% }% {\closeout\foo} ================================================ FILE: marktoberdorf_slides/collatz.py ================================================ def collatz(n): if n <= 1: return 1 else: if n % 2 == 0: return collatz(n // 2) else: return collatz(3 * n + 1) def max_iters(): return 10 def expected_result_set(): return [1] ================================================ FILE: marktoberdorf_slides/examples/adder.py ================================================ from z3 import * def add1(x0,y0,c0): return (simplify(Xor(Xor(x0,y0),c0)), simplify(Or(And(x0,y0),And(x0,c0),And(y0,c0)))) def addN(xN,yN,cin): res = [] cout = cin for (x,y) in zip(xN,yN): (new_res,cout) = add1(x,y,cout) res.append(new_res) return (res,cout) ================================================ FILE: marktoberdorf_slides/examples/automata.py ================================================ from z3 import * Char = BitVecSort(8) List = Datatype('List') List.declare('cons', ('head', Char), ('tail', List)) List.declare('nil') List = List.create() # abbreviations cons = List.cons head = List.head tail = List.tail nil = List.nil Bool = BoolSort() # don't use model-based quantifier instantiation here set_param('smt.mbqi', False) solver = SimpleSolver() # we will set up axioms to solve for the regular expression # [0-9]+|[a-z] q0 = Function('q0',List,Bool) q1 = Function('q1',List,Bool) q2 = Function('q2',List,Bool) q3 = Function('q3',List,Bool) q4 = Function('q4',List,Bool) y = Const('y',List) # qo -[e]-> q1, qo -[e]-> q3 def q0axiom(): body = q0(y) == Or(q1(y),q3(y)) return ForAll(y, body, patterns = [q0(y)]) # q1 -[0..9]-> q2 def q1axiom(): body = q1(y) == And(y!=nil,ULE(ord('0'),head(y)),ULE(head(y),ord('9')),\ q2(tail(y))) return ForAll(y, body, patterns = [q1(y)]) # q2 -[0..9] -> q2 (q2 is final) def q2axiom(): body = q2(y) == Or(y==nil,And(y!=nil,ULE(ord('0'),head(y)),ULE(head(y),ord('9')),q2(tail(y)))) return ForAll(y, body, patterns = [q2(y)]) # q3 -[a-z]-> q4 def q3axiom(): body = q3(y) == And(y!=nil,ULE(ord('a'),head(y)),ULE(head(y),ord('z')),q4(tail(y))) return ForAll(y, body, patterns = [q3(y)]) # (q4 is final) def q4axiom(): body = q4(y) == (y==nil) return ForAll(y, body, patterns = [q4(y)]) #to generate longer results def lengthGE(x,k): axiom = BoolVal(True) for i in range(k): axiom = And(axiom,Not(x == nil)) x = tail(x) return axiom def test(): solver.add(q0axiom(),q1axiom(),q2axiom(),q3axiom(),q4axiom()) y = Const('y',List) solver.add(lengthGE(y,4)) solver.add(q0(y)) print(solver.assertions()) ok = solver.check() assert(ok != unsat) print(solver.model()) yVal = solver.model().evaluate(y,True) print(yVal) test() ================================================ FILE: marktoberdorf_slides/examples/check_adder.py ================================================ from adder import * N = 128 # now prove that adder is equal to bitvector add xN = BoolVector("x",N) yN = BoolVector("y",N) x_bv = BitVec("x_bv",N) y_bv = BitVec("y_bv",N) # need to equate the inputs (Extract(lo,hi,bv) def eq_bool(bv, i, b): return (Extract(i,i,bv) == 1) == b def eq_bitvec_boolvec(bitvec,boolvec): return [ eq_bool(bitvec,i,boolvec[i]) for i in range(bitvec.size()) ] inputs_equal = eq_bitvec_boolvec(x_bv,xN) + eq_bitvec_boolvec(y_bv,yN) res,cout = addN(xN,yN,BoolVal(False)) res_bv = x_bv + y_bv outputs_equal = eq_bitvec_boolvec(res_bv,res) s = Solver() s.add(And(inputs_equal)) s.add(Not(And(outputs_equal))) #print(s.assertions()) result = s.check() if result == sat: print(s.model()) else: print(result) ================================================ FILE: marktoberdorf_slides/examples/check_mult.py ================================================ from mult import * # now prove that adder is equal to bitvector add N = 16 xN = BoolVector("x",N) yN = BoolVector("y",N) x_bv = BitVec("x_bv",N) y_bv = BitVec("y_bv",N) # need to equate the inputs (Extract(lo,hi,bv) def eq_bool(bv, i, b): return (Extract(i,i,bv) == 1) == b def eq_bitvec_boolvec(bitvec,boolvec): return [ eq_bool(bitvec,i,boolvec[i]) for i in range(bitvec.size()) ] inputs_equal = eq_bitvec_boolvec(x_bv,xN) + eq_bitvec_boolvec(y_bv,yN) res,cout = multN(xN,yN) res_bv = x_bv * y_bv outputs_equal = eq_bitvec_boolvec(res_bv,res) s = Solver() s.add(And(inputs_equal)) s.add(Not(And(outputs_equal))) result = s.check() print(result) ================================================ FILE: marktoberdorf_slides/examples/first.py ================================================ from z3 import * x = BitVec("x",8) y = BitVec("y",8) z = BitVec("z",8) s = Solver() s.add(x > 0,y > 0,z==x+y) s.add(Not(z > 0)) result = s.check() if result == sat: print(s.model()) else: print(result) ================================================ FILE: marktoberdorf_slides/examples/hats.py ================================================ from z3 import * N = 7 # set up the bit vectors for the hats and what each person will guess hat = [ BitVec("Hat"+str(i),10) for i in range(N) ] guess = [ BitVec("Guess"+str(i),10) for i in range(N) ] # compute the sum of each person i's guess and the hats numbers for all j != i sum = [ sum([guess[i]]+[ hat[j] for j in range(N) if j!=i]) for i in range(N) ] # the program for each person i prog = [ (sum[i] % N) == i for i in range(N) ] s = Solver() def bounded(x): return And(0<=x,x 1 else None cvc_3 = args[2] if len(args) > 2 else None # arithmetical operations if op == "+": return cvc_l + cvc_r elif op == "-": return cvc_l - cvc_r elif op == "*": return cvc_l * cvc_r elif op == "//": return cvc_l / cvc_r elif op == "%": return cvc_l % cvc_r # bitwise elif op == "<<": return cvc_l << cvc_r elif op == ">>": return cvc_l >> cvc_r elif op == "^": return cvc_l ^ cvc_r elif op == "|": return cvc_l | cvc_l elif op == "&": return cvc_l & cvc_r # string elif op == "str.len": return cvc_l.len() elif op == "str.find": return cvc_l.find(cvc_r, cvc_3) elif op == "str.replace": return cvc_l.replace(cvc_r, cvc_3) elif op == "str.startswith": return self._wrapIf(cvc_l.startswith(cvc_r), env) # collection operators elif op == "getitem": return cvc_l[cvc_r] elif op == "slice": return cvc_l[cvc_r:cvc_3] # equality gets coerced to integer elif op == "==": if cvc_l is None or cvc_r is None: # forces false condition no model contains None return self._wrapIf(self._astToCVCExpr(0, env) != self._astToCVCExpr(0, env), env) else: return self._wrapIf((cvc_l == cvc_r), env) elif op == "!=": if cvc_l is None or cvc_r is None: return self._wrapIf(self._astToCVCExpr(0, env) == self._astToCVCExpr(0, env), env) else: return self._wrapIf((cvc_l != cvc_r), env) elif op == "<": return self._wrapIf((cvc_l < cvc_r), env) elif op == ">": return self._wrapIf((cvc_l > cvc_r), env) elif op == "<=": return self._wrapIf((cvc_l <= cvc_r), env) elif op == ">=": return self._wrapIf((cvc_l >= cvc_r), env) elif op == "in": return self._wrapIf((cvc_l.__contains__(cvc_r)), env) else: utils.crash("Unknown BinOp during conversion from ast to CVC (expressions): %s" % op) elif isinstance(expr, SymbolicObject): if expr.isVariable(): if env is None: variable = self._getVariable(expr) return variable else: return env[expr.name] else: return self._astToCVCExpr(expr.expr, env) elif isinstance(expr, int) | isinstance(expr, str): if env is None: if isinstance(expr, int): return CVCInteger.constant(expr, self.solver) elif isinstance(expr, str): return CVCString.constant(expr, self.solver) else: return expr elif expr is None: return None else: utils.crash("Unknown node during conversion from ast to CVC (expressions): %s" % expr) ================================================ FILE: symbolic/cvc_expr/expression.py ================================================ import logging import CVC4 log = logging.getLogger("se.cvc_expr.expr") class CVCExpression(object): CVC_TYPE = 'Bool' def __init__(self, cvc_expr, solver): self.cvc_expr = cvc_expr self.solver = solver self.em = self.solver.getExprManager() @classmethod def variable(cls, name, solver): raise NotImplementedError @classmethod def constant(cls, v, solver): raise NotImplementedError def getvalue(self): raise NotImplementedError def ite(self, th, el): assert th.cvc_expr.getType().toString() == el.cvc_expr.getType().toString() return th.__class__(self.em.mkExpr(CVC4.ITE, self.cvc_expr, th.cvc_expr, el.cvc_expr), self.solver) def __and__(self, other): return CVCExpression(self.em.mkExpr(CVC4.AND, self.cvc_expr, other.cvc_expr), self.solver) def __xor__(self, other): return CVCExpression(self.em.mkExpr(CVC4.XOR, self.cvc_expr, other.cvc_expr), self.solver) def __or__(self, other): return CVCExpression(self.em.mkExpr(CVC4.OR, self.cvc_expr, other.cvc_expr), self.solver) def not_op(self): return CVCExpression(self.em.mkExpr(CVC4.NOT, self.cvc_expr), self.solver) def __ne__(self, other): return CVCExpression(self.em.mkExpr(CVC4.NOT, self.em.mkExpr(CVC4.EQUAL, self.cvc_expr, other.cvc_expr)), self.solver) def __eq__(self, other): return CVCExpression(self.em.mkExpr(CVC4.EQUAL, self.cvc_expr, other.cvc_expr), self.solver) def __lt__(self, other): return CVCExpression(self.em.mkExpr(CVC4.LT, self.cvc_expr, other.cvc_expr), self.solver) def __gt__(self, other): return CVCExpression(self.em.mkExpr(CVC4.GT, self.cvc_expr, other.cvc_expr), self.solver) def __ge__(self, other): return CVCExpression(self.em.mkExpr(CVC4.GEQ, self.cvc_expr, other.cvc_expr), self.solver) def __le__(self, other): return CVCExpression(self.em.mkExpr(CVC4.LEQ, self.cvc_expr, other.cvc_expr), self.solver) def __str__(self): return self.cvc_expr.toString() ================================================ FILE: symbolic/cvc_expr/integer.py ================================================ import logging import CVC4 from CVC4 import Rational, Integer from .expression import CVCExpression log = logging.getLogger("se.cvc.integer") class CVCInteger(CVCExpression): """Python numbers are represented as integers in the CVC path expression. For bitwise operations, integers are transformed into bit vectors of size _bv_size and then converted back to a natural number using CVC's BITVECTOR_TO_NAT operator. In order to maintain sound reasoning of the behavior of generated inputs, all inputs to bit vector operations are asserted positive through _assert_bvsanity as well as the outputs through _assert_bvbounds. These assumptions restrict the symbolic execution from finding valid solutions to path formulas in order to avoid generating path expressions with solutions that do not match program behavior. For example, x = -1 is a valid solution to x != CVC4.BITVECTOR_TO_NAT(CVC4.INT_TO_BITVECTOR(x)) since the output of the right-hand side of the equation will be positive (natural numbers are >= 0). Possible improvements: 1) _bv_size is currently fixed at a low number. The Z3 integration starts with small bit vectors and gradually increases the size until a solution is found. Match that functionality in CVCInteger. 2) Create an alternative implementation of CVCInteger that uses bit vectors for all operations. In the presence of bitwise operations, the conversion between bit vectors and integers is expensive. 3) Encode in the formula a BITVECTOR_TO_INT conversion that performs two's complement arithmetic.""" CVC_TYPE = 'Int' _bv_size = 8 @classmethod def variable(cls, name, solver): em = solver.getExprManager() expr = em.mkVar(name, em.integerType()) return cls(expr, solver) @classmethod def constant(cls, v, solver): em = solver.getExprManager() return cls(em.mkConst(Rational(Integer(str(v)))), solver) def getvalue(self): """In order to mitigate the limited accuracy of the C-type values returned by the CVC getters, strings are parsed into Python numbers. This fix was added to pass the PyExZ3/test/bignum.py test case.""" ce = self.solver.getValue(self.cvc_expr) rational = ce.getConstRational() numerator = int(rational.getNumerator().toString()) denominator = int(rational.getDenominator().toString()) if rational.isIntegral(): return numerator // denominator else: return numerator / denominator def __add__(self, other): return CVCInteger(self.em.mkExpr(CVC4.PLUS, self.cvc_expr, other.cvc_expr), self.solver) def __sub__(self, other): return CVCInteger(self.em.mkExpr(CVC4.MINUS, self.cvc_expr, other.cvc_expr), self.solver) def __mul__(self, other): return CVCInteger(self.em.mkExpr(CVC4.MULT, self.cvc_expr, other.cvc_expr), self.solver) def __truediv__(self, other): return CVCInteger(self.em.mkExpr(CVC4.DIVISION, self.cvc_expr, other.cvc_expr), self.solver) def __mod__(self, other): return CVCInteger(self.em.mkExpr(CVC4.INTS_MODULUS, self.cvc_expr, other.cvc_expr), self.solver) def __or__(self, other): return self._bvhelper(other, CVC4.BITVECTOR_OR) def __and__(self, other): return self._bvhelper(other, CVC4.BITVECTOR_AND) def __xor__(self, other): return self._bvhelper(other, CVC4.BITVECTOR_XOR) def __lshift__(self, other): return self._bvhelper(other, CVC4.BITVECTOR_SHL) def __rshift__(self, other): return self._bvhelper(other, CVC4.BITVECTOR_ASHR) def tobv(self): bvconversion = self.em.mkConst(CVC4.IntToBitVector(self._bv_size)) return self.em.mkExpr(bvconversion, self.cvc_expr) def bvsanity(self): return self == CVCExpression(self.em.mkExpr(CVC4.BITVECTOR_TO_NAT, self.tobv()), self.solver) def _bvhelper(self, other, op): calculation = self.em.mkExpr(op, self.tobv(), other.tobv()) self.solver.guards.append(self.bvsanity() & other.bvsanity()) self._assert_bvbounds(calculation) return CVCInteger(self.em.mkExpr(CVC4.BITVECTOR_TO_NAT, calculation), self.solver) def _assert_bvbounds(self, bvexpr): bitextract = self.em.mkConst(CVC4.BitVectorExtract(0, 0)) self.solver.guards.append((CVCExpression( self.em.mkExpr(CVC4.EQUAL, self.em.mkExpr(bitextract, bvexpr), self.em.mkConst(CVC4.BitVector(1, 0))), self.solver))) ================================================ FILE: symbolic/cvc_expr/string.py ================================================ import logging import CVC4 from .expression import CVCExpression from .integer import CVCInteger log = logging.getLogger("se.cvc.string") class CVCString(CVCExpression): CVC_TYPE = 'String' @classmethod def variable(cls, name, solver): em = solver.getExprManager() expr = em.mkVar(name, em.stringType()) return cls(expr, solver) @classmethod def constant(cls, v, solver): em = solver.getExprManager() chararray = [CVC4.CVC4String_convertCharToUnsignedInt(c) for c in bytes(v, 'UTF-8')] cvcstr = CVC4.CVC4String(chararray) assert cvcstr.size() == len(v) return cls(em.mkConst(cvcstr), solver) def getvalue(self): ce = self.solver.getValue(self.cvc_expr) chararray = [CVC4.CVC4String_convertUnsignedIntToChar(c) for c in ce.getConstString().getVec()] v = bytes(chararray).decode() assert len(v) == ce.getConstString().size() return v def len(self): return CVCInteger(self.em.mkExpr(CVC4.STRING_LENGTH, self.cvc_expr), self.solver) def __add__(self, other): return CVCString(self.em.mkExpr(CVC4.STRING_CONCAT, self.cvc_expr, other.cvc_expr), self.solver) def __contains__(self, item): return CVCExpression(self.em.mkExpr(CVC4.STRING_STRCTN, self.cvc_expr, item.cvc_expr), self.solver) def __getitem__(self, item): if isinstance(item, slice): offset = item.stop - item.start self.solver.guards.append(item.start >= CVCInteger.constant(0, self.solver)) self.solver.guards.append(offset >= CVCInteger.constant(0, self.solver)) # Adding these forms of guards globally # can limit the number of solutions generated # but restructuring to avoid reducing the # solution space is a significant undertaking. self.solver.guards.append(self.len() > item.start) self.solver.guards.append(self.len() >= item.stop) return CVCString(self.em.mkExpr(CVC4.STRING_SUBSTR, self.cvc_expr, item.start.cvc_expr, offset.cvc_expr), self.solver) return CVCString(self.em.mkExpr(CVC4.STRING_CHARAT, self.cvc_expr, item.cvc_expr), self.solver) def find(self, findstr, beg): """CVC4's String IndexOf functionality is capable of specifying an index to begin the search. However, the current implementation searches from the beginning of the string.""" return CVCInteger( self.em.mkExpr(CVC4.STRING_STRIDOF, self.cvc_expr, findstr.cvc_expr, beg.cvc_expr), self.solver) def replace(self, old, new): return CVCString(self.em.mkExpr(CVC4.STRING_STRREPL, self.cvc_expr, old.cvc_expr, new.cvc_expr), self.solver) def startswith(self, prefix): return CVCExpression(self.em.mkExpr(CVC4.STRING_PREFIX, prefix.cvc_expr, self.cvc_expr), self.solver) ================================================ FILE: symbolic/cvc_wrap.py ================================================ import logging import utils import CVC4 from CVC4 import ExprManager, SmtEngine, SExpr from symbolic.cvc_expr.exprbuilder import ExprBuilder log = logging.getLogger("se.cvc") class CVCWrapper(object): options = {'produce-models': 'true', # Enable experimental string support 'strings-exp': 'true', # Enable modular arithmetic with constant modulus 'rewrite-divk': 'true', # Per Query timeout of 5 seconds 'tlimit-per': 5000, 'output-language': 'smt2', 'input-language': 'smt2'} logic = 'ALL_SUPPORTED' def __init__(self): self.asserts = None self.query = None self.em = None self.solver = None def findCounterexample(self, asserts, query): """Tries to find a counterexample to the query while asserts remains valid.""" self.em = ExprManager() self.solver = SmtEngine(self.em) for name, value in CVCWrapper.options.items(): self.solver.setOption(name, SExpr(str(value))) self.solver.setLogic(CVCWrapper.logic) self.query = query self.asserts = self._coneOfInfluence(asserts, query) result = self._findModel() log.debug("Query -- %s" % self.query) log.debug("Asserts -- %s" % asserts) log.debug("Cone -- %s" % self.asserts) log.debug("Result -- %s" % result) return result def _findModel(self): self.solver.push() exprbuilder = ExprBuilder(self.asserts, self.query, self.solver) self.solver.assertFormula(exprbuilder.query.cvc_expr) try: result = self.solver.checkSat() log.debug("Solver returned %s" % result.toString()) if not result.isSat(): ret = None elif result.isUnknown(): ret = None elif result.isSat(): ret = self._getModel(exprbuilder.cvc_vars) else: raise Exception("Unexpected SMT result") except RuntimeError as r: log.debug("CVC exception %s" % r) ret = None self.solver.pop() return ret @staticmethod def _getModel(variables): """Retrieve the model generated for the path expression.""" return {name: cvc_var.getvalue() for (name, cvc_var) in variables.items()} @staticmethod def _coneOfInfluence(asserts, query): cone = [] cone_vars = set(query.getVars()) ws = [a for a in asserts if len(set(a.getVars()) & cone_vars) > 0] remaining = [a for a in asserts if a not in ws] while len(ws) > 0: a = ws.pop() a_vars = set(a.getVars()) cone_vars = cone_vars.union(a_vars) cone.append(a) new_ws = [a for a in remaining if len(set(a.getVars()) & cone_vars) > 0] remaining = [a for a in remaining if a not in new_ws] ws = ws + new_ws return cone ================================================ FILE: symbolic/explore.py ================================================ # Copyright: see copyright.txt from collections import deque import logging import os from .z3_wrap import Z3Wrapper from .path_to_constraint import PathToConstraint from .invocation import FunctionInvocation from .symbolic_types import symbolic_type, SymbolicType log = logging.getLogger("se.conc") class ExplorationEngine: def __init__(self, funcinv, solver="z3"): self.invocation = funcinv # the input to the function self.symbolic_inputs = {} # string -> SymbolicType # initialize for n in funcinv.getNames(): self.symbolic_inputs[n] = funcinv.createArgumentValue(n) self.constraints_to_solve = deque([]) self.num_processed_constraints = 0 self.path = PathToConstraint(lambda c : self.addConstraint(c)) # link up SymbolicObject to PathToConstraint in order to intercept control-flow symbolic_type.SymbolicObject.SI = self.path if solver == "z3": self.solver = Z3Wrapper() elif solver == "cvc": from .cvc_wrap import CVCWrapper self.solver = CVCWrapper() else: raise Exception("Unknown solver %s" % solver) # outputs self.generated_inputs = [] self.execution_return_values = [] def addConstraint(self, constraint): self.constraints_to_solve.append(constraint) # make sure to remember the input that led to this constraint constraint.inputs = self._getInputs() def explore(self, max_iterations=0): self._oneExecution() iterations = 1 if max_iterations != 0 and iterations >= max_iterations: log.debug("Maximum number of iterations reached, terminating") return self.execution_return_values while not self._isExplorationComplete(): selected = self.constraints_to_solve.popleft() if selected.processed: continue self._setInputs(selected.inputs) log.info("Selected constraint %s" % selected) asserts, query = selected.getAssertsAndQuery() model = self.solver.findCounterexample(asserts, query) if model == None: continue else: for name in model.keys(): self._updateSymbolicParameter(name,model[name]) self._oneExecution(selected) iterations += 1 self.num_processed_constraints += 1 if max_iterations != 0 and iterations >= max_iterations: log.info("Maximum number of iterations reached, terminating") break return self.generated_inputs, self.execution_return_values, self.path # private def _updateSymbolicParameter(self, name, val): self.symbolic_inputs[name] = self.invocation.createArgumentValue(name,val) def _getInputs(self): return self.symbolic_inputs.copy() def _setInputs(self,d): self.symbolic_inputs = d def _isExplorationComplete(self): num_constr = len(self.constraints_to_solve) if num_constr == 0: log.info("Exploration complete") return True else: log.info("%d constraints yet to solve (total: %d, already solved: %d)" % (num_constr, self.num_processed_constraints + num_constr, self.num_processed_constraints)) return False def _getConcrValue(self,v): if isinstance(v,SymbolicType): return v.getConcrValue() else: return v def _recordInputs(self): args = self.symbolic_inputs inputs = [ (k,self._getConcrValue(args[k])) for k in args ] self.generated_inputs.append(inputs) print(inputs) def _oneExecution(self,expected_path=None): self._recordInputs() self.path.reset(expected_path) ret = self.invocation.callFunction(self.symbolic_inputs) print(ret) self.execution_return_values.append(ret) ================================================ FILE: symbolic/invocation.py ================================================ # Copyright: see copyright.txt class FunctionInvocation: def __init__(self, function, reset): self.function = function self.reset = reset self.arg_constructor = {} self.initial_value = {} def callFunction(self,args): self.reset() return self.function(**args) def addArgumentConstructor(self, name, init, constructor): self.initial_value[name] = init self.arg_constructor[name] = constructor def getNames(self): return self.arg_constructor.keys() def createArgumentValue(self,name,val=None): if val == None: val = self.initial_value[name] return self.arg_constructor[name](name,val) ================================================ FILE: symbolic/loader.py ================================================ # Copyright: copyright.txt import inspect import re import os import sys from .invocation import FunctionInvocation from .symbolic_types import SymbolicInteger, getSymbolic # The built-in definition of len wraps the return value in an int() constructor, destroying any symbolic types. # By redefining len here we can preserve symbolic integer types. import builtins builtins.len = (lambda x : x.__len__()) class Loader: def __init__(self, filename, entry): self._fileName = os.path.basename(filename) self._fileName = self._fileName[:-3] if (entry == ""): self._entryPoint = self._fileName else: self._entryPoint = entry; self._resetCallback(True) def getFile(self): return self._fileName def getEntry(self): return self._entryPoint def createInvocation(self): inv = FunctionInvocation(self._execute,self._resetCallback) func = self.app.__dict__[self._entryPoint] argspec = inspect.getargspec(func) # check to see if user specified initial values of arguments if "concrete_args" in func.__dict__: for (f,v) in func.concrete_args.items(): if not f in argspec.args: print("Error in @concrete: " + self._entryPoint + " has no argument named " + f) raise ImportError() else: Loader._initializeArgumentConcrete(inv,f,v) if "symbolic_args" in func.__dict__: for (f,v) in func.symbolic_args.items(): if not f in argspec.args: print("Error (@symbolic): " + self._entryPoint + " has no argument named " + f) raise ImportError() elif f in inv.getNames(): print("Argument " + f + " defined in both @concrete and @symbolic") raise ImportError() else: s = getSymbolic(v) if (s == None): print("Error at argument " + f + " of entry point " + self._entryPoint + " : no corresponding symbolic type found for type " + str(type(v))) raise ImportError() Loader._initializeArgumentSymbolic(inv, f, v, s) for a in argspec.args: if not a in inv.getNames(): Loader._initializeArgumentSymbolic(inv, a, 0, SymbolicInteger) return inv # need these here (rather than inline above) to correctly capture values in lambda def _initializeArgumentConcrete(inv,f,val): inv.addArgumentConstructor(f, val, lambda n,v: val) def _initializeArgumentSymbolic(inv,f,val,st): inv.addArgumentConstructor(f, val, lambda n,v: st(n,v)) def executionComplete(self, return_vals): if "expected_result" in self.app.__dict__: return self._check(return_vals, self.app.__dict__["expected_result"]()) if "expected_result_set" in self.app.__dict__: return self._check(return_vals, self.app.__dict__["expected_result_set"](),False) else: print(self._fileName + ".py contains no expected_result function") return None # -- private def _resetCallback(self,firstpass=False): self.app = None if firstpass and self._fileName in sys.modules: print("There already is a module loaded named " + self._fileName) raise ImportError() try: if (not firstpass and self._fileName in sys.modules): del(sys.modules[self._fileName]) self.app =__import__(self._fileName) if not self._entryPoint in self.app.__dict__ or not callable(self.app.__dict__[self._entryPoint]): print("File " + self._fileName + ".py doesn't contain a function named " + self._entryPoint) raise ImportError() except Exception as arg: print("Couldn't import " + self._fileName) print(arg) raise ImportError() def _execute(self, **args): return self.app.__dict__[self._entryPoint](**args) def _toBag(self,l): bag = {} for i in l: if i in bag: bag[i] += 1 else: bag[i] = 1 return bag def _check(self, computed, expected, as_bag=True): b_c = self._toBag(computed) b_e = self._toBag(expected) if as_bag and b_c != b_e or not as_bag and set(computed) != set(expected): print("-------------------> %s test failed <---------------------" % self._fileName) print("Expected: %s, found: %s" % (b_e, b_c)) return False else: print("%s test passed <---" % self._fileName) return True def loaderFactory(filename,entry): if not os.path.isfile(filename) or not re.search(".py$",filename): print("Please provide a Python file to load") return None try: dir = os.path.dirname(filename) sys.path = [ dir ] + sys.path ret = Loader(filename,entry) return ret except ImportError: sys.path = sys.path[1:] return None ================================================ FILE: symbolic/path_to_constraint.py ================================================ # Copyright: see copyright.txt import logging from .predicate import Predicate from .constraint import Constraint log = logging.getLogger("se.pathconstraint") class PathToConstraint: def __init__(self, add): self.constraints = {} self.add = add self.root_constraint = Constraint(None, None) self.current_constraint = self.root_constraint self.expected_path = None def reset(self,expected): self.current_constraint = self.root_constraint if expected==None: self.expected_path = None else: self.expected_path = [] tmp = expected while tmp.predicate is not None: self.expected_path.append(tmp.predicate) tmp = tmp.parent def whichBranch(self, branch, symbolic_type): """ This function acts as instrumentation. Branch can be either True or False.""" # add both possible predicate outcomes to constraint (tree) p = Predicate(symbolic_type, branch) p.negate() cneg = self.current_constraint.findChild(p) p.negate() c = self.current_constraint.findChild(p) if c is None: c = self.current_constraint.addChild(p) # we add the new constraint to the queue of the engine for later processing log.debug("New constraint: %s" % c) self.add(c) # check for path mismatch # IMPORTANT: note that we don't actually check the predicate is the # same one, just that the direction taken is the same if self.expected_path != None and self.expected_path != []: expected = self.expected_path.pop() # while not at the end of the path, we expect the same predicate result # at the end of the path, we expect a different predicate result done = self.expected_path == [] if ( not done and expected.result != c.predicate.result or \ done and expected.result == c.predicate.result ): print("Replay mismatch (done=",done,")") print(expected) print(c.predicate) if cneg is not None: # We've already processed both cneg.processed = True c.processed = True log.debug("Processed constraint: %s" % c) self.current_constraint = c def toDot(self): # print the thing into DOT format header = "digraph {\n" footer = "\n}\n" return header + self._toDot(self.root_constraint) + footer def _toDot(self,c): if (c.parent == None): label = "root" else: label = c.predicate.symtype.toString() if not c.predicate.result: label = "Not("+label+")" node = "C" + str(c.id) + " [ label=\"" + label + "\" ];\n" edges = [ "C" + str(c.id) + " -> " + "C" + str(child.id) + ";\n" for child in c.children ] return node + "".join(edges) + "".join([ self._toDot(child) for child in c.children ]) ================================================ FILE: symbolic/predicate.py ================================================ # Copyright - see copyright.txt class Predicate: """Predicate is one specific ``if'' encountered during the program execution. """ def __init__(self, st, result): self.symtype = st self.result = result def getVars(self): return self.symtype.getVars() def __eq__(self, other): if isinstance(other, Predicate): res = self.result == other.result and self.symtype.symbolicEq(other.symtype) return res else: return False def __hash__(self): return hash(self.symtype) def __str__(self): return self.symtype.toString() + " (%s)" % (self.result) def __repr__(self): return self.__str__() def negate(self): """Negates the current predicate""" assert(self.result is not None) self.result = not self.result ================================================ FILE: symbolic/symbolic_types/__init__.py ================================================ # Copyright: see copyright.txt from .symbolic_int import SymbolicInteger as SymInt from .symbolic_int import SymbolicObject as SymObj from .symbolic_dict import SymbolicDict as SymD from .symbolic_str import SymbolicStr as SymS from .symbolic_type import SymbolicType as SymType SymObj.wrap = lambda conc, sym : SymbolicInteger("se",conc,sym) SymbolicInteger = SymInt SymbolicDict = SymD SymbolicStr = SymS SymbolicType = SymType def getSymbolic(v): exported = [(int,SymbolicInteger),(dict,SymbolicDict),(str,SymbolicStr)] for (t,s) in exported: if isinstance(v,t): return s return None ================================================ FILE: symbolic/symbolic_types/symbolic_dict.py ================================================ import ast import sys from . symbolic_type import SymbolicObject # SymbolicDict: the key and values will both be SymbolicType for full generality # keys of dictionary must be immutable # values in dictionary may be mutable # TODO: big simplification: can only initialize with # an empty dictionary class SymbolicDict(SymbolicObject,dict): def __new__(cls, name, *args, **kwargs): self = dict.__new__(cls,args,kwargs) return self def __init__(self, name, kwargs): SymbolicObject.__init__(self,name,None) dict.__init__(self,kwargs) def getConcrValue(self): return self def __bool__(self): return bool(len(self)) # def wrap(conc,sym): # pass # TODO # def __getitem__(self,key): # val = super.__getitem__(key) # if isinstance(val,SymbolicType): # wrap = val.wrap # else: # wrap = lambda c,s : c # return self._do_bin_op(key, lambda d, k: val, ast.Index, wrap) # def __setitem__(self,key,value): # # update the expression (this is a triple - not binary) # concrete, symbolic =\ # self._do_sexpr([self,key,value], lambda d, k, v : d.super.__setitem__(k,v), ast.Store,\ # lambda c, s: c, s) # # note that we do an in place update of # self.expr = symbolic # def __contains__(self,key): # for k in self.keys(): # if k == key: # return True # return False # def __delitem__(self,key) # if dict.__contains(self,key): # pass # # self.expr = Delete(self.expr,key) # dict.__delitem__(self,key) ================================================ FILE: symbolic/symbolic_types/symbolic_int.py ================================================ # Copyright: copyright.txt from . symbolic_type import SymbolicObject # we use multiple inheritance to achieve concrete execution for any # operation for which we don't have a symbolic representation. As # we can see a SymbolicInteger is both symbolic (SymbolicObject) and # concrete (int) class SymbolicInteger(SymbolicObject,int): # since we are inheriting from int, we need to use new # to perform construction correctly def __new__(cls, name, v, expr=None): return int.__new__(cls, v) def __init__(self, name, v, expr=None): SymbolicObject.__init__(self, name, expr) self.val = v def getConcrValue(self): return self.val def wrap(conc,sym): return SymbolicInteger("se",conc,sym) def __hash__(self): return hash(self.val) def _op_worker(self,args,fun,op): return self._do_sexpr(args, fun, op, SymbolicInteger.wrap) # now update the SymbolicInteger class for operations we # will build symbolic terms for ops = [("add", "+" ),\ ("sub", "-" ),\ ("mul", "*" ),\ ("mod", "%" ),\ ("floordiv", "//" ),\ ("and", "&" ),\ ("or", "|" ),\ ("xor", "^" ),\ ("lshift", "<<" ),\ ("rshift", ">>" ) ] def make_method(method,op,a): code = "def %s(self,other):\n" % method code += " return self._op_worker(%s,lambda x,y : x %s y, \"%s\")" % (a,op,op) locals_dict = {} exec(code, globals(), locals_dict) setattr(SymbolicInteger,method,locals_dict[method]) for (name,op) in ops: method = "__%s__" % name make_method(method,op,"[self,other]") rmethod = "__r%s__" % name make_method(rmethod,op,"[other,self]") ================================================ FILE: symbolic/symbolic_types/symbolic_str.py ================================================ from . symbolic_type import SymbolicObject from symbolic.symbolic_types.symbolic_int import SymbolicInteger from string import whitespace class SymbolicStr(SymbolicObject, str): def __new__(cls, name, v, expr=None): return str.__new__(cls, v) def __init__(self, name, v, expr=None): SymbolicObject.__init__(self, name, expr) self.val = v def getConcrValue(self): return self.val def wrap(conc, sym): return SymbolicStr("se", conc, sym) def __hash__(self): return hash(self.val) def _op_worker(self, args, fun, op): return self._do_sexpr(args, fun, op, SymbolicStr.wrap) def __bool__(self): return SymbolicObject.__bool__(self.__len__() != 0) def __len__(self): return self._do_sexpr([self], lambda x: len(x), "str.len", SymbolicInteger.wrap) def __contains__(self, item): return self._do_sexpr([self, item], lambda x, y: str.__contains__(x, y), "in", SymbolicInteger.wrap) def __getitem__(self, key): """Negative indexes, out of bound slices, and slice skips are not currently supported.""" if isinstance(key, slice): start = key.start if key.start is not None else 0 stop = key.stop if key.stop is not None else self.__len__() return self._do_sexpr([self, start, stop], lambda x, y, z: str.__getitem__(x, slice(y, z)), "slice", SymbolicStr.wrap) return self._do_sexpr([self, key], lambda x, y: str.__getitem__(x, y), "getitem", SymbolicStr.wrap) def find(self, findstr, beg=0): return self._do_sexpr([self, findstr, beg], lambda x, y, z: str.find(x, y, z), "str.find", SymbolicInteger.wrap) def startswith(self, prefix): return self._do_sexpr([self, prefix], lambda x, y: str.startswith(x, y), "str.startswith", SymbolicInteger.wrap) def split(self, sep=None, maxsplit=None): if sep is None: sep = " " if len(self) == 0: return [] elif maxsplit == 0 or sep not in self: return [self] else: sep_idx = self.find(sep) maxsplit = None if maxsplit is None else maxsplit - 1 return [self[0:sep_idx]] + \ self[sep_idx + 1:].split(sep, maxsplit) def count(self, sub): """String count is not a native function of the SMT solver. Instead, we implement count as a recursive series of find operations. Note that not all of the functionality of count is supported at this time, such as the start index.""" if sub not in self: ret = 0 elif sub == "": ret = self.__len__() + 1 else: find_idx = self.find(sub) reststr = self[find_idx + sub.__len__():] ret = reststr.count(sub) + 1 assert int(ret) == str.count(str(self), str(sub)) return ret def _replace(self, old, new): return self._do_sexpr([self, old, new], lambda x, y, z: str.replace(x, y, z), "str.replace", SymbolicStr.wrap) def replace(self, old, new, maxreplace=-1): """CVC only replaces the first occurrence of old with new (maxreplace=1). For this reason, SymbolicStr's replace is implemented as a recurrence of single replaces.""" if maxreplace == 0 or old not in self: ret = self else: pivot_point = self.find(old) + old.__len__() first_half = self[:pivot_point] first_half = first_half._replace(old, new) second_half = self[pivot_point:] ret = first_half + second_half.replace(old, new, maxreplace-1) assert str(ret) == str.replace(str(self), str(old), str(new), int(maxreplace)) return ret def strip(self, chars=None): if chars is None: chars = whitespace if self.__len__() == 0: return self for char in chars: if self[0] == char: return self[1:].strip(chars) for char in chars: if self[self.__len__() - 1] == char: return self[:self.__len__() - 1].strip(chars) return self # Currently only a subset of string operations are supported. ops = [("add", "+")] def make_method(method,op,a): code = "def %s(self,other):\n" % method code += " return self._op_worker(%s,lambda x,y : x %s y, \"%s\")" % (a,op,op) locals_dict = {} exec(code, globals(), locals_dict) setattr(SymbolicStr, method, locals_dict[method]) for (name,op) in ops: method = "__%s__" % name make_method(method,op,"[self,other]") rmethod = "__r%s__" % name make_method(rmethod,op,"[other,self]") ================================================ FILE: symbolic/symbolic_types/symbolic_type.py ================================================ # Copyright: see copyright.txt import utils import inspect import functools # the ABSTRACT base class for representing any expression that depends on a symbolic input # it also tracks the corresponding concrete value for the expression (aka concolic execution) class SymbolicType(object): def __init__(self, name, expr=None): self.name = name self.expr = expr # to be provided by subclass def getConcrValue(self): raise NotImplemented() def wrap(conc,sym): raise NotImplemented() # public funs def isVariable(self): return self.expr == None def unwrap(self): if self.isVariable(): return (self.getConcrValue(),self) else: return (self.getConcrValue(),self.expr) def getVars(self): if self.isVariable(): return [self.name] elif isinstance(self.expr,list): return self._getVarsLeaves(self.expr) else: return [] def _getVarsLeaves(self,l): if isinstance(l,list): return functools.reduce(lambda a, x: self._getVarsLeaves(x) + a,l,[]) elif isinstance(l,SymbolicType): return [l.name] else: return [] # creating the expression tree def _do_sexpr(self,args,fun,op,wrap): unwrapped = [ (a.unwrap() if isinstance(a,SymbolicType) else (a,a)) for a in args ] args = zip(inspect.getargspec(fun).args, [ c for (c,s) in unwrapped ]) concrete = fun(**dict([a for a in args])) symbolic = [ op ] + [ s for c,s in unwrapped ] return wrap(concrete,symbolic) def symbolicEq(self, other): if not isinstance(other,SymbolicType): return False if self.isVariable() or other.isVariable(): return self.name == other.name return self._eq_worker(self.expr,other.expr) def _eq_worker(self, expr1, expr2): if type(expr1) != type(expr2): return False if isinstance(expr1, list): return len(expr1) == len(expr2) and\ type(expr1[0]) == type(expr2[0]) and\ all([ self._eq_worker(x,y) for x,y in zip(expr1[1:],expr2[1:]) ]) elif isinstance(expr1, SymbolicType): return expr1.name == expr2.name else: return expr1 == expr2 def toString(self): if self.isVariable(): return self.name + "#" + str(self.getConcrValue()) else: return self._toString(self.expr) def _toString(self,expr): if isinstance(expr,list): return "(" + expr[0] + " " + ", ".join([ self._toString(a) for a in expr[1:] ]) + ")" elif isinstance(expr,SymbolicType): return expr.toString() else: return str(expr) # this class is also ABSTRACT although __init__.py does # initialize wrap to return SymbolicInteger for the # relational comparison operators class SymbolicObject(SymbolicType,object): def __init__(self, name, expr=None): SymbolicType.__init__(self,name,expr) SI = None # this is set up by ConcolicEngine to link __bool__ to PathConstraint def wrap(conc,sym): # see __init__.py raise NotImplemented() # this is a critical interception point: the __bool__ # method is called whenever a predicate is evaluated in # Python execution (if, while, and, or). This allows us # to capture the path condition def __bool__(self): ret = bool(self.getConcrValue()) if SymbolicObject.SI != None: SymbolicObject.SI.whichBranch(ret,self) return ret # compute both the symbolic and concrete image of operator def _do_bin_op(self, other, fun, op, wrap): return self._do_sexpr([self,other], fun, op, wrap) def __eq__(self, other): # TODO: what it self is not symbolic and other is??? return self._do_bin_op(other, lambda x, y: x == y, "==", SymbolicObject.wrap) def __ne__(self, other): return self._do_bin_op(other, lambda x, y: x != y, "!=", SymbolicObject.wrap) def __lt__(self, other): return self._do_bin_op(other, lambda x, y: x < y, "<", SymbolicObject.wrap) def __le__(self, other): return self._do_bin_op(other, lambda x, y: x <= y, "<=", SymbolicObject.wrap) def __gt__(self, other): return self._do_bin_op(other, lambda x, y: x > y, ">", SymbolicObject.wrap) def __ge__(self, other): return self._do_bin_op(other, lambda x, y: x >= y, ">=", SymbolicObject.wrap) ================================================ FILE: symbolic/z3_expr/__init__.py ================================================ ================================================ FILE: symbolic/z3_expr/bitvector.py ================================================ from z3 import * from .expression import Z3Expression class Z3BitVector(Z3Expression): def __init__(self,N): Z3Expression.__init__(self) self.N = N def _isIntVar(self,v): return isinstance(v,BitVecRef) def _variable(self,name,solver): return BitVec(name,self.N,solver.ctx) def _constant(self,v,solver): return BitVecVal(v,self.N,solver.ctx) ================================================ FILE: symbolic/z3_expr/expression.py ================================================ import utils from symbolic.symbolic_types.symbolic_int import SymbolicInteger from symbolic.symbolic_types.symbolic_type import SymbolicType from z3 import * class Z3Expression(object): def __init__(self): self.z3_vars = {} def toZ3(self,solver,asserts,query): self.z3_vars = {} solver.assert_exprs([self.predToZ3(p,solver) for p in asserts]) solver.assert_exprs(Not(self.predToZ3(query,solver))) def predToZ3(self,pred,solver,env=None): sym_expr = self._astToZ3Expr(pred.symtype,solver,env) if env == None: if not is_bool(sym_expr): sym_expr = sym_expr != self._constant(0,solver) if not pred.result: sym_expr = Not(sym_expr) else: if not pred.result: sym_expr = not sym_expr return sym_expr def getIntVars(self): return [ v[1] for v in self.z3_vars.items() if self._isIntVar(v[1]) ] # ----------- private --------------- def _isIntVar(self, v): raise NotImplementedException def _getIntegerVariable(self,name,solver): if name not in self.z3_vars: self.z3_vars[name] = self._variable(name,solver) return self.z3_vars[name] def _variable(self,name,solver): raise NotImplementedException def _constant(self,v,solver): raise NotImplementedException def _wrapIf(self,e,solver,env): if env == None: return If(e,self._constant(1,solver),self._constant(0,solver)) else: return e # add concrete evaluation to this, to check def _astToZ3Expr(self,expr,solver,env=None): if isinstance(expr, list): op = expr[0] args = [ self._astToZ3Expr(a,solver,env) for a in expr[1:] ] z3_l,z3_r = args[0],args[1] # arithmetical operations if op == "+": return self._add(z3_l, z3_r, solver) elif op == "-": return self._sub(z3_l, z3_r, solver) elif op == "*": return self._mul(z3_l, z3_r, solver) elif op == "//": return self._div(z3_l, z3_r, solver) elif op == "%": return self._mod(z3_l, z3_r, solver) # bitwise elif op == "<<": return self._lsh(z3_l, z3_r, solver) elif op == ">>": return self._rsh(z3_l, z3_r, solver) elif op == "^": return self._xor(z3_l, z3_r, solver) elif op == "|": return self._or(z3_l, z3_r, solver) elif op == "&": return self._and(z3_l, z3_r, solver) # equality gets coerced to integer elif op == "==": return self._wrapIf(z3_l == z3_r,solver,env) elif op == "!=": return self._wrapIf(z3_l != z3_r,solver,env) elif op == "<": return self._wrapIf(z3_l < z3_r,solver,env) elif op == ">": return self._wrapIf(z3_l > z3_r,solver,env) elif op == "<=": return self._wrapIf(z3_l <= z3_r,solver,env) elif op == ">=": return self._wrapIf(z3_l >= z3_r,solver,env) else: utils.crash("Unknown BinOp during conversion from ast to Z3 (expressions): %s" % op) elif isinstance(expr, SymbolicInteger): if expr.isVariable(): if env == None: return self._getIntegerVariable(expr.name,solver) else: return env[expr.name] else: return self._astToZ3Expr(expr.expr,solver,env) elif isinstance(expr, SymbolicType): utils.crash("{} is an unsupported SymbolicType of {}". format(expr, type(expr))) elif isinstance(expr, int): if env == None: return self._constant(expr,solver) else: return expr else: utils.crash("Unknown node during conversion from ast to Z3 (expressions): %s" % expr) def _add(self, l, r, solver): return l + r def _sub(self, l, r, solver): return l - r def _mul(self, l, r, solver): return l * r def _div(self, l, r, solver): return l / r def _mod(self, l, r, solver): return l % r def _lsh(self, l, r, solver): return l << r def _rsh(self, l, r, solver): return l >> r def _xor(self, l, r, solver): return l ^ r def _or(self, l, r, solver): return l | r def _and(self, l, r, solver): return l & r ================================================ FILE: symbolic/z3_expr/integer.py ================================================ from z3 import * from .expression import Z3Expression class Z3Integer(Z3Expression): def _isIntVar(self,v): return isinstance(v,IntRef) def _variable(self,name,solver): return Int(name,solver.ctx) def _constant(self,v,solver): return IntVal(v,solver.ctx) def _mod(self, l, r, solver): mod_fun = Function('int_mod', IntSort(), IntSort(), IntSort()) return mod_fun(l, r) def _lsh(self, l, r, solver): lsh_fun = Function('int_lsh', IntSort(), IntSort(), IntSort()) return lsh_fun(l, r) def _rsh(self, l, r, solver): rsh_fun = Function('int_rsh', IntSort(), IntSort(), IntSort()) return rsh_fun(l, r) def _xor(self, l, r, solver): xor_fun = Function('int_xor', IntSort(), IntSort(), IntSort()) return xor_fun(l, r) def _or(self, l, r, solver): or_fun = Function('int_or', IntSort(), IntSort(), IntSort()) return or_fun(l, r) def _and(self, l, r, solver): and_fun = Function('int_and', IntSort(), IntSort(), IntSort()) return and_fun(l, r) ================================================ FILE: symbolic/z3_wrap.py ================================================ # Copyright: see copyright.txt import sys import ast import logging from z3 import * from .z3_expr.integer import Z3Integer from .z3_expr.bitvector import Z3BitVector log = logging.getLogger("se.z3") class Z3Wrapper(object): def __init__(self): self.N = 32 self.asserts = None self.query = None self.use_lia = True self.z3_expr = None def findCounterexample(self, asserts, query): """Tries to find a counterexample to the query while asserts remains valid.""" self.solver = Solver() self.query = query self.asserts = self._coneOfInfluence(asserts,query) res = self._findModel() log.debug("Query -- %s" % self.query) log.debug("Asserts -- %s" % asserts) log.debug("Cone -- %s" % self.asserts) log.debug("Result -- %s" % res) return res # private # this is very inefficient def _coneOfInfluence(self,asserts,query): cone = [] cone_vars = set(query.getVars()) ws = [ a for a in asserts if len(set(a.getVars()) & cone_vars) > 0 ] remaining = [ a for a in asserts if a not in ws ] while len(ws) > 0: a = ws.pop() a_vars = set(a.getVars()) cone_vars = cone_vars.union(a_vars) cone.append(a) new_ws = [ a for a in remaining if len(set(a.getVars()) & cone_vars) > 0 ] remaining = [ a for a in remaining if a not in new_ws ] ws = ws + new_ws return cone def _findModel(self): # Try QF_LIA first (as it may fairly easily recognize unsat instances) if self.use_lia: self.solver.push() self.z3_expr = Z3Integer() self.z3_expr.toZ3(self.solver,self.asserts,self.query) res = self.solver.check() #print(self.solver.assertions) self.solver.pop() if res == unsat: return None # now, go for SAT with bounds self.N = 32 self.bound = (1 << 4) - 1 while self.N <= 64: self.solver.push() (ret,mismatch) = self._findModel2() if (not mismatch): break self.solver.pop() self.N = self.N+8 if self.N <= 64: print("expanded bit width to "+str(self.N)) #print("Assertions") #print(self.solver.assertions()) if ret == unsat: res = None elif ret == unknown: res = None elif not mismatch: res = self._getModel() else: res = None if self.N<=64: self.solver.pop() return res def _setAssertsQuery(self): self.z3_expr = Z3BitVector(self.N) self.z3_expr.toZ3(self.solver,self.asserts,self.query) def _findModel2(self): self._setAssertsQuery() int_vars = self.z3_expr.getIntVars() res = unsat while res == unsat and self.bound <= (1 << (self.N-1))-1: self.solver.push() constraints = self._boundIntegers(int_vars,self.bound) self.solver.assert_exprs(constraints) res = self.solver.check() if res == unsat: self.bound = (self.bound << 1)+1 self.solver.pop() if res == sat: # Does concolic agree with Z3? If not, it may be due to overflow model = self._getModel() #print("Match?") #print(self.solver.assertions) self.solver.pop() mismatch = False for a in self.asserts: eval = self.z3_expr.predToZ3(a,self.solver,model) if (not eval): mismatch = True break if (not mismatch): mismatch = not (not self.z3_expr.predToZ3(self.query,self.solver,model)) #print(mismatch) return (res,mismatch) elif res == unknown: self.solver.pop() return (res,False) def _getModel(self): res = {} model = self.solver.model() for name in self.z3_expr.z3_vars.keys(): try: ce = model.eval(self.z3_expr.z3_vars[name]) res[name] = ce.as_signed_long() except: pass return res def _boundIntegers(self,vars,val): bval = BitVecVal(val,self.N,self.solver.ctx) bval_neg = BitVecVal(-val-1,self.N,self.solver.ctx) return And([ v <= bval for v in vars]+[ bval_neg <= v for v in vars]) ================================================ FILE: test/abs_test.py ================================================ def abs_test(a,b): if (a < 0): if (abs(a) == b): return 0 return 1 return 2 def expected_result(): return [0,1,2] ================================================ FILE: test/andor.py ================================================ def andor(x,y): if(x or y): return 1 else: return 2 def expected_result(): return [1,1,2] ================================================ FILE: test/arrayindex2.py ================================================ A = [0, 1, 0, 0, 1, 0, 1] def arrayindex2(i): if i in [ j for j in range(len(A)) if A[j] ]: return i else: return "OTHER" def expected_result(): return [ 1,4,6, "OTHER" ] ================================================ FILE: test/bad_eq.py ================================================ def bad_eq(i): if (0 == i): return 0 return 1 def expected_result(): return [0,1] ================================================ FILE: test/bignum.py ================================================ import sys def bignum(a): if a == sys.maxsize: return "bv" if a == sys.maxsize+1: return "bignum" return "other" def expected_result(): return [ "other", "bv", "bignum" ] ================================================ FILE: test/binary_search.py ================================================ from lib.bsearch import * array = [ 0, 4, 6, 95, 430, 4944, 119101 ] def binary_search(k): i = bsearch(array,k) if(i>=0): if (not array[i]==k): return "ERROR" else: return str(k) else: if (k in array): return "ERROR" else: return "NOT_FOUND" def expected_result(): return [str(i) for i in array] + [ "NOT_FOUND" for i in range(len(array)+1) ] ================================================ FILE: test/bitwidth.py ================================================ def bitwidth(a): if (a + 1 < a): return 0 else: return 1 def expected_result(): return [1] ================================================ FILE: test/complex.py ================================================ def complex(x,y): if (y >= 1<<32): h = hash(y) print("hash(",y,") =",h) if (x == h): if (y == (1<<32) + 203): return 0 else: return 1 else: return 2 def expected_result_set(): return [0,1,2,None] ================================================ FILE: test/cseppento1.py ================================================ def cseppento1(x,y): # based on B2a_IfElse by Lajos Cseppento # see: L. Cseppento: Comparison of Symbolic Execution Based Test Generation Tools, B.Sc. Thesis, Budapest University of Technology and Economics, 2013. if (x > 0 and y > 0): return 1 elif (x < 0 and y > 0): return 2 elif (x < 0 and y < 0): return 3 elif (x > 0 and y < 0): return 4 elif (x > 0 and y < 0): # impossible branch , because the previous is the same return -1 elif (x == 0 or y == 0): return 0 else: # impossible branch return -2 def expected_result(): return [0,0,0,1,2,3,4] # should it be [0,1,2,3,4] instead? ================================================ FILE: test/cseppento2.py ================================================ def cseppento2(a,b): # based on B2c_NonLinear by Lajos Cseppento # see: L. Cseppento: Comparison of Symbolic Execution Based Test Generation Tools, B.Sc. Thesis, Budapest University of Technology and Economics, 2013. if (2 * a * a - 5 * a + 3 == 0 and 2 * b * b - 5 * b + 3 == 0 and a != b): return 1 else: return 2 def expected_result(): return [2,2,2] # should it be [2] ? ================================================ FILE: test/cseppento3.py ================================================ def cseppento3(x): # based on B3c_DoWhile by Lajos Cseppento # see: L. Cseppento: Comparison of Symbolic Execution Based Test Generation Tools, B.Sc. Thesis, Budapest University of Technology and Economics, 2013. # Sum of the positive integers <= min (x, 100) # 1+2+4+5+7+8+...[+98+100] i = 1 sum = 0 while (i<=x): i = i + 1 if (i % 3 == 0): continue if (i > 100): break sum = sum + i return sum #def expected_result(): # return [] ================================================ FILE: test/cvc/effectivebool.py ================================================ """Tests strings and integers used as a branch condition. The interpreter calls the bool constructor with the contents of the branch condition passed in as the argument. If a __bool__ function does not exist, __len__ is called and compared to zero.""" from symbolic.args import symbolic @symbolic(string="foo", num=1) def effectivebool(string, num): if string: return 0 elif num: return 1 else: return 2 def expected_result(): return [0, 1, 2] ================================================ FILE: test/cvc/emptystr.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def emptystr(s): if s != '': return 0 else: return 1 def expected_result(): return [0, 1] ================================================ FILE: test/cvc/escape.py ================================================ from symbolic.args import symbolic @symbolic(string="foo") def escape(string): if string and '\\' not in string and string.find(':') > 0: return 0 else: return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/none.py ================================================ from symbolic.args import * @symbolic(c=3) def none(c): if c == None: return 1 elif c != None: return 0 def expected_result_set(): return {0} ================================================ FILE: test/cvc/strcontains.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strcontains(s): if "bar" in s: return 0 else: return 1 def expected_result(): return [0, 1] ================================================ FILE: test/cvc/strcount.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strcount(s): if s.count("x") == 2: return 1 elif s.count("xy") == 1: return 2 elif s.count("") == 3: return 3 else: return 0 def expected_result_set(): return {0, 1, 2, 3} ================================================ FILE: test/cvc/strfind.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strfind(s): find_idx = s.find("bar") if find_idx == 3: return 0 elif find_idx == -1: return 1 else: return 2 def expected_result(): return [0, 1, 2] ================================================ FILE: test/cvc/strfindbeg.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strfindbeg(s): find_idx = s.find("bar", 1) if find_idx == 3: return 0 elif find_idx == -1: return 1 else: return 2 def expected_result(): return [0, 1, 2] ================================================ FILE: test/cvc/strindex.py ================================================ from symbolic.args import symbolic @symbolic(s="foobar") def strindex(s): """Test case does not currently test negative indexes. It is also currently unclear how we want to handle concrete executions that raise errors. Currently the error stops execution and prevents a branch predicate from forming.""" if s[4] == 'Q': return 0 else: return 1 def expected_result(): return [0, 1] ================================================ FILE: test/cvc/stringadd.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def stringadd(s): x = s + "bar" if x == "nobar": return 0 return 1 def expected_result(): return [0, 1] ================================================ FILE: test/cvc/stringtest.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def stringtest(s): if (s == "bar"): return 0 elif (s == '\\'): return 2 else: return 1 def expected_result_set(): return {0, 1, 2} ================================================ FILE: test/cvc/strmiddle.py ================================================ from symbolic.args import symbolic @symbolic(s="x") def strmiddle(s): x = "A"+s+"C" if "B" in x: return 0 else: return 1 def expected_result(): return [0, 1] ================================================ FILE: test/cvc/strreplace.py ================================================ from symbolic.args import symbolic @symbolic(s="bar") def strreplace(s): if "faa" == s.replace("o", "a"): return 0 else: return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/strslice.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strslice(s): if '\\' not in s and s[0:2] == "//": return 0 return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/strsplit.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strsplit(s): if ['a', 'b'] == s.split("&"): return 0 return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/strstartswith.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strstartswith(s): if s.startswith('abc'): return 0 return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/strstrip.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strstrip(s): if " " in s and "abc" == s.strip(): return 0 return 1 def expected_result_set(): return {0, 1} ================================================ FILE: test/cvc/strsubstring.py ================================================ from symbolic.args import symbolic @symbolic(s="foo") def strsubstring(s): """Test case for Python slicing, negative indices and steps are not currently tested.""" if s[2:] == "obar": return 0 elif s[:2] == "bb": return 1 elif s[1:3] == "bb": return 2 else: return 3 def expected_result(): return [0, 1, 2, 3] ================================================ FILE: test/decorator.py ================================================ from symbolic.args import * @concrete(a=1,b=2) @symbolic(c=3) def decorator(a,b,c): if a+b+c == 6: return 0 else: return 1 def expected_result(): return [0,1] ================================================ FILE: test/decorator_dict.py ================================================ from symbolic.args import * @symbolic(d=dict([(42,6)])) def decorator_dict(d): if d[42] == 6: return 0 else: return 1 def expected_result(): return [0] ================================================ FILE: test/diamond.py ================================================ def diamond(x,y,z): ret = 0 if (x): ret = ret + 1 if (y): ret = ret + 1 if (z): ret = ret + 1 return ret def expected_result(): return [ 0, 1, 1, 1, 2, 2, 2, 3] ================================================ FILE: test/dict.py ================================================ D = dict({ (101,2), (1,3), (4,9) }) def dict(x): # if x in D.keys(): if x in [ j for j in D.keys() ]: return D[x] else: return "NONE" def expected_result(): return [2,3,9,"NONE"] ================================================ FILE: test/dictionary.py ================================================ # Copyright: see copyright.txt # Test if engine explores all paths from lib.se_dict import SymbolicDictionary def dictionary(in1): d = SymbolicDictionary({}) d[3] = 10 if d.has_key(in1): return 1 else: return 2 def expected_result(): return [1,2] ================================================ FILE: test/elseif.py ================================================ # Copyright: see copyright.txt # Test if engine explores all paths def elseif(in1): if in1 == 0: return 0 elif in1 == 1: return 1 elif in1 == 2: return 2 elif in1 == 3: return 3 elif in1 == 4: return 4 elif in1 == 5: return 5 elif in1 == 6: return 6 elif in1 == 7: return 7 elif in1 == 8: return 8 else: return 9 return 10 def expected_result(): return [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ================================================ FILE: test/expand.py ================================================ def expand(in1, in2): if (in1 + in2 >= 1 << 32): return 0 else: return 1 def expected_result(): return [0,1] ================================================ FILE: test/expressions.py ================================================ # Copyright: see copyright.txt def expressions(in1, in2): a = in1 b = in2 + 47 c = a * b # only solution should be a==1, b==6 (assuming Python actually uses 32-bit integers) if c==53: # a > 0 and a < 20 and b < 100 and c == 53: d = -1 else: d = 0 return d def expected_result(): return [-1,0] ================================================ FILE: test/filesys.py ================================================ import os import sys def filesys(x): # if file doesn't exist, create it and g = 1 if (os.path.exists("tmp.txt")): file = open("tmp.txt","r") g = int(file.readline()) g = g + 3 file.close() file = open("tmp.txt","w") file.write(str(g)) file.close() if (x == g): return 0 elif (x == g+1): return 1 else: return 2 def expected_result_set(): return [2] ================================================ FILE: test/fp.py ================================================ def fp(a): if a % 2 == 0: # The next condition basically checks whether a is zero (in a weird way, though). if a == int(a / 2): return 0 else: return 1 else: return 2 def expected_result(): return [0, 1, 2] ================================================ FILE: test/gcd.py ================================================ def rec_gcd(u,v): if (u == v): return u if (u == 0): return v if (v == 0): return u if not (u & 1): # u is even if v & 1: #v is odd return rec_gcd(u >> 1, v) else: # both u and v are even return rec_gcd(u >> 1, v >> 1) << 1 else: if not (v & 1): # u is odd, v is even return rec_gcd(u, v >> 1) # reduce larger argument if (u > v): return rec_gcd((u - v) >> 1, v) return rec_gcd((v - u) >> 1, u) def iter_gcd(u,v): # GCD(0,v) == v; GCD(u,0) == u, GCD(0,0) == 0 if (u == 0): return v if (v == 0): return u # Let shift := lg K, where K is the greatest power of 2 # dividing both u and v. shift = 0 while ((u | v) & 1) == 0: u = u >> 1 v = v >> 1 shift = shift + 1 while ((u & 1) == 0): u = u >> 1 # From here on, u is always odd. while (True): # remove all factors of 2 in v -- they are not common # note: v is not zero, so while will terminate while ((v & 1) == 0): v = v >> 1 # Now u and v are both odd. Swap if necessary so u <= v, # then set v = v - u (which is even). For bignums, the # swapping is just pointer movement, and the subtraction # can be done in-place. if (u > v): u, v = v, u v = v - u # Here v >= u. if (v == 0): break # restore common factors of 2 return u << shift def gcd(x,y): if (x>=0 and y>=0): rec_result = rec_gcd(x,y) iter_result = iter_gcd(x,y) if (rec_result != iter_result): return "ERROR" else: return "OK" else: return "PRE" def expected_result_set(): return ["PRE","OK"] ================================================ FILE: test/hashval.py ================================================ # Created by Thomas Ball (2014) def compute(x): res = x res = res + (res << 10) res = res ^ (res >> 6) return res def hashval(key): hv = compute(key) if (hv == key + 1): return 0 else: return 1 def expected_result(): return [1] ================================================ FILE: test/len_test.py ================================================ from symbolic.args import * class Foo(): def __init__(self, var): self.var = var def __len__(self): return self.var @symbolic(a=0) def len_test(a): f = Foo(a) if len(f) == 2: return 1 else: return 0 def expected_result(): return [0, 1] ================================================ FILE: test/lib/__init__.py ================================================ # hello there1 ================================================ FILE: test/lib/bsearch.py ================================================ def bsearch(a,k): lo, hi = 0, len(a)-1 while(lo <= hi): mid = (lo+hi) >> 1 if (a[mid] == k): return mid elif (a[mid] < k): lo = mid+1 else: hi = mid-1 return -1 ================================================ FILE: test/lib/se_dict.py ================================================ # Copyright: see copyright.txt class SymbolicDictionary(dict): def __init__(self, *args, **kwargs): dict.__init__(self) self.update(*args, **kwargs) def has_key(self, key): for k in self.keys(): if k == key: return True return False ================================================ FILE: test/list.py ================================================ def list(a,b): if ([a,b] == [1,2]): return 1 else: return 2 def expected_result_set(): return [1,2] ================================================ FILE: test/logical_op.py ================================================ # Copyright: see copyright.txt def logical_op(in1, in2): if (in1 & in2) == 1: if (in1 & in2) == 7: return 1 else: return 2 else: return 3 return 0 def expected_result(): return [2,3] ================================================ FILE: test/loop.py ================================================ def loop(in1,in2): if in1 > in2: i = 0 while i < in1 and False: i = i+1 return 1 else: return 0 def expected_result(): return [0,1,1] ================================================ FILE: test/many_branches.py ================================================ # Copyright: see copyright.txt # Test if engine explores all paths def many_branches(in1, in2, in3): if in1 == 0: if in2 == 5: if in3 == 10: return 1 else: return 2 else: if in3 <= 3: return 3 else: return 4 else: if in1 == 1: if in2 == 7: return 5 else: return 6 else: if in2 == 9: return 7 else: return 8 return 0 def expected_result(): return [1, 2, 3, 4, 5, 6, 7, 8] ================================================ FILE: test/maxtest.py ================================================ # Created by Thomas Ball (2014) # def max2(s,t): if (s < t): return t else: return s def max4(x,y,x2,y2): return max2(max2(x,y),max2(x2,y2)) def maxtest(a,b,c,d): m = max4(a,b,c,d) if (m < a or m < b or m < c or m < d): return "ERROR" else: return "OK" def expected_result(): return [ "OK" for i in range(8) ] ================================================ FILE: test/mod.py ================================================ def mod(x,y): if 0 < y < 10 and x % (y+1) == 3: return 0 else: return 1 def expected_result(): return [0,1,1,1] ================================================ FILE: test/modulo.py ================================================ def modulo(in1): if in1 % 3 != 0: return 1 elif in1 % 5 != 0: return 2 return 0 def expected_result(): return [0,1,2] ================================================ FILE: test/modulo2.py ================================================ def modulo2(in1): if (in1 <= 0): return -1 if in1 % 3 != 0: return 1 elif in1 % 5 != 0: return 2 return 0 def expected_result(): return [-1,0,1,2] ================================================ FILE: test/mult_assmt.py ================================================ def mult_assmt(in1,in2,in3): v = in1 if v == in2: if in3 > 0: v = v + 1 if v != in2: return 1 else: return 2 return 0 def expected_result(): return [0,1,2] ================================================ FILE: test/polyspace.py ================================================ def where_are_the_errors(input): k = input // 100 x = 2 y = k + 5 while x < 10: x = x + 1 y = y + 3 if (3*k + 100) > 43: y = y + 1 # x == 10, y == k+30 if x - y == 0: # unreachable return "DIVZERO" x = x // (x - y) return x def polyspace(i): ret = where_are_the_errors(i) return ret def expected_result(): return [-1,10] ================================================ FILE: test/power.py ================================================ # currently, we don't handle the power operator symbolically, # so this test is not expected to cover the else branch. The # initial (concrete) value of x is zero, so we expect only to # cover the then branch. def power(x): if (x+2) ** 2 == 4: return 0 else: return 1 def expected_result(): return [0] ================================================ FILE: test/power2.py ================================================ def power2(x): b = x * x; if b > 0: return 0 elif b == 0: return 1 else: # This path is not possible if it is guaranteed that overflows do not occur. return 2 def expected_result(): return [0, 1] ================================================ FILE: test/powtest.py ================================================ def powtest(in1): if in1*in1 == 0: return 1 elif in1*in1 > 0: return 2 return 0 def expected_result(): return [1,2] ================================================ FILE: test/reverse.py ================================================ # check that sub and rsub are modelled properly def reverse(x): if (x - 5 == 0): return 0 return 1 def expected_result(): return [0,1] ================================================ FILE: test/set.py ================================================ S = { 1, 3, 9, 12, 15, 19 } def set(x): if x in [ j for j in S]: return x else: return "NONE" def expected_result(): return [1,3,9,12,15,19,"NONE"] ================================================ FILE: test/shallow_branches.py ================================================ # Copyright: see copyright.txt # Test if engine explores all paths def shallow_branches(in1, in2, in3, in4, in5): if in1 == 0: return 1 if in2 == 0: return 3 if in3 == 0: return 5 if in4 == 0: return 7 if in5 == 0: return 9 return 0 def expected_result(): return [0, 1, 3, 5, 7, 9] ================================================ FILE: test/simple.py ================================================ def simple(x): if (x+1 > 10): return 42 else: return 43 def expected_result(): return [ 42, 43] ================================================ FILE: test/swap.py ================================================ def swap(in1,in2): if in1 > in2: # swap in1 and in2 in1 = in1 ^ in2; in2 = in1 ^ in2; in1 = in1 ^ in2; if in1 > in2: # impossible return 1 else: return 2 else: return 0 def expected_result(): return [0,2] ================================================ FILE: test/tmp ================================================ ================================================ FILE: test/tuplecmp.py ================================================ def tuplelt(a, b): a0, a1 = a b0, b1 = b if a0 < b0: return True elif a1 < b1: return True return False def tuplecmp(a0, a1, b0, b1): return tuplelt((a0, a1), (b0, b1)) def expected_result(): return [True, True, False] ================================================ FILE: test/unnecessary_condition.py ================================================ def unnecessary_condition(in1,in2): if in1 > in2: unnec = in1 < in2 and False if unnec: return 2 return 1 else: return 0 def expected_result(): return [0,1] ================================================ FILE: test/unnecessary_condition2.py ================================================ def unnecessary_condition2(in1,in2): if in1 > in2: # unnec always false unnec = in1 < 5 and False # this is a branching point because of (in1 < 5) if unnec: # this is not a real branching point return 2 return 1 else: return 0 def expected_result(): return [0,1,1] ================================================ FILE: test/unnecessary_condition3.py ================================================ def unnecessary_condition3(in1): if in1 > 0: # in1 > 0 return op(in1) + 10 else: return op(in1) + 20 def op(in1): if in1 < -10: return 1 if in1 < -5: return 2 if in1 < -3: return 3 if in1 < 0: return 4 return 0 def expected_result(): return [10,20,21,22,23,24] ================================================ FILE: test/unnecessary_condition4.py ================================================ def unnecessary_condition4(in1): v = op(in1) if in1 > 0: # in1 > 0 return v + 10 else: return v + 20 def op(in1): if in1 < -10: return 1 if in1 < -5: return 2 if in1 < -3: return 3 if in1 < 0: return 4 return 0 def expected_result(): return [10,20,21,22,23,24] ================================================ FILE: test/weird.py ================================================ def weird(x,y): if (x < y) + x == 1: return 0 else: return 1 def expected_result(): return [0,1] #print weird(0,1) #print weird(2,3) ================================================ FILE: test/whileloop.py ================================================ def whileloop(x): y = 1 while (0 <= x < 10 and y<=x): y = y + 1 ================================================ FILE: tools/symbolic_int_subtype.py ================================================ # Check if SymbolicInteger is a subtype of `int' modulo concolic execution. # # To run: # $ python sym_exec.py examples/symbolic_int_subtype.py from inspect import signature from symbolic.symbolic_types.symbolic_int import SymbolicInteger # Collect integer methods to test. INT_FUNCS = [] for fname in dir(int): # TODO for some functions signature lookup fails, maybe hardcode arity try: if fname in ('__delattr__', '__getattribute__', '__setattr__', '__new__', '__init__'): continue INT_FUNCS.append((fname, len(signature(getattr(int, fname)).parameters))) except: pass # NOTE Uncomment this to have a restricted set of (correctly modelled) functions # INT_FUNCS = [ ('__add__', 2), ('__sub__', 2), ('__and__', 2), ('__or__', 2) ] def symbolic_int_subtype(func_index, a, b, c): # make concolic execution branch on elements of INT_FUNCS if func_index in [ i for i, fname in enumerate(INT_FUNCS) if INT_FUNCS[i] ]: name, arity = INT_FUNCS[func_index] print("%s/%d" % (name, arity)) assert(0 <= arity <= 3) int_params = [ int(a), int(b), int(c) ] sym_params = [ a, b, c ] int_func = getattr(int, name) sym_func = getattr(SymbolicInteger, name) try: int_return = int_func(*int_params[:arity]) except ValueError as e: int_return = e except ZeroDivisionError as e: int_return = e try: sym_return = sym_func(*sym_params[:arity]) except ValueError as e: sym_return = e except ZeroDivisionError as e: sym_return = e same = ((isinstance(int_return, Exception) and isinstance(sym_return, Exception) and type(int_return) == type(sym_return) ) or int_return == sym_return) if not same: s = ("\nint %s(%s): %r,\nsym %s(%s): %r" % (name, ','.join(str(i) for i in int_params), int_return, name, ','.join(str(i) for i in sym_params), sym_return)) raise Exception(s) return (name, same) else: return "OUTSIDE" # TODO Implement oracle. # How to predict the number of paths for a given int method? ================================================ FILE: utils.py ================================================ # Copyright: see copyright.txt import sys import traceback def traceback(): stack = traceback.format_stack() rest = stack[:-2] return "\n"+"".join(rest) def crash(msg): #stack = _traceback() print(msg) sys.exit(-1) ================================================ FILE: vagrant.sh ================================================ # Configuration INSTALLDIR=/home/vagrant/pyex # System Maintenance apt-get update apt-get -y upgrade # Dependencies apt-get -y install python3 apt-get -y install graphviz graphviz-dev ## Z3 apt-get -y install g++ apt-get -y install python3-examples cd /tmp git clone https://github.com/Z3Prover/z3.git cd z3 git checkout -b unstable origin/unstable python scripts/mk_make.py cd build make make install cp libz3.so /usr/lib/python3/dist-packages python3 /usr/share/doc/python3.2/examples/scripts/reindent.py z3*.py cp z3*.py /usr/lib/python3/dist-packages cp z3*.pyc /usr/lib/python3/dist-packages cd ## CVC4 apt-get install -y libgmp-dev apt-get install -y libboost-all-dev apt-get install -y openjdk-7-jre openjdk-7-jdk apt-get install -y swig apt-get install -y python3-dev cd /tmp git clone https://github.com/CVC4/CVC4.git cd CVC4 ./autogen.sh contrib/get-antlr-3.4 export PYTHON_CONFIG=/usr/bin/python3.2-config ./configure --enable-optimized --with-antlr-dir=/tmp/CVC4/antlr-3.4 ANTLR=/tmp/CVC4/antlr-3.4/bin/antlr3 --enable-language-bindings=python echo "python_cpp_SWIGFLAGS = -py3" >> src/bindings/Makefile.am autoreconf make make doc make install echo "/usr/local/lib" > /etc/ld.so.conf.d/cvc4.conf /sbin/ldconfig cp builds/src/bindings/python/CVC4.py /usr/lib/python3/dist-packages/CVC4.py cp builds/src/bindings/python/.libs/CVC4.so /usr/lib/python3/dist-packages/_CVC4.so cd # Installation ln -s /vagrant $INSTALLDIR ln -s $INSTALLDIR/symbolic /usr/lib/python3/dist-packages/ cat > /usr/bin/pyex <