├── .github └── workflows │ └── main.yml ├── .gitignore ├── .vscode ├── extensions.json └── launch.json ├── LICENSE.md ├── MANIFEST.in ├── README.md ├── bin ├── checkstyle.sh ├── opfuzz ├── typefuzz └── yinyang ├── docs ├── Makefile ├── basic_usage.rst ├── building_on.rst ├── conf.py ├── customization.rst ├── fusion.rst ├── index.rst ├── installation.rst ├── make.bat └── setup.rst ├── examples ├── c27.txt ├── c31.txt ├── c42.txt ├── phi1.smt2 ├── phi2.smt2 ├── phi3.smt2 ├── phi4.smt2 ├── seed27.smt2 ├── seed31.smt2 └── seed42.smt2 ├── media └── logo.png ├── pyproject.toml ├── scripts └── SMT-LIB-clone.sh ├── setup.cfg ├── tests ├── RunUnitTests.py ├── integration │ ├── detection │ │ ├── TestCrashes.py │ │ ├── TestDetection.py │ │ └── crashes │ │ │ ├── cvc4-4414.crash │ │ │ ├── cvc4-4694.crash │ │ │ ├── cvc4-5021.crash │ │ │ ├── cvc4-5079.crash │ │ │ ├── cvc4-5101.crash │ │ │ ├── cvc4-5106.crash │ │ │ ├── cvc4-5238.crash │ │ │ ├── cvc4-5288.crash │ │ │ ├── cvc4-5341.native │ │ │ ├── cvc4-5358.crash │ │ │ ├── cvc4-5454.crash │ │ │ ├── cvc4-5489.crash │ │ │ ├── cvc4-5508.crash │ │ │ ├── cvc4-5511.crash │ │ │ ├── cvc4-5513.crash │ │ │ ├── cvc4-5608.crash │ │ │ ├── cvc4-5609.crash │ │ │ ├── cvc4-5610.crash │ │ │ ├── cvc4-ukn1.native │ │ │ ├── z3-4292.crash │ │ │ ├── z3-4305.crash │ │ │ ├── z3-4310.crash │ │ │ ├── z3-4334.crash │ │ │ ├── z3-4346.crash │ │ │ ├── z3-4352.crash │ │ │ ├── z3-4353.crash │ │ │ ├── z3-4357.crash │ │ │ ├── z3-4371.crash │ │ │ ├── z3-4372.crash │ │ │ ├── z3-4392.crash │ │ │ ├── z3-4469.crash │ │ │ ├── z3-4532.crash │ │ │ ├── z3-4798.crash │ │ │ ├── z3-4809.crash │ │ │ ├── z3-4837.crash │ │ │ ├── z3-4843.crash │ │ │ ├── z3-4845.crash │ │ │ ├── z3-4853.crash │ │ │ ├── z3-4860.crash │ │ │ ├── z3-4866.crash │ │ │ ├── z3-ukn1.crash │ │ │ └── z3-ukn2.crash │ ├── misc │ │ ├── DirectoryMode.py │ │ ├── FileSizeLimit.py │ │ ├── NoSolvers.py │ │ ├── Usage.py │ │ ├── mock_benchmarks │ │ │ ├── invalid.smt2 │ │ │ ├── larger.smt2 │ │ │ └── valid.smt2 │ │ ├── pypi.sh │ │ └── too_large.smt2 │ ├── opfuzz │ │ ├── SanityOpFuzz.py │ │ ├── cvc4_wrong_3564_hidden.smt2 │ │ ├── z3-segfault-3549.smt2 │ │ └── z3_invmodel_3118_hidden.smt2 │ ├── parsing │ │ ├── ast │ │ │ ├── Ast.py │ │ │ ├── CheckOutput.py │ │ │ └── Run.py │ │ └── parser │ │ │ ├── Parse.py │ │ │ └── Run.py │ ├── semanticfusion │ │ ├── 37315_issue-1694.smt2 │ │ ├── 5jby0_z3_bug_incorrect_script1.smt2 │ │ ├── 5jby0_z3_bug_incorrect_script2.smt2 │ │ ├── SanitySemanticFusion.py │ │ ├── gIxXB_cvc4_bug_incorrect_script1.smt2 │ │ ├── gIxXB_cvc4_bug_incorrect_script2.smt2 │ │ ├── intersection-example-simple.proof-node75884.smt2 │ │ └── water_tank-node5020.smt2 │ └── typefuzz │ │ ├── BasicUsage.py │ │ └── SanityTypeFuzz.py ├── regression │ ├── 53.smt2 │ ├── 55.smt2 │ ├── issue42.py │ └── scoping_bug.py ├── res │ ├── formula1.smt2 │ ├── formula2.smt2 │ ├── formula_file.smt2 │ ├── fusion_functions.txt │ ├── issue18.smt2 │ ├── issue7.smt2 │ └── operators.txt └── unit │ ├── TestGenTypeAwareMutation.py │ ├── TestLocalVariables.py │ ├── TestParsing.py │ ├── TestSemanticFusion.py │ ├── TestTerm.py │ ├── TestTypeAwareOpMutation.py │ ├── TestTypechecker.py │ └── test.smt2 └── yinyang ├── __init__.py ├── config ├── Config.py ├── OpfuzzHelptext.py ├── TypefuzzHelptext.py ├── YinyangHelptext.py ├── __init__.py ├── fusion_functions.txt ├── operator_mutations.txt ├── option_setting.txt └── typefuzz_config.txt └── src ├── __init__.py ├── base ├── ArgumentParser.py ├── Driver.py ├── Error.py ├── Exitcodes.py ├── Utils.py ├── Version.py └── __init__.py ├── core ├── Fuzzer.py ├── FuzzerUtil.py ├── Logger.py ├── OptionGenerator.py ├── Solver.py ├── Statistic.py └── __init__.py ├── mutators ├── GenTypeAwareMutation │ ├── GenTypeAwareMutation.py │ ├── Operator.py │ ├── Util.py │ └── __init__.py ├── Mutator.py ├── SemanticFusion │ ├── SemanticFusion.py │ ├── Util.py │ ├── VariableFusion.py │ └── __init__.py ├── TypeAwareOpMutation.py └── __init__.py └── parsing ├── Ast.py ├── AstVisitor.py ├── Parse.py ├── SMTLIBv2.g4 ├── SMTLIBv2.interp ├── SMTLIBv2.tokens ├── SMTLIBv2Lexer.interp ├── SMTLIBv2Lexer.py ├── SMTLIBv2Lexer.tokens ├── SMTLIBv2Listener.py ├── SMTLIBv2Parser.py ├── SMTLIBv2Visitor.py ├── TimeoutDecorator.py ├── Typechecker.py ├── Types.py ├── __init__.py ├── antlr-4.9.2-complete.jar └── regenerate_grammar.sh /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | tests: 7 | runs-on: ubuntu-20.04 8 | strategy: 9 | matrix: 10 | python-version: [3.6, 3.7, 3.8, 3.9] 11 | steps: 12 | - uses: actions/checkout@v2 13 | - name: Set up Python ${{ matrix.python-version }} 14 | uses: actions/setup-python@v2 15 | with: 16 | python-version: ${{ matrix.python-version }} 17 | - name: Install dependencies 18 | run: | 19 | pip install codespell 20 | python -m pip install flake8 21 | python -m pip install --upgrade pip 22 | python -m pip install antlr4-python3-runtime==4.9.2 23 | python -m pip install ffg 24 | - name: Spell check 25 | run: | 26 | codespell --skip="Solver.py,SMTLIBv2*,*.g4,*.tokens,*.interp,*.smt2" 27 | - name: code style and static analysis with flake 28 | run: | 29 | bin/checkstyle.sh 30 | - name: Run Unittests 31 | run: | 32 | python -m unittest tests/RunUnitTests.py 33 | - name: Detection logic 34 | run: | 35 | python tests/integration/detection/TestDetection.py 36 | python tests/integration/detection/TestCrashes.py 37 | - name: Misc 38 | run: | 39 | python tests/integration/misc/FileSizeLimit.py 40 | python tests/integration/misc/NoSolvers.py 41 | python tests/integration/misc/DirectoryMode.py 42 | - name: semanticfusion 43 | run: | 44 | python tests/integration/semanticfusion/SanitySemanticFusion.py 45 | - name: typefuzz 46 | run: | 47 | python tests/integration/typefuzz/SanityTypeFuzz.py 48 | python tests/integration/typefuzz/BasicUsage.py 49 | - name: opfuzz 50 | run: | 51 | python tests/integration/opfuzz/SanityOpFuzz.py 52 | python tests/integration/misc/Usage.py 53 | - name: regression 54 | run: | 55 | python tests/regression/issue42.py 56 | cd tests/regression && python scoping_bug.py 57 | - name: pypi check 58 | run: | 59 | tests/integration/misc/pypi.sh 60 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .DS_Store 3 | build 4 | dist 5 | logs 6 | yinyang.egg-info 7 | env 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "ms-python.python" 4 | ] 5 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "SanitySemanticFusion case", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "bin/yinyang", 12 | "console": "integratedTerminal", 13 | "justMyCode": false, 14 | "args": ["-k", "-s", "fusion", "-o", "unsat", "/home/nicola/Documents/eth/studies/ast/yinyang/cvc4-1.6-x86_64-linux-opt --strings-exp", "tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script1.smt2", "tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script2.smt2"] 15 | }, 16 | { 17 | "name": "Unit tests", 18 | "type": "python", 19 | "request": "launch", 20 | "module": "unittest", 21 | "args": [ 22 | "tests/RunUnitTests.py" 23 | ], 24 | "justMyCode": true 25 | }, 26 | { 27 | "name": "Current File", 28 | "type": "python", 29 | "request": "launch", 30 | "program": "${file}", 31 | "console": "integratedTerminal", 32 | "justMyCode": false 33 | } 34 | ] 35 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2020 Yin-Yang Contributors 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include yinyang/config/* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

portfolio_view

2 | 3 |
4 |

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

14 | 15 | 16 | 17 | yinyang 18 | ------------ 19 | A fuzzing framework for SMT solvers. Given a set of seed SMT formulas, yinyang generates mutant formulas to stress-test SMT solvers. yinyang can be used to robustify SMT solvers. It already found **1,500+** bugs in the two state-of-the-art SMT solvers Z3 and CVC4. 20 | 21 | 22 | 23 | Installation 24 | ------------ 25 | To install a stable version of yinyang use: 26 | 27 | ``` 28 | pip3 install yinyang 29 | ``` 30 | 31 | To install the most recent version, check out the repository: 32 | 33 | ``` bash 34 | git clone https://github.com/testsmt/yinyang.git 35 | pip3 install antlr4-python3-runtime==4.9.2 ffg 36 | ``` 37 | 38 | Note that you may want to add `yinyang/bin` to your PATH, for running yinyang conveniently without prefix. 39 | 40 | Usage 41 | ------------- 42 | 1. **Get SMT-LIB 2 benchmarks**. Edit `scripts/SMT-LIB-clone.sh` to select the logics for testing. Run `./scripts/SMT-LIB-clone.sh` 43 | to download the corresponding SMT-LIB 2 benchmarks. Alternatively, you can download benchmarks directly from the [SMT-LIB website](http://smtlib.cs.uiowa.edu/benchmarks.shtml) or supply your own benchmarks. 44 | 45 | 2. **Get and build SMT solvers** for testing. Install two or more [SMT solvers](http://smtlib.cs.uiowa.edu/solvers.shtml) that support the SMT-LIB 2 format. You may find it convenient to add them to your PATH. 46 | 47 | 3. **Run yinyang** on the benchmarks e.g. with Z3 and CVC4. 48 | ```bash 49 | typefuzz "z3 model_validate=true;cvc4 --check-models -m -i -q" benchmarks 50 | ``` 51 | 52 | yinyang will by default randomly select formulas from the folder `./benchmarks` and generate 300 mutants per seed formula. If a bug has been found, the bug trigger is stored in `./bugs`. yinyang will run in an infinite loop. You can use the shortcut CTRL+C to terminate yinyang manually. 53 | 54 | 📘 [Documentation](https://yinyang.readthedocs.io/en/latest/) 55 | 56 | Feedback 57 | --------- 58 | For bugs/issues/questions/feature requests please file an issue. We are always happy to receive your feedback or help you adjust yinyang to the needs of your custom solver, help you build on yinyang, etc. 59 | 60 | 📬 [Contact us](https://yinyang.readthedocs.io/en/latest/building_on.html#contact) 61 | 62 | Additional Resources 63 | ---------- 64 | - [Citing yinyang](https://yinyang.readthedocs.io/en/latest/building_on.html#citing-yinyang) 65 | - [Project website](https://testsmt.github.io/) with bug statistics, talk videos, etc. 66 | - [Google Open Source Peer Bonus](https://opensource.googleblog.com/2021/04/announcing-first-group-of-google-open-source-peer-bonus-winners.html#:~:text=The%20Google%20Open%20Source%20Peer,exceptional%20contributions%20to%20open%20source.) 🏆 67 | - [Amazon Research Awards](https://www.amazon.science/research-awards/recipients/zhendong-su-fall-2021) 🏆 68 | -------------------------------------------------------------------------------- /bin/checkstyle.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | flake8 --exclude "*SMTLIBv2*,*runtests.py*,__init__.py" yinyang/src tests yinyang/config bin/opfuzz bin/yinyang bin/typefuzz --select=E --ignore=E402 --statistics 3 | -------------------------------------------------------------------------------- /bin/opfuzz: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # MIT License 4 | # 5 | # Copyright (c) [2020 - 2021] The yinyang authors 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import os 26 | import sys 27 | import signal 28 | import inspect 29 | from pathlib import Path 30 | 31 | path = Path(__file__) 32 | rootpath = str(path.parent.absolute().parent) 33 | sys.path.append(rootpath) 34 | 35 | current_dir = os.getcwd() 36 | 37 | from yinyang.src.base.Driver import run_checks 38 | from yinyang.src.base.Error import raise_runtime_error 39 | from yinyang.src.base.ArgumentParser import build_opfuzz_parser 40 | from yinyang.src.base.Exitcodes import OK_BUGS, OK_NOBUGS 41 | from yinyang.src.base.Exitcodes import ERR_USAGE, ERR_INTERNAL 42 | 43 | from yinyang.src.core.Fuzzer import Fuzzer 44 | 45 | from yinyang.config.OpfuzzHelptext import ( 46 | usage, 47 | header, 48 | short_description, 49 | long_description, 50 | options, 51 | ) 52 | 53 | 54 | def main(): 55 | parser = build_opfuzz_parser(current_dir, usage) 56 | 57 | if len(sys.argv) == 1: 58 | 59 | # Show medium-length description when called without args containing 60 | # one example and the usage dialogue. 61 | print(header + "\n\nusage:" + usage + short_description, flush=True) 62 | exit(ERR_USAGE) 63 | 64 | elif "-h" in sys.argv or "--help" in sys.argv: 65 | 66 | # If called for help, show long description containing general 67 | # information on opfuzz, two examples with in-depth explanation, 68 | # and the usage dialogue. 69 | print( 70 | header 71 | + "\n" 72 | + long_description 73 | + "\n" 74 | + options 75 | + "\n" 76 | + "usage:" 77 | + usage 78 | + "\n", 79 | flush=True, 80 | ) 81 | exit(OK_NOBUGS) 82 | 83 | else: 84 | args = run_checks(parser, "opfuzz") 85 | try: 86 | fuzzer = Fuzzer(args, "opfuzz") 87 | 88 | def print_stats(): 89 | fuzzer.statistic.printsum() 90 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 91 | exit(OK_NOBUGS) 92 | exit(OK_BUGS) 93 | 94 | def stats_control_c(sig, frame): 95 | print("\b\b\rUser interrupt", flush=True) 96 | print_stats() 97 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 98 | exit(OK_NOBUGS) 99 | exit(OK_BUGS) 100 | 101 | def silent_control_c(sig, frame): 102 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 103 | exit(OK_NOBUGS) 104 | exit(OK_BUGS) 105 | 106 | if not args.quiet: 107 | signal.signal(signal.SIGINT, stats_control_c) 108 | else: 109 | signal.signal(signal.SIGINT, silent_control_c) 110 | exit(OK_NOBUGS) 111 | 112 | fuzzer.run() 113 | except Exception as e: 114 | trace = inspect.trace() 115 | raise_runtime_error(trace, sys.argv, e) 116 | exit(ERR_INTERNAL) 117 | 118 | 119 | if __name__ == "__main__": 120 | main() 121 | -------------------------------------------------------------------------------- /bin/typefuzz: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # MIT License 4 | # 5 | # Copyright (c) [2020 - 2021] The yinyang authors 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | import os 25 | import sys 26 | import signal 27 | import inspect 28 | from pathlib import Path 29 | 30 | path = Path(__file__) 31 | rootpath = str(path.parent.absolute().parent) 32 | sys.path.append(rootpath) 33 | 34 | current_dir = os.getcwd() 35 | 36 | from yinyang.src.base.Driver import run_checks 37 | from yinyang.src.base.Error import raise_runtime_error 38 | from yinyang.src.base.ArgumentParser import build_typefuzz_parser 39 | from yinyang.src.base.Exitcodes import OK_BUGS, OK_NOBUGS 40 | from yinyang.src.base.Exitcodes import ERR_USAGE, ERR_INTERNAL 41 | 42 | from yinyang.src.core.Fuzzer import Fuzzer 43 | 44 | from yinyang.config.TypefuzzHelptext import ( 45 | usage, 46 | header, 47 | short_description, 48 | long_description, 49 | options, 50 | ) 51 | 52 | 53 | def main(): 54 | parser = build_typefuzz_parser(current_dir, usage) 55 | 56 | if len(sys.argv) == 1: 57 | 58 | # Show medium-length description when called without args containing 59 | # one example and the usage dialogue. 60 | print(header + "\n\nusage:" + usage + short_description, flush=True) 61 | exit(ERR_USAGE) 62 | 63 | elif "-h" in sys.argv or "--help" in sys.argv: 64 | 65 | # If called for help, show long description containing general 66 | # information on opfuzz, two examples with in-depth explanation, 67 | # and the usage dialogue. 68 | print( 69 | header 70 | + "\n" 71 | + long_description 72 | + "\n" 73 | + options 74 | + "\n" 75 | + "usage:" 76 | + usage 77 | + "\n", 78 | flush=True, 79 | ) 80 | exit(OK_NOBUGS) 81 | 82 | else: 83 | args = run_checks(parser, "typefuzz") 84 | try: 85 | fuzzer = Fuzzer(args, "typefuzz") 86 | 87 | def print_stats(): 88 | fuzzer.statistic.printsum() 89 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 90 | exit(OK_NOBUGS) 91 | exit(OK_BUGS) 92 | 93 | def stats_control_c(sig, frame): 94 | print("\b\b\rUser interrupt", flush=True) 95 | print_stats() 96 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 97 | exit(OK_NOBUGS) 98 | exit(OK_BUGS) 99 | 100 | def silent_control_c(sig, frame): 101 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 102 | exit(OK_NOBUGS) 103 | exit(OK_BUGS) 104 | 105 | if not args.quiet: 106 | signal.signal(signal.SIGINT, stats_control_c) 107 | else: 108 | signal.signal(signal.SIGINT, silent_control_c) 109 | exit(OK_NOBUGS) 110 | 111 | fuzzer.run() 112 | except Exception as e: 113 | trace = inspect.trace() 114 | raise_runtime_error(trace, sys.argv, e) 115 | exit(ERR_INTERNAL) 116 | 117 | 118 | if __name__ == "__main__": 119 | main() 120 | -------------------------------------------------------------------------------- /bin/yinyang: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | # MIT License 4 | # 5 | # Copyright (c) [2020 - 2021] The yinyang authors 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | # SOFTWARE. 24 | 25 | import os 26 | import sys 27 | import signal 28 | import inspect 29 | from pathlib import Path 30 | 31 | path = Path(__file__) 32 | rootpath = str(path.parent.absolute().parent) 33 | sys.path.append(rootpath) 34 | 35 | current_dir = os.getcwd() 36 | 37 | from yinyang.src.base.Driver import run_checks 38 | from yinyang.src.base.Error import raise_runtime_error 39 | from yinyang.src.base.ArgumentParser import build_yinyang_parser 40 | from yinyang.src.base.Exitcodes import OK_BUGS, OK_NOBUGS 41 | from yinyang.src.base.Exitcodes import ERR_USAGE, ERR_INTERNAL 42 | 43 | from yinyang.src.core.Fuzzer import Fuzzer 44 | 45 | from yinyang.config.YinyangHelptext import ( 46 | usage, 47 | header, 48 | short_description, 49 | long_description, 50 | options, 51 | ) 52 | 53 | 54 | def main(): 55 | parser = build_yinyang_parser(current_dir, usage) 56 | 57 | if len(sys.argv) == 1: 58 | 59 | # Show medium-length description when called without args containing 60 | # one example and the usage dialogue. 61 | print(header + "\n\nusage:" + usage + short_description, flush=True) 62 | exit(ERR_USAGE) 63 | 64 | elif "-h" in sys.argv or "--help" in sys.argv: 65 | 66 | # If called for help, show long description containing general 67 | # information on opfuzz, two examples with in-depth explanation, 68 | # and the usage dialogue. 69 | print( 70 | header 71 | + "\n" 72 | + long_description 73 | + "\n" 74 | + options 75 | + "\n" 76 | + "usage:" 77 | + usage 78 | + "\n", 79 | flush=True, 80 | ) 81 | exit(OK_NOBUGS) 82 | 83 | else: 84 | args = run_checks(parser, "yinyang") 85 | try: 86 | fuzzer = Fuzzer(args, "yinyang") 87 | 88 | def print_stats(): 89 | fuzzer.statistic.printsum() 90 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 91 | exit(OK_NOBUGS) 92 | exit(OK_BUGS) 93 | 94 | def stats_control_c(sig, frame): 95 | print("\b\b\rUser interrupt", flush=True) 96 | print_stats() 97 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 98 | exit(OK_NOBUGS) 99 | exit(OK_BUGS) 100 | 101 | def silent_control_c(sig, frame): 102 | if fuzzer.statistic.crashes + fuzzer.statistic.soundness == 0: 103 | exit(OK_NOBUGS) 104 | exit(OK_BUGS) 105 | 106 | if not args.quiet: 107 | signal.signal(signal.SIGINT, stats_control_c) 108 | else: 109 | signal.signal(signal.SIGINT, silent_control_c) 110 | exit(OK_NOBUGS) 111 | 112 | fuzzer.run() 113 | exit(OK_NOBUGS) 114 | except Exception as e: 115 | trace = inspect.trace() 116 | raise_runtime_error(trace, sys.argv, e) 117 | exit(ERR_INTERNAL) 118 | 119 | 120 | if __name__ == "__main__": 121 | main() 122 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/basic_usage.rst: -------------------------------------------------------------------------------- 1 | Basic usage 2 | ============== 3 | 4 | yinyang is a mutation-based fuzzer, i.e. it mutates a set of seed formulas using a mutation strategy and then uses the mutated formulas as the test seeds for SMT solvers. yinyang can so detect soundness bugs, invalid model bugs, crashes, segfaults, etc. With ``typefuzz`` we generate mutants by generating fresh expressions from the ones from the seed and root them by operators such as ``=,distinct,+,-, *,/`` by one another. You can run yinyang with the ``typefuzz`` strategy using the following command: 5 | 6 | .. code-block:: bash 7 | 8 | $ typefuzz "" 9 | 10 | - ````: a sequence of SMT solvers command lines separated by semicolons. At least two SMT solvers command lines are necessary. 11 | 12 | 13 | - ````: path to single seed or a directory containing the SMT-LIB seed files. 14 | 15 | 16 | **Example:** 17 | 18 | .. code-block:: bash 19 | 20 | $ typefuzz "z3 model_validate=true;cvc4 --check-models -m -i -q" benchmarks 21 | 22 | 23 | yinyang will by default randomly select formulas from the folder ``./benchmarks``. By default SMT-LIB files larger than 20k will be ignored. yinyang will generate 300 mutants per seed formula and will run in an infinite loop. You can use the shortcut ``CTRL+C`` to terminate yinyang manually. If a bug has been found, the bug trigger is stored in ``./bugs``. 24 | 25 | .. note:: 26 | To catch invalid model bugs, you have to supply options to enable model validation in ````. Also consider that you may need to supply options to enable model production and incremental mode to command lines in ````. 27 | 28 | **Reducing a bug**. 29 | After finding a bug, it is useful to produce a minimal test case before reporting the bug to save the SMT solver developers' time and effort. For many test cases, the C code reducer `creduce `_ does a great job. Besides, SMT-LIB specific reducer `pydelta `_ can be used. 30 | -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | import sphinx_rtd_theme 2 | 3 | # Configuration file for the Sphinx documentation builder. 4 | # 5 | # This file only contains a selection of the most common options. For a full 6 | # list see the documentation: 7 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 8 | 9 | # -- Path setup -------------------------------------------------------------- 10 | 11 | # If extensions (or modules to document with autodoc) are in another directory, 12 | # add these directories to sys.path here. If the directory is relative to the 13 | # documentation root, use os.path.abspath to make it absolute, like shown here. 14 | # 15 | # import os 16 | # import sys 17 | # sys.path.insert(0, os.path.abspath('.')) 18 | 19 | 20 | # -- Project information ----------------------------------------------------- 21 | 22 | project = "yinyang" 23 | copyright = "2021, Dominik Winterer, Chengyu Zhang, Zhendong Su" 24 | author = "Dominik Winterer, Chengyu Zhang, Zhendong Su" 25 | 26 | # The full version, including alpha/beta/rc tags 27 | release = "v0.2" 28 | 29 | 30 | # -- General configuration --------------------------------------------------- 31 | 32 | # Add any Sphinx extension module names here, as strings. They can be 33 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 34 | # ones. 35 | extensions = ["recommonmark", "sphinx_rtd_theme"] 36 | 37 | # Add any paths that contain templates here, relative to this directory. 38 | templates_path = ["_templates"] 39 | 40 | # List of patterns, relative to source directory, that match files and 41 | # directories to ignore when looking for source files. 42 | # This pattern also affects html_static_path and html_extra_path. 43 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 44 | 45 | 46 | source_suffix = { 47 | ".rst": "restructuredtext", 48 | ".txt": "markdown", 49 | ".md": "markdown", 50 | } 51 | 52 | # -- Options for HTML output ------------------------------------------------- 53 | 54 | # The theme to use for HTML and HTML Help pages. See the documentation for 55 | # a list of builtin themes. 56 | # 57 | html_theme = "sphinx_rtd_theme" 58 | 59 | html_theme_options = { 60 | "display_version": True, 61 | "collapse_navigation": False, 62 | "sticky_navigation": True, 63 | } 64 | htmlhelp_basename = "yinyang doc" 65 | 66 | # Add any paths that contain custom static files (such as style sheets) here, 67 | # relative to this directory. They are copied after the builtin static files, 68 | # so a file named "default.css" will overwrite the builtin "default.css". 69 | html_static_path = ["_static"] 70 | 71 | html_css_files = [ 72 | "css/custom.css", 73 | ] 74 | -------------------------------------------------------------------------------- /docs/customization.rst: -------------------------------------------------------------------------------- 1 | Customization 2 | ============= 3 | 4 | Options 5 | ......... 6 | 7 | yinyang provides the following options. Please consult ``typefuzz --help`` for a full list. 8 | 9 | * ``-i --iterations ITERATIONS`` the number of iterations on each seed. (default: 300) 10 | * ``-m --modulo MODULO`` specifies how often the mutants will be forwarded to the SMT solvers. For example, with 300 iterations and 2 as a modulo, 150 mutants per seed file will be passed to the SMT solvers. High modulo and iteration counts prioritize deeper mutations. (default: 2) 11 | * ``-t --timeout TIMEOUT`` imposes a timeout limit (in seconds) on each SMT solver for solving mutant formula. (default: 8) 12 | * ``-d, --diagnose`` forwards solver outputs to stdout e.g. for solver command line diagnosis. 13 | * ``-bugs BUGSFOLDER`` (default: ./bugs) 14 | * ``-scratch SCRATCHFOLDER`` specifies where the mutant formulas are temporarily stored. Note, if you run yinyang with several processes in parallel, each instance should have its own scratch folder. (default: ./scratch) 15 | * ``-km --keep-mutants`` do not delete the mutants from the scratch folder. Warning: beware that this can quickly exhaust your entire disk space. 16 | * ``-g, --generate-functions`` dimension of the fusion functions to generate, if greater than 0 do not take into account --config option. (default: 0) 17 | * ``-m, --multiple-variables`` try to fuse at least vars variables, if possible, distributing the variables evenly as possible between the seeds (default: 2) 18 | * ``-q --quiet`` do not output statistics and other output. 19 | * ``-fl, --file-size-limit`` file size limit on seed formula in bytes. (default: 20000) 20 | 21 | 22 | 23 | Customize solvers configurations 24 | ................................. 25 | If you want to test several SMT solver configurations at once the putting them as a commandline argument like ``typefuzz "" `` may be inconvenient to you. Instead, you can modify the solver list in ``.yinyang/Config.py``. The directory file need to be created by the user. 26 | 27 | As an example consider: 28 | 29 | .. code-block:: python3 30 | 31 | solvers = [ 32 | "z3 model_validate=true", 33 | "z3 model_validate=true smt.arith.solver=2", 34 | "z3 model_validate=true smt.arith.solver=3", 35 | "z3 model_validate=true smt.arith.solver=6", 36 | "cvc4 --check-models --produce-models --incremental --strings-exp -q", 37 | ] 38 | 39 | You can then use ``typefuzz "" `` to run the above five solver configurations. 40 | 41 | 42 | Customize bug detection 43 | ......................... 44 | yinyang's bug detection logic is based on three lists: ``crash_list, duplicate_list, ignore_list`` of ``.yinyang/Config.py`` which you can customize. yinyang detects crash bugs by matching the stdout and stderr of the solvers in with the strings in the list``crash_list``. If yinyang detects a bug this way, it subsequently matches the crash message against all strings in ``duplicate_list``. The ``duplicate_list`` is useful to filter out repeatedly occurring bugs from getting copied to ``./bugs``. The ``ignore_list`` can be used to filter out errors occurring in a solver call. By default yinyang detects mutants returning non-zero exit codes as crashes except those that match with the ``ignore_list``. 45 | 46 | 47 | The below setup shows the three lists in ``.yinyang/Config.py`` that worked well in practice with Z3 and CVC4. 48 | 49 | .. code-block:: python3 50 | 51 | crash_list = [ 52 | "Exception", 53 | "lang.AssertionError", 54 | "lang.Error", 55 | "runtime error", 56 | "LEAKED", 57 | "Leaked", 58 | "Segmentation fault", 59 | "segmentation fault", 60 | "segfault", 61 | "ASSERTION", 62 | "Assertion", 63 | "Fatal failure", 64 | "Internal error detected", 65 | "an invalid model was generated", 66 | "Failed to verify", 67 | "failed to verify", 68 | "ERROR: AddressSanitizer:", 69 | "invalid expression", 70 | "Aborted" 71 | ] 72 | 73 | duplicate_list = [ 74 | 75 | ] 76 | 77 | ignore_list = [ 78 | "(error ", 79 | "unexpected char", 80 | "failed to open file", 81 | "Expected result sat but got unsat", 82 | "Expected result unsat but got sat", 83 | "Parse Error", 84 | "Cannot get model", 85 | "Symbol 'str.to-re' not declared as a variable", 86 | "Symbol 'str.to.re' not declared as a variable", 87 | "Unimplemented code encountered", 88 | ] 89 | -------------------------------------------------------------------------------- /docs/fusion.rst: -------------------------------------------------------------------------------- 1 | Fusion 2 | =============== 3 | Fusion is a metamorphic testing approach than can work with a single SMT solver.If multiple suitable SMT solvers are available for your use-case, we recommend using ``opfuzz`` instead. 4 | 5 | 6 | Basic Idea 7 | ........... 8 | The basic idea behind fusion is to fuse formula pairs into a new formula of known satisfiability (either both sat or both unsat). Given two seed formulas :math:`\varphi_1`, :math:`\varphi_2` and variables :math:`x, y` of :math:`\varphi_1` and :math:`\varphi_2` respectively, the idea is to 9 | 10 | 1. Concatenate the formulas :math:`\varphi_1` and :math:`\varphi_2` 11 | 2. Add a fresh variable :math:`z = f(x,y)` 12 | 3. Replace random occurrences of :math:`x = g_x(y)` and :math:`y = g_y(x)` within the concatenated formula 13 | 14 | We call :math:`f` a fusion function and :math:`g_x, g_y` inversion functions. 15 | 16 | Usage 17 | ...... 18 | 19 | .. code-block:: bash 20 | 21 | $ python3 yinyang.py "" -o -s fusion 22 | $ python3 yinyang.py "" -o -s fusion 23 | 24 | where 25 | 26 | * ```` a sequence of SMT solver commandlines separated by semicolons `;`. Note, since Fusion is a metamorphic testing approach, one SMT solver is sufficient. 27 | 28 | * ```` desired test oracle result {sat, unsat}. 29 | 30 | 31 | * ``, `` SMT-LIB v2.6 file of the same satisfiability, i.e. both either sat or unsat in accordance with the oracle. 32 | 33 | * ```` path to single seed or directory containing the SMT-LIB seed files, all of the same satisifiability. 34 | 35 | 36 | **Examples:** 37 | 38 | .. code-block:: bash 39 | 40 | $ python3 yinyang.py "z3" -o sat -s fusion examples/phi1.smt2 examples/phi2.smt2 41 | 42 | yinyang will test z3 by running fusion with 30 iterations on the two satisfiable seed formulas. The mutants generated yinyang will then be by construction satisfiable. In turn, with unsat as an oracle and two unsatisfiable seed formulas, fusion will generate unsatisfiable formulas. 43 | 44 | 45 | .. code-block:: bash 46 | 47 | $ python3 yinyang.py "z3" -o unsat -s fusion examples/phi3.smt2 examples/phi4.smt2 48 | 49 | 50 | Seeds 51 | ...... 52 | Fusion requires the seeds that are pre-categorized to be either sat or unsat. Pre-categorized SMT-LIB scripts are available in the `following repository `_. Fusion currently only supports non-incremental mode, e.g. LIA, LRA, NRA, QF_LIA, QF_LRA, QF_NRA, QF_SLIA, QF_S, etc. Fusion's applicability is constraint by the fusion function used. 53 | 54 | 55 | Fusion functions 56 | ................................ 57 | The configuration file ``yinyang/config/fusion_functions.txt`` specifies fusion and inversion functions. The format is the following: 58 | 59 | .. code-block:: text 60 | 61 | #begin 62 | []* 63 | 64 | [*] 65 | 66 | 67 | 68 | #end 69 | 70 | **Example:** 71 | 72 | The following code shows schematically fusion and inversion are described in ``yinyang/config/fusion_functions.txt``. 73 | 74 | .. code-block:: text 75 | 76 | #begin 77 | (declare-const x Real) 78 | (declare-const y Real) 79 | (declare-const z Real) 80 | (declare-const c Real) 81 | (declare-const c1 Real) 82 | (assert (= z (* (- (- y c) x) c1))) 83 | (assert (= x (- (- y c) (/ z c1)))) 84 | (assert (= y (+ (+ (/ z c1) x) c))) 85 | #end 86 | 87 | 88 | 89 | The example realizes a fusion function for integer variables. First, the variables x,y,z are declared. Variables c_i will be substituted by a random but fixed real constant each. Then fusion function :math:`z = f(x, y) = ((y - c) - x) * c1` is defined in the first assert block. Its corresponding inversion functions for x and y are described in the second and third asserts. 90 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | yinyang: a fuzzer for SMT solvers 2 | ==================================== 3 | 4 | .. figure:: ../media/logo.png 5 | :width: 90 6 | :align: center 7 | 8 | 9 | yinyang is a `fuzzing framework `_ for SMT solvers. It realizes three tools `typefuzz`, `opfuzz` and `yinyang`. Given a set of `SMT-LIB `_ seed formulas, each of the tools generates mutant formulas to stress-test SMT solvers. yinyang roughly operates in the following stages: 10 | 11 | 12 | 1. *Parsing:* First, yinyang parses a single or a set of SMT-LIB formulas to be used for fuzzing. yinyang's parser supports the SMT-LIB v2.6 standard and is customizable. 13 | 14 | 2. *Mutation:* Next, yinyang will mutate the parsed formula(s) using a mutation strategy. yinyang ships three mutation stragies. The most powerful one is generative type-aware operator mutation which mutates expressions within seed formulas and will by default generate 300 mutant formulas per parsed formula. 15 | 16 | 3. *Oracle Check:* Finally, yinyang will query the SMT solvers under test with the mutant formulas and compare the result against a test oracle. By default, such a test oracle would be a second SMT solver but it can also be fixed to be sat or unsat. 17 | 18 | yinyang is intended for use by (1) SMT solver developers testing existing solvers, (2) researchers inventing new decision procedures to asses the robustness of their implementations, and (3) practitioners developing applications based on SMT solvers. 19 | 20 | .. toctree:: 21 | :maxdepth: 2 22 | 23 | installation 24 | setup 25 | basic_usage 26 | customization 27 | fusion 28 | building_on 29 | -------------------------------------------------------------------------------- /docs/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============== 3 | 4 | To install a stable version of yinyang use: 5 | 6 | ``` 7 | pip3 install yinyang 8 | ``` 9 | 10 | The following commands clone yinyang and install the antlr4 python runtime. 11 | 12 | .. code-block:: bash 13 | 14 | $ git clone https://github.com/testsmt/yinyang.git 15 | $ pip3 install antlr4-python3-runtime==4.9.2 16 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /docs/setup.rst: -------------------------------------------------------------------------------- 1 | Fuzzing setup 2 | ============= 3 | 4 | SMT-LIB seeds 5 | .............. 6 | 7 | To select SMT-LIB seed files for fuzzing SMT solvers with yinyang, edit ``scripts/SMT-LIB-clone.sh`` to select the logics for testing. Then use the following command to download the chosen benchmarks. 8 | 9 | .. code-block:: bash 10 | 11 | $ ./scripts/SMT-LIB-clone.sh 12 | 13 | Alternatively, you can download the benchmarks directly from the website of `SMT-LIB initiative `_ 14 | or use your own benchmarks. 15 | 16 | 17 | SMT solvers 18 | .............. 19 | 20 | To run typefuzz or opfuzz, you need to install two or more SMT solvers. 21 | The SMT-LIB initiative provides a comprehensive `list of SMT solvers `_. 22 | Make sure that all SMT solvers you consider for testing support the chosen seeds. 23 | 24 | If you can only use one SMT solver consider :doc:`fusion`. 25 | -------------------------------------------------------------------------------- /examples/c27.txt: -------------------------------------------------------------------------------- 1 | ; 2 | (not Bool Bool) 3 | (=> Bool Bool Bool :right-assoc) 4 | (and Bool Bool Bool :left-assoc) 5 | (or Bool Bool Bool :left-assoc) 6 | (xor Bool Bool Bool :left-assoc) 7 | (str.from_int Int String) 8 | 9 | 10 | -------------------------------------------------------------------------------- /examples/c31.txt: -------------------------------------------------------------------------------- 1 | (str.prefixof String String Bool) 2 | -------------------------------------------------------------------------------- /examples/c42.txt: -------------------------------------------------------------------------------- 1 | (+ Real Real Real :left-assoc) 2 | (+ Int Int Int :left-assoc) 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/phi1.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun x () Int) 2 | (declare-fun w () Bool) 3 | (assert (= x (- 1))) 4 | (assert (= w (= x (- 1)))) 5 | (assert w) 6 | (check-sat) 7 | -------------------------------------------------------------------------------- /examples/phi2.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun y () Int) 2 | (declare-fun v () Bool) 3 | (assert (= v (not (= y (- 1))))) 4 | (assert (ite v false (= y (- 1)))) 5 | (check-sat) 6 | -------------------------------------------------------------------------------- /examples/phi3.smt2: -------------------------------------------------------------------------------- 1 | ; phi3 2 | (declare-fun x () Real) 3 | (assert (not (= (+ (+ 1.0 x) 6.0) (+ 7.0 x)))) 4 | (check-sat) 5 | -------------------------------------------------------------------------------- /examples/phi4.smt2: -------------------------------------------------------------------------------- 1 | ; phi4 2 | (declare-fun y () Real) 3 | (declare-fun w () Real) 4 | (declare-fun v () Real) 5 | (assert (and (< y v) (>= w v) 6 | (< (/ w v) 0) (> y 0))) 7 | (check-sat) 8 | -------------------------------------------------------------------------------- /examples/seed27.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun x () String) 2 | (assert (> (- (str.to_int (str.++ x x))) 0)) 3 | (check-sat) 4 | -------------------------------------------------------------------------------- /examples/seed31.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun a () String) 2 | (assert (str.< a "ar")) 3 | (assert (= "ar" (str.replace a "ar" ""))) 4 | (check-sat) 5 | -------------------------------------------------------------------------------- /examples/seed42.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun a () Real) 2 | (declare-fun b () Real) 3 | (assert (= b (+ 1 (* a a (+ 1 (/ b b)))))) 4 | (check-sat) 5 | -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/media/logo.png -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = [ 3 | "setuptools>=42", 4 | "wheel" 5 | ] 6 | build-backend = "setuptools.build_meta" 7 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = yinyang 3 | version = 0.3.0 4 | author = Dominik Winterer, Chengyu Zhang, Jiwon Park, Zhendong Su, Nicola Dardanis, Lucas Weitzendorf 5 | author_email = dominik.winterer@inf.ethz.ch, dale.chengyu.zhang@gmail.com, jiwon.park@polytechnique.edu, ‎zhendong.su@inf.ethz.ch, nicdard@gmail.com, lweitzendorf@gmail.com 6 | description = A fuzzing framework for SMT solvers 7 | long_description = file: README.md 8 | long_description_content_type = text/markdown 9 | url = https://testsmt.github.io/ 10 | project_urls = 11 | Bug Tracker = https://github.com/testsmt/yinyang/issues 12 | Documentation = https://yinyang.readthedocs.io/en/latest/ 13 | Source Code = https://github.com/testsmt/yinyang 14 | classifiers = 15 | Programming Language :: Python :: 3 16 | License :: OSI Approved :: MIT License 17 | Operating System :: OS Independent 18 | 19 | [options] 20 | include_package_data = True 21 | packages = find: 22 | install_requires = 23 | antlr4-python3-runtime==4.9.2 24 | ffg==0.1.2 25 | python_requires = >=3.6 26 | scripts = 27 | bin/yinyang 28 | bin/opfuzz 29 | bin/typefuzz 30 | -------------------------------------------------------------------------------- /tests/RunUnitTests.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | import unittest 25 | 26 | from tests.unit.TestTerm import TermTestCase 27 | from tests.unit.TestParsing import ParsingTestCase 28 | from tests.unit.TestTypechecker import TypecheckerTestCase 29 | from tests.unit.TestSemanticFusion import SemanticFusionTestCase 30 | from tests.unit.TestTypeAwareOpMutation import TypeAwareOpMutationTestCase 31 | from tests.unit.TestGenTypeAwareMutation import GenTypeAwareMutationTestCase 32 | 33 | sys.path.append("../") 34 | 35 | if __name__ == "__main__": 36 | unittest.main() 37 | -------------------------------------------------------------------------------- /tests/integration/detection/TestCrashes.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import subprocess 25 | import sys 26 | 27 | python = sys.executable 28 | 29 | 30 | def call_fuzzer(first_config, second_config, fn, opts): 31 | cmd = ( 32 | python 33 | + " bin/opfuzz " 34 | + '"' 35 | + first_config 36 | + ";" 37 | + second_config 38 | + '" ' 39 | + opts 40 | + " " 41 | + fn 42 | ) 43 | output = subprocess.getoutput(cmd) 44 | print("$", cmd) 45 | print(output) 46 | crash_issues = 0 47 | for line in output.split("\n"): 48 | if "Detected crash bug:" in line: 49 | crash_issues += 1 50 | return crash_issues, cmd 51 | 52 | 53 | def create_mocksmt2(fn): 54 | open(fn, "w").write( 55 | "(declare-fun x () Int)\n(declare-fun y () Int)\n(assert (= x y))" 56 | ) 57 | 58 | 59 | def create_mocksolver_msg(msg, script_fn): 60 | code = "#! /usr/bin/env python3\n" 61 | code += 'msg="""' + msg + '"""\n' 62 | code += "print(msg)" 63 | open(script_fn, "w").write(code) 64 | os.system("chmod +x " + script_fn) 65 | 66 | 67 | def test_crash_list(msg, fn): 68 | print("Test", fn) 69 | solver = "crash.py" 70 | create_mocksolver_msg(msg, solver) 71 | first_config = os.path.abspath(solver) 72 | second_config = os.path.abspath(solver) 73 | opts = "-i 1 -m 1" 74 | crash, cmd = call_fuzzer(first_config, second_config, FN, opts) 75 | 76 | if crash != 1: 77 | print("[ERROR] Crash", fn, "cannot be captured.") 78 | print(cmd) 79 | exit(1) 80 | else: 81 | os.system("rm -rf " + solver) 82 | 83 | 84 | if __name__ == "__main__": 85 | FN = "mock.smt2" 86 | create_mocksmt2(FN) 87 | root_folder = os.path.dirname(os.path.realpath(__file__)) 88 | crash_folder = root_folder + "/crashes" 89 | for fn in os.listdir(crash_folder): 90 | fn = crash_folder + "/" + fn 91 | msg = open(fn).read() 92 | test_crash_list(msg, fn) 93 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-4414.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::TheoryEngine::checkTheoryAssertionsWithModel(bool) at /home/suz/software/CVC4/src/theory/theory_engine.cpp:2283 2 | Internal error detectedTHEORY_ARRAYS has an asserted fact that the model doesn't satisfy. 3 | The fact: (= (store a 2 3) (store b 2 3)) 4 | Model value: false 5 | Aborted 6 | 7 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-4694.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within bool CVC4::theory::arith::nl::TranscendentalSolver::checkTfTangentPlanesFun(CVC4::Node, unsigned int, std::vector&) at /home/peisen/test/tofuzz/CVC4/src/theory/arith/nl/transcendental_solver.cpp:896 2 | Check failure 3 | 4 | std::find( d_secant_points[tf][d].begin(), d_secant_points[tf][d].end(), c) == d_secant_points[tf][d].end() 5 | 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5021.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within CVC4::Node CVC4::theory::Rewriter::rewriteTo(CVC4::theory::TheoryId, CVC4::Node, CVC4::TConvProofGenerator*) at src/theory/rewriter.cpp:327 2 | Check failure 3 | d_rewriteStack->find(response.d_node) == d_rewriteStack->end() 4 | 5 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5079.crash: -------------------------------------------------------------------------------- 1 | sat 2 | sat 3 | CVC4 suffered a segfault. 4 | Offending address is 0x7faa1777300c 5 | Aborted 6 | 7 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5101.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::SmtEngine::checkModel(bool) at /home/CVC4-Release/src/smt/smt_engine.cpp:1677 2 | Internal error detectedSmtEngine::checkModel(): ERRORS SATISFYING ASSERTIONS WITH MODEL: 3 | model value for i17 4 | is (/ (- 1) 2) 5 | value type is Real 6 | should be of type Int 7 | Run with `--check-models -v' for additional diagnostics. 8 | Aborted 9 | 10 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5106.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within bool CVC4::theory::arith::nl::NlModel::simpleCheckModelMsum(const std::map, CVC4::NodeTemplate >&, bool) at /home/peisen/test/tofuzz/CVC4/src/theory/arith/nl/nl_model.cpp:1095 2 | Check failure 3 | 4 | false 5 | 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5238.crash: -------------------------------------------------------------------------------- 1 | sat 2 | unsat 3 | ( 4 | ) 5 | CVC4 suffered a segfault. 6 | Offending address is 0x55d86748bcec 7 | Aborted 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5288.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within static CVC4::theory::RewriteResponse CVC4::theory::arith::ArithRewriter::rewriteIntsDivModTotal(CVC4::TNode, bool) at /local/suz-local/software/CVC4/src/theory/arith/arith_rewriter.cpp:806 2 | Check failure 3 | n.getConst().isIntegral() 4 | Aborted 5 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5341.native: -------------------------------------------------------------------------------- 1 | Fatal failure within bool CVC4::theory::quantifiers::InstStrategyEnum::process(CVC4::Node, bool, bool) at /home/CVC4/src/theory/quantifiers/inst_strategy_enumerative.cpp:317 2 | Check failure 3 | 4 | terms[i].isNull() || terms[i].getType().isComparableTo(ftypes[i]) 5 | 6 | Aborted 7 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5358.crash: -------------------------------------------------------------------------------- 1 | sat 2 | Fatal failure within void CVC4::smt::CheckModels::checkModel(CVC4::smt::Model*, CVC4::context::CDList >*, bool) at /home/peisen/test/tofuzz/CVC4/src/smt/check_models.cpp:258 3 | Internal error detectedSmtEngine::checkModel(): ERRORS SATISFYING ASSERTIONS WITH MODEL: 4 | assertion: (and (<= (/ 0 1) r6) (<= r6 r6) (<= r6 r1)) 5 | simplifies to: false 6 | expected `true'. 7 | Run with `--check-models -v' for additional diagnostics. 8 | Aborted 9 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5454.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within CVC4::decision::JustificationHeuristic::SearchResult CVC4::decision::JustificationHeuristic::findSplitterRec(CVC4::TNode, CVC4::prop::SatValue) at /home/peisen/test/tofuzz/CVC4/src/decision/justification_heuristic.cpp:568 2 | Check failure 3 | 4 | litPresent == false || litVal == desiredVal 5 | Output should be justified 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5489.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::SmtEngine::checkModel(bool) at /local/suz-local/software/CVC4/src/smt/smt_engine.cpp:1791 2 | Internal error detectedSmtEngine::checkModel(): ERRORS SATISFYING ASSERTIONS WITH MODEL: 3 | assertion: (let ((_let_0 (b j d))) (and (= d _let_0) (= _let_0 a))) 4 | simplifies to: false 5 | expected `true'. 6 | Run with `--check-models -v' for additional diagnostics. 7 | Aborted 8 | 9 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5508.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::theory::strings::InferenceManager::processConflict(const CVC4::theory::strings::InferInfo&) at /home/CVC4/src/theory/strings/inference_manager.cpp:301 2 | Check failure 3 | 4 | !d_state.isInConflict() 5 | 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5511.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within CVC4::symfpuLiteral::wrappedBitVector CVC4::symfpuLiteral::wrappedBitVector::matchWidth(const CVC4::symfpuLiteral::wrappedBitVector&) const [with bool isSigned = false] at src/util/floatingpoint_literal_symfpu.cpp:379 2 | Check failure 3 | this->getWidth() <= op.getWidth() 4 | Aborted 5 | 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5513.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::theory::bags::TheoryBags::eqNotifyNewClass(CVC4::TNode) at /CVC4/src/theory/bags/theory_bags.cpp:106 2 | Check failure 3 | 4 | false 5 | Not implemented yet 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5608.crash: -------------------------------------------------------------------------------- 1 | sat 2 | sat 3 | Fatal failure within CVC4::theory::TrustNode CVC4::theory::strings::TermRegistry::getRegisterTermLemma(CVC4::Node) at /home/peisen/test/tofuzz/CVC4/src/theory/strings/term_registry.cpp:368 4 | Check failure 5 | 6 | d_proxyVarToLength.find(nc) != d_proxyVarToLength.end() 7 | 8 | Aborted (core dumped) 9 | 10 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5609.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::smt::CheckModels::checkModel(CVC4::smt::Model*, CVC4::context::CDList >*, bool) at /CVC4/src/smt/check_models.cpp:249 2 | Internal error detectedSmtEngine::checkModel(): ERRORS SATISFYING ASSERTIONS WITH MODEL: 3 | assertion: (str.contains (str.replace_re_all str7 (str.to_re str8) (str.++ "pQHRoRXwvFIzQiVZFnTiewbePvXHRuMcpJcoKPmTTjPAvGYCNjngoFlOKzthoecQkHVgJxtfUnssQkHhSMKmIYSbwvtzRUFAQ" str6)) (str.replace_re str8 (str.to_re str7) str8)) 4 | simplifies to: false 5 | expected `true'. 6 | Run with `--check-models -v' for additional diagnostics. 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-5610.crash: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::theory::strings::CoreSolver::processSimpleNEq(CVC4::theory::strings::NormalForm&, CVC4::theory::strings::NormalForm&, unsigned int&, bool, unsigned int, std::vector&, CVC4::TypeNode) at /home/CVC4/src/theory/strings/core_solver.cpp:1374 2 | Check failure 3 | 4 | nfiv.size() == nfjv.size() 5 | 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/cvc4-ukn1.native: -------------------------------------------------------------------------------- 1 | Fatal failure within void CVC4::theory::sep::TheorySep::computeLabelModel(CVC4::Node) at /home/CVC4/src/theory/sep/theory_sep.cpp:1677 2 | Check failure 3 | 4 | !d_type_references_all[tn].empty() 5 | 6 | Aborted 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4292.crash: -------------------------------------------------------------------------------- 1 | ==159304==ERROR: AddressSanitizer: heap-use-after-free on address 0x60e000028e38 at pc 0x00000141d4c4 bp 0x7ffc212c6d30 sp 0x7ffc212c6d20 2 | READ of size 8 at 0x60e000028e38 thread T0 3 | #0 0x141d4c3 in smt::theory_str::simplify_parent(expr*, expr*) ../src/smt/theory_str.cpp:2319 4 | #1 0x14535b4 in smt::theory_str::handle_equality(expr*, expr*) ../src/smt/theory_str.cpp:6705 5 | #2 0x1457802 in smt::theory_str::new_eq_eh(int, int) ../src/smt/theory_str.cpp:6992 6 | #3 0xfc5a08 in smt::context::propagate_th_eqs() ../src/smt/smt_context.cpp:1617 7 | #4 0xfc65bf in smt::context::propagate() ../src/smt/smt_context.cpp:1694 8 | #5 0xfdcae0 in smt::context::bounded_search() ../src/smt/smt_context.cpp:3732 9 | #6 0xfdacdc in smt::context::search() ../src/smt/smt_context.cpp:3613 10 | #7 0xfd9269 in smt::context::check(unsigned int, expr* const*, bool) ../src/smt/smt_context.cpp:3496 11 | #8 0xd3f814 in smt::kernel::imp::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:116 12 | #9 0xd3e471 in smt::kernel::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:296 13 | #10 0x10f36b6 in check_sat_core2 ../src/smt/smt_solver.cpp:190 14 | #11 0x19e4fcb in solver_na2as::check_sat_core(unsigned int, expr* const*) ../src/solver/solver_na2as.cpp:67 15 | #12 0x19ebafe in combined_solver::check_sat_core(unsigned int, expr* const*) ../src/solver/combined_solver.cpp:219 16 | #13 0x19e9035 in solver::check_sat(unsigned int, expr* const*) ../src/solver/solver.cpp:330 17 | #14 0x19a1964 in cmd_context::check_sat(unsigned int, expr* const*) ../src/cmd_context/cmd_context.cpp:1549 18 | #15 0x1932033 in smt2::parser::parse_check_sat() ../src/parsers/smt2/smt2parser.cpp:2596 19 | #16 0x1935f8f in smt2::parser::parse_cmd() ../src/parsers/smt2/smt2parser.cpp:2938 20 | #17 0x19376a1 in smt2::parser::operator()() ../src/parsers/smt2/smt2parser.cpp:3130 21 | #18 0x19166c6 in parse_smt2_commands(cmd_context&, std::istream&, bool, params_ref const&, char const*) ../src/parsers/smt2/smt2parser.cpp:3179 22 | #19 0x43c182 in read_smtlib2_commands(char const*) ../src/shell/smtlib_frontend.cpp:89 23 | #20 0x4542b2 in main ../src/shell/main.cpp:352 24 | #21 0x7fab2d60582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) 25 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4305.crash: -------------------------------------------------------------------------------- 1 | Failed to verify: a.is_numeral(val, r) 2 | ASSERTION VIOLATION 3 | File: ../src/qe/qe_arith.cpp 4 | Line: 348 5 | UNREACHABLE CODE WAS REACHED. 6 | Z3 4.8.9.0 7 | Please file an issue with this message and more detail about how you encountered it at https://github.com/Z3Prover/z3/issues/new 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4310.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/ast/ast.cpp 3 | Line: 431 4 | UNREACHABLE CODE WAS REACHED. 5 | Z3 4.8.9.0 6 | Please file an issue with this message and more detail about how you encountered it at https://github.com/Z3Prover/z3/issues/new 7 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4334.crash: -------------------------------------------------------------------------------- 1 | ==42186==ERROR: AddressSanitizer: heap-use-after-free on address 0x60d0000cc5c8 at pc 0x000000d1b305 bp 0x7fff46504c00 sp 0x7fff46504bf0 2 | READ of size 8 at 0x60d0000cc5c8 thread T0 3 | #0 0xd1b304 in smt::enode::get_owner() const ../src/smt/smt_enode.h:180 4 | #1 0x140a63e in smt::theory_str::instantiate_concat_axiom(smt::enode*) ../src/smt/theory_str.cpp:997 5 | #2 0x1408d5a in smt::theory_str::propagate() ../src/smt/theory_str.cpp:864 6 | #3 0xfc59b9 in smt::context::propagate_theories() ../src/smt/smt_context.cpp:1600 7 | #4 0xfc6824 in smt::context::propagate() ../src/smt/smt_context.cpp:1698 8 | #5 0xfd603b in smt::context::init_assumptions(ref_vector const&) ../src/smt/smt_context.cpp:3203 9 | #6 0xfd941a in smt::context::check(unsigned int, expr* const*, bool) ../src/smt/smt_context.cpp:3495 10 | #7 0xd3fa3a in smt::kernel::imp::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:116 11 | #8 0xd3e697 in smt::kernel::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:296 12 | #9 0x10f3954 in check_sat_core2 ../src/smt/smt_solver.cpp:190 13 | #10 0x19e8da3 in solver_na2as::check_sat_core(unsigned int, expr* const*) ../src/solver/solver_na2as.cpp:67 14 | #11 0x19ef8d6 in combined_solver::check_sat_core(unsigned int, expr* const*) ../src/solver/combined_solver.cpp:219 15 | #12 0x19ece0d in solver::check_sat(unsigned int, expr* const*) ../src/solver/solver.cpp:330 16 | #13 0x19a573c in cmd_context::check_sat(unsigned int, expr* const*) ../src/cmd_context/cmd_context.cpp:1549 17 | #14 0x1935e0b in smt2::parser::parse_check_sat() ../src/parsers/smt2/smt2parser.cpp:2596 18 | #15 0x1939d67 in smt2::parser::parse_cmd() ../src/parsers/smt2/smt2parser.cpp:2938 19 | #16 0x193b479 in smt2::parser::operator()() ../src/parsers/smt2/smt2parser.cpp:3130 20 | #17 0x191a49e in parse_smt2_commands(cmd_context&, std::istream&, bool, params_ref const&, char const*) ../src/parsers/smt2/smt2parser.cpp:3179 21 | #18 0x43c1ae in read_smtlib2_commands(char const*) ../src/shell/smtlib_frontend.cpp:89 22 | #19 0x4542de in main ../src/shell/main.cpp:352 23 | #20 0x7fd87ae1382f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f) 24 | 25 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4346.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/util/rational.h 3 | Line: 113 4 | is_unsigned() 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4352.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_str_regex.cpp 3 | Line: 1386 4 | new_lhs 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | a 7 | 8 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4353.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_str_mc.cpp 3 | Line: 1162 4 | NOT IMPLEMENTED YET! 5 | Z3 4.8.9.0 6 | Please file an issue with this message and more detail about how you encountered it at https://github.com/Z3Prover/z3/issues/new 7 | 8 | ASSERTION VIOLATION 9 | File: ../src/smt/theory_str_mc.cpp 10 | Line: 1162 11 | NOT IMPLEMENTED YET! 12 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 13 | 14 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4357.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_str.cpp 3 | Line: 9016 4 | UNREACHABLE CODE WAS REACHED. 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4371.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_diff_logic_def.h 3 | Line: 977 4 | (asgn == l_true) == a->is_true() 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4372.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_arith_core.h 3 | Line: 2507 4 | m_unassigned_atoms[v] > 0 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | 7 | ==111203==ERROR: AddressSanitizer: heap-use-after-free on address 0x61b0000fe580 at pc 0x00000142c3b6 bp 0x7f633a0a7e20 sp 0x7f633a0a7e10 8 | READ of size 1 at 0x61b0000fe580 thread T69 9 | #0 0x142c3b5 in smt::theory_str::process_concat_eq_type1(expr*, expr*) ../src/smt/theory_str.cpp:3370 10 | #1 0x14257de in smt::theory_str::simplify_concat_equality(expr*, expr*) ../src/smt/theory_str.cpp:2798 11 | #2 0x1456581 in smt::theory_str::check_eqc_concat_concat(std::set, std::allocator >&, std::set, std::allocator >&) ../src/smt/theory_str.c 12 | pp:6792 13 | #3 0x1454d53 in smt::theory_str::handle_equality(expr*, expr*) ../src/smt/theory_str.cpp:6689 14 | #4 0x1459260 in smt::theory_str::new_eq_eh(int, int) ../src/smt/theory_str.cpp:7001 15 | #5 0xfc651e in smt::context::propagate_th_eqs() ../src/smt/smt_context.cpp:1617 16 | #6 0xfc70d5 in smt::context::propagate() ../src/smt/smt_context.cpp:1694 17 | #7 0xfd692b in smt::context::init_assumptions(ref_vector const&) ../src/smt/smt_context.cpp:3203 18 | #8 0xfd9d0a in smt::context::check(unsigned int, expr* const*, bool) ../src/smt/smt_context.cpp:3495 19 | #9 0xd4032a in smt::kernel::imp::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:116 20 | #10 0xd3ef87 in smt::kernel::check(unsigned int, expr* const*) ../src/smt/smt_kernel.cpp:296 21 | #11 0x10f4244 in check_sat_core2 ../src/smt/smt_solver.cpp:190 22 | #12 0x19f8ad5 in solver_na2as::check_sat_core(unsigned int, expr* const*) ../src/solver/solver_na2as.cpp:67 23 | #13 0x19fcb3f in solver::check_sat(unsigned int, expr* const*) ../src/solver/solver.cpp:330 24 | #14 0x5e117c in solver::check_sat(ref_vector const&) ../src/solver/solver.h:149 25 | #15 0x1a0c037 in parallel_tactic::solver_state::simplify() ../src/solver/parallel_tactic.cpp:265 26 | #16 0x1a0ebd0 in parallel_tactic::cube_and_conquer(parallel_tactic::solver_state&) ../src/solver/parallel_tactic.cpp:481 27 | #17 0x1a0ff85 in parallel_tactic::run_solver() ../src/solver/parallel_tactic.cpp:634 28 | #18 0x1a10661 in parallel_tactic::solve(ref&)::{lambda()#1}::operator()() const (/home/peisen/test/tofuzz/z3-debug/build/z3+0x1a10661) 29 | #19 0x1a167c1 in void std::_Bind_simple&)::{lambda()#1} ()>::_M_invoke<>(std::_Index_tuple<>) /usr/include/c++/5/functional:1531 30 | #20 0x1a166d5 in std::_Bind_simple&)::{lambda()#1} ()>::operator()() /usr/include/c++/5/functional:1520 31 | #21 0x1a16665 in std::thread::_Impl&)::{lambda()#1} ()> >::_M_run() /usr/include/c++/5/thread:115 32 | #22 0x7f6360410e5d (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0xd0e5d) 33 | #23 0x7f636072a6b9 in start_thread (/lib/x86_64-linux-gnu/libpthread.so.0+0x76b9) 34 | 35 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4392.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/smt_internalizer.cpp 3 | Line: 1056 4 | b_internalized(n) 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | 7 | ./z3-4855.crash 8 | sat 9 | (error "line 7 column 10: an invalid model was generated") 10 | ( 11 | (define-fun b () (_ FloatingPoint 8 24) 12 | (fp #b0 #x7e #b00111111111111111111111)) 13 | (define-fun c () (_ FloatingPoint 8 24) 14 | (fp #b0 #x01 #b00000100000001000010000)) 15 | (define-fun a () RoundingMode 16 | roundTowardZero) 17 | ) 18 | unsat 19 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4469.crash: -------------------------------------------------------------------------------- 1 | sat 2 | (error "line 8 column 10: an invalid model was generated") 3 | 4 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4532.crash: -------------------------------------------------------------------------------- 1 | sat 2 | (error "line 10 column 44: an invalid model was generated") 3 | ( 4 | (define-fun h () Real 5 | 0.0) 6 | (define-fun d () Real 7 | (- 1.0)) 8 | (define-fun c () Real 9 | 2.0) 10 | (define-fun e () Real 11 | (- 1.0)) 12 | (define-fun b () Real 13 | 0.0) 14 | (define-fun f () Real 15 | 0.0) 16 | (define-fun a () Real 17 | 1.0) 18 | (define-fun div0 ((x!0 Int) (x!1 Int)) Int 19 | 0) 20 | (define-fun mod0 ((x!0 Int) (x!1 Int)) Int 21 | 0) 22 | ) 23 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4798.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: D:\a\1\s\src\ast/rewriter/rewriter_def.h 3 | Line: 213 4 | UNREACHABLE CODE WAS REACHED. 5 | Z3 4.8.9.0 6 | Please file an issue with this message and more detail about how you encountered it at https://github.com/Z3Prover/z3/issues/new 7 | 8 | /z3-4873.crash 9 | sat 10 | (error "line 8 column 10: an invalid model was generated") 11 | ( 12 | (define-fun h ((x!0 Int)) Int 13 | 0) 14 | (define-fun f ((x!0 Int)) Int 15 | x!0) 16 | (define-fun g ((x!0 Int)) Int 17 | 0) 18 | ) 19 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4809.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/opt/maxres.cpp 3 | Line: 219 4 | m_model->is_true(m_asms) || m.limit().is_canceled() 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4837.crash: -------------------------------------------------------------------------------- 1 | Failed to verify: len_exists 2 | 3 | ================================================================= 4 | ==101197==ERROR: LeakSanitizer: detected memory leaks 5 | 6 | Direct leak of 104 byte(s) in 13 object(s) allocated from: 7 | #0 0x7f452be5c662 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98662) 8 | #1 0x2625eb3 in memory::allocate(unsigned long) ../src/util/memory_manager.cpp:268 9 | #2 0x62e482 in region::allocate(unsigned long) ../src/util/region.h:37 10 | #3 0x1048e7d in operator new[](unsigned long, region&) ../src/util/region.h:115 11 | #4 0x104761c in smt::ext_simple_justification::ext_simple_justification(region&, unsigned int, smt::literal const*, unsigned int, std::pair const*) ../src/smt/smt_justificati 12 | on.cpp:304 13 | #5 0xd42823 in smt::ext_theory_simple_justification::ext_theory_simple_justification(int, region&, unsigned int, smt::literal const*, unsigned int, std::pair const*, unsigned 14 | int, parameter*) ../src/smt/smt_justification.h:325 15 | #6 0xdfb12f in smt::ext_theory_eq_propagation_justification::ext_theory_eq_propagation_justification(int, region&, unsigned int, smt::literal const*, unsigned int, std::pair 16 | const*, smt::enode*, smt::enode*, unsigned int, parameter*) ../src/smt/smt_justification.h:374 17 | #7 0x12089ec in smt::theory_lra::imp::fixed_var_eh(int, rational const&) ../src/smt/theory_lra.cpp:3161 18 | #8 0x1206c28 in smt::theory_lra::imp::propagate_eqs(lp::tv, unsigned int, lp::lconstraint_kind, lp_api::bound&, rational const&) ../src/smt/theory_lra.cpp:3007 19 | #9 0x1206642 in smt::theory_lra::imp::assert_bound(int, bool, lp_api::bound&) ../src/smt/theory_lra.cpp:2960 20 | #10 0x1200ee5 in smt::theory_lra::imp::propagate() ../src/smt/theory_lra.cpp:2246 21 | #11 0x11dfc80 in smt::theory_lra::propagate() ../src/smt/theory_lra.cpp:3927 22 | #12 0xfc62a9 in smt::context::propagate_theories() ../src/smt/smt_context.cpp:1600 23 | #13 0xfc7114 in smt::context::propagate() ../src/smt/smt_context.cpp:1698 24 | #14 0xfdd66e in smt::context::bounded_search() ../src/smt/smt_context.cpp:3733 25 | #15 0xfdb86a in smt::context::search() ../src/smt/smt_context.cpp:3614 26 | #16 0xfd9df7 in smt::context::check(unsigned int, expr* const*, bool) ../src/smt/smt_context.cpp:3497 27 | #17 0xfd9123 in smt::context::setup_and_check(bool) ../src/smt/smt_context.cpp:3433 28 | #18 0xd402e2 in smt::kernel::imp::setup_and_check() ../src/smt/smt_kernel.cpp:108 29 | #19 0xd3ef39 in smt::kernel::setup_and_check() ../src/smt/smt_kernel.cpp:292 30 | #20 0xc70102 in smt_tactic::operator()(ref const&, sref_buffer&) ../src/smt/tactic/smt_tactic.cpp:201 31 | #21 0x1a72fa5 in and_then_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:120 32 | #22 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 33 | #23 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 34 | #24 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 35 | #25 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 36 | #26 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 37 | #27 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 38 | #28 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 39 | #29 0x1a7b6ba in cond_tactical::operator()(ref const&, sref_buffer&) ../src/tactic/tactical.cpp:1034 40 | 41 | ASSERTION VIOLATION 42 | File: ../src/muz/spacer/spacer_util.cpp 43 | Line: 430 44 | !m.is_false(a) 45 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 46 | 47 | Unexpected expression: false 48 | ASSERTION VIOLATION 49 | File: ../src/muz/spacer/spacer_util.cpp 50 | Line: 529 51 | UNREACHABLE CODE WAS REACHED. 52 | Z3 4.8.8.0 53 | Please file an issue with this message and more detail about how you encountered it at https://github.com/Z3Prover/z3/issues/new 54 | 55 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4843.crash: -------------------------------------------------------------------------------- 1 | sat 2 | ( 3 | (define-fun x () (_ FloatingPoint 11 53) 4 | (_ -zero 11 53)) 5 | ) 6 | sat 7 | (error "line 8 column 20: an invalid model was generated") 8 | ( 9 | (define-fun x () (_ FloatingPoint 11 53) 10 | (_ +zero 11 53)) 11 | ) 12 | 13 | 14 | sat 15 | (error "line 34 column 10: an invalid model was generated") 16 | ( 17 | (define-fun p () (_ FloatingPoint 8 24) 18 | (fp #b1 #x24 #b00000000000000000000000)) 19 | (define-fun bb () (_ FloatingPoint 8 24) 20 | (fp #b0 #xd7 #b00100000010000010110100)) 21 | (define-fun d () (_ FloatingPoint 8 24) 22 | (fp #b1 #x7f #b01100110011001100110100)) 23 | (define-fun n () (_ FloatingPoint 8 24) 24 | (fp #b0 #x24 #b00000000000000000110100)) 25 | (define-fun k () (_ FloatingPoint 8 24) 26 | (_ NaN 8 24)) 27 | (define-fun h () (_ FloatingPoint 8 24) 28 | (_ +zero 8 24)) 29 | (define-fun j () (_ FloatingPoint 8 24) 30 | (fp #b0 #xd7 #b00100000010000010110100)) 31 | (define-fun o () (_ FloatingPoint 8 24) 32 | (_ +zero 8 24)) 33 | (define-fun i () (_ FloatingPoint 8 24) 34 | (fp #b1 #x7f #b11100110011001100110111)) 35 | (define-fun f () (_ FloatingPoint 8 24) 36 | (fp #b1 #x7f #b01100110011001100110100)) 37 | (define-fun g () (_ FloatingPoint 8 24) 38 | (_ +zero 8 24)) 39 | (define-fun q () (_ FloatingPoint 8 24) 40 | (fp #b1 #x24 #b00000000000000000000000)) 41 | (define-fun l () (_ FloatingPoint 8 24) 42 | (fp #b0 #x80 #b00000000000000000000000)) 43 | (define-fun aa () (_ FloatingPoint 8 24) 44 | (_ +zero 8 24)) 45 | (define-fun cc () (_ FloatingPoint 8 24) 46 | (_ -oo 8 24)) 47 | (define-fun c () RoundingMode 48 | roundNearestTiesToAway) 49 | (define-fun b () RoundingMode 50 | roundNearestTiesToEven) 51 | (define-fun a () RoundingMode 52 | roundNearestTiesToEven) 53 | (define-fun e () RoundingMode 54 | roundTowardZero) 55 | ) 56 | 57 | sat 58 | (error "line 5 column 10: an invalid model was generated") 59 | ( 60 | (define-fun Z () (_ FloatingPoint 2 6) 61 | (fp #b0 #b00 #b00001)) 62 | (define-fun X () (_ FloatingPoint 2 6) 63 | (fp #b1 #b01 #b00000)) 64 | (define-fun Y () (_ FloatingPoint 2 6) 65 | (fp #b1 #b01 #b00001)) 66 | ) 67 | 68 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4845.crash: -------------------------------------------------------------------------------- 1 | (error "line 4 column 20: an invalid model was generated") 2 | ( 3 | (define-fun b () Float16 4 | (_ +zero 5 11)) 5 | (define-fun a () Float16 6 | (fp #b0 #b10000 #b0000001000)) 7 | ) 8 | unsat 9 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4853.crash: -------------------------------------------------------------------------------- 1 | (error "line 17 column 10: an invalid model was generated") 2 | ( 3 | (define-fun r8 () Real 4 | 0.0) 5 | (define-fun r12 () Real 6 | (- 1.0)) 7 | (define-fun r2 () Real 8 | (- (/ 1.0 2.0))) 9 | (define-fun r7 () Real 10 | 0.0) 11 | (define-fun r9 () Real 12 | 0.0) 13 | (define-fun r0 () Real 14 | (- (/ 1.0 2.0))) 15 | (define-fun /0 ((x!0 Real) (x!1 Real)) Real 16 | (- (/ 1.0 2.0))) 17 | ) 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4860.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/math/lp/lar_solver.cpp 3 | Line: 1826 4 | column_is_fixed(k) 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | 7 | 8 | sat 9 | (error "line 6 column 10: an invalid model was generated") 10 | (model 11 | (define-fun b () String 12 | "") 13 | (define-fun c () String 14 | "") 15 | (define-fun a () String 16 | "\x00") 17 | ) 18 | 19 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-4866.crash: -------------------------------------------------------------------------------- 1 | sat 2 | (error "line 12 column 10: an invalid model was generated") 3 | ( 4 | (define-fun str0 () String 5 | "!0!") 6 | (define-fun i5 () Int 7 | 0) 8 | (define-fun str2 () String 9 | "\x00") 10 | (define-fun i2 () Int 11 | 1) 12 | (define-fun i4 () Int 13 | 0) 14 | (define-fun v4 () Bool 15 | true) 16 | (define-fun str3 () String 17 | "!0!") 18 | (define-fun v5 () Bool 19 | true) 20 | (define-fun v1 () Bool 21 | true) 22 | ) 23 | 24 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-ukn1.crash: -------------------------------------------------------------------------------- 1 | sat 2 | (error "line 9 column 10: an invalid model was generated") 3 | (model 4 | (define-fun e () Real 5 | (/ 9232379240400289791.0 4611686016279904256.0)) 6 | (define-fun a () Real 7 | (- (/ 2143289343.0 2147483648.0))) 8 | (define-fun c () Real 9 | (/ 1.0 8.0)) 10 | (define-fun d () Real 11 | (/ 50440315803061452800000000.0 631185189288030893469201889.0)) 12 | (define-fun b () Real 13 | 1.0) 14 | ) 15 | 16 | -------------------------------------------------------------------------------- /tests/integration/detection/crashes/z3-ukn2.crash: -------------------------------------------------------------------------------- 1 | ASSERTION VIOLATION 2 | File: ../src/smt/theory_str.cpp 3 | Line: 998 4 | u.str.is_concat(a_cat) 5 | (C)ontinue, (A)bort, (S)top, (T)hrow exception, Invoke (G)DB 6 | 7 | ./z3-4862.crash 8 | [584] % z3release model_validate=true small.smt2 9 | sat 10 | ( 11 | (define-fun X () (_ FloatingPoint 11 53) 12 | (fp #b1 #b01011100010 #x83b6fffeff76e)) 13 | (define-fun Y () (_ FloatingPoint 9 53) 14 | (fp #b1 #b000000000 #x00000003076e0)) 15 | ) 16 | sat 17 | unsat 18 | (error "line 5 column 10: an invalid model was generated") 19 | ( 20 | (define-fun X () (_ FloatingPoint 11 53) 21 | (fp #b0 #b00000000000 #x0001a2bffffff)) 22 | (define-fun Y () (_ FloatingPoint 9 53) 23 | (_ +oo 9 53)) 24 | ) 25 | sat 26 | unsat 27 | 28 | -------------------------------------------------------------------------------- /tests/integration/misc/DirectoryMode.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | import subprocess 26 | 27 | python = sys.executable 28 | 29 | TIME_LIMIT = 180 30 | 31 | 32 | def run_opfuzz(first_config, second_config, directory, opts, timeout_limit): 33 | timeout = "timeout --signal=INT " + str(timeout_limit) + " " 34 | cmd = ( 35 | timeout 36 | + python 37 | + " bin/opfuzz " 38 | + '"' 39 | + first_config 40 | + ";" 41 | + second_config 42 | + '" ' 43 | + opts 44 | + " " 45 | + directory 46 | ) 47 | output = subprocess.getoutput(cmd) 48 | generated_seeds = 0 49 | used_seeds = 0 50 | ignored_issues = 0 51 | return output, cmd 52 | 53 | 54 | def get_cvc4(): 55 | cvc4_link = "https://github.com/CVC4/CVC4/releases/download/1.8/\ 56 | cvc4-1.8-x86_64-linux-opt" 57 | os.system("wget " + cvc4_link) 58 | subprocess.getoutput("chmod +x cvc4-1.8-x86_64-linux-opt") 59 | return os.path.abspath("cvc4-1.8-x86_64-linux-opt") 60 | 61 | 62 | def get_z3(): 63 | z3_link = "https://github.com/Z3Prover/z3/releases/download/z3-4.8.10/\ 64 | z3-4.8.10-x64-ubuntu-18.04.zip" 65 | os.system("wget " + z3_link) 66 | os.system("unzip z3-4.8.10-x64-ubuntu-18.04.zip") 67 | return os.path.abspath("z3-4.8.10-x64-ubuntu-18.04/bin/z3") 68 | 69 | 70 | def cleanup(): 71 | subprocess.getoutput("rm -rf cvc4*") 72 | subprocess.getoutput("rm -rf z3*") 73 | 74 | 75 | cleanup() 76 | cvc4 = get_cvc4() 77 | z3 = get_z3() 78 | first_config = z3 + " model_validate=true" 79 | second_config = cvc4 + " --check-models --produce-models --incremental -q" 80 | mock_benchmarks = str(os.path.dirname(os.path.realpath(__file__)))\ 81 | + "/mock_benchmarks" 82 | out, cmd = run_opfuzz( 83 | first_config, second_config, mock_benchmarks, "-m 1", TIME_LIMIT) 84 | if "3 seeds processed, 1 valid, 2 invalid" not in out: 85 | print("An error occurred.", flush=True) 86 | print("cmd", cmd) 87 | exit(1) 88 | -------------------------------------------------------------------------------- /tests/integration/misc/FileSizeLimit.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import subprocess 25 | import sys 26 | 27 | python = sys.executable 28 | 29 | 30 | def call_fuzzer(first_config, second_config, fn, opts): 31 | cmd = ( 32 | python 33 | + " bin/opfuzz " 34 | + '"' 35 | + first_config 36 | + ";" 37 | + second_config 38 | + '" ' 39 | + opts 40 | + " " 41 | + fn 42 | ) 43 | output = subprocess.getoutput(cmd) 44 | return output, cmd 45 | 46 | 47 | def create_mocksolver_msg(msg, script_fn): 48 | code = "#! /usr/bin/env python3\n" 49 | code += 'msg="""' + msg + '"""\n' 50 | code += "print(msg)" 51 | open(script_fn, "w").write(code) 52 | os.system("chmod +x " + script_fn) 53 | 54 | 55 | solver = "solver.py" 56 | msg = "sat" 57 | create_mocksolver_msg(msg, solver) 58 | first_config = os.path.abspath(solver) 59 | second_config = os.path.abspath(solver) 60 | opts = "-i 1 -m 1" 61 | FN = os.path.dirname(os.path.realpath(__file__)) + "/too_large.smt2" 62 | 63 | out, cmd = call_fuzzer(first_config, second_config, FN, opts) 64 | if "1 seeds processed, 0 valid, 1 invalid" not in out: 65 | print(cmd) 66 | exit(1) 67 | -------------------------------------------------------------------------------- /tests/integration/misc/NoSolvers.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import subprocess 24 | import sys 25 | 26 | python = sys.executable 27 | 28 | 29 | def call_fuzzer(fn): 30 | cmd = python + ' bin/opfuzz "" ' + fn 31 | output = subprocess.getoutput(cmd) 32 | return output 33 | 34 | 35 | fn = "examples/phi1.smt2" 36 | out = call_fuzzer(fn) 37 | print(out) 38 | if "error: no solver specified" in out: 39 | exit(0) 40 | exit(1) 41 | -------------------------------------------------------------------------------- /tests/integration/misc/Usage.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """ 24 | Integration test for usage part in README.md. 25 | """ 26 | import os 27 | import sys 28 | import subprocess 29 | 30 | import_path = os.path.dirname( 31 | os.path.dirname( 32 | os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) 33 | ) 34 | sys.path.append(import_path) 35 | 36 | python = sys.executable 37 | 38 | TIME_LIMIT = 30 39 | 40 | 41 | def run_opfuzz(first_config, second_config, directory, opts, timeout_limit): 42 | timeout = "timeout --signal=INT " + str(timeout_limit) + " " 43 | cmd = ( 44 | timeout 45 | + python 46 | + " bin/opfuzz " 47 | + '"' 48 | + first_config 49 | + ";" 50 | + second_config 51 | + '" ' 52 | + opts 53 | + " " 54 | + directory 55 | ) 56 | print(cmd, flush=True) 57 | output = subprocess.getoutput(cmd) 58 | return output, cmd 59 | 60 | 61 | def error(output): 62 | if "Traceback" in output: 63 | return True 64 | if "error" in output or "Error" in output: 65 | return True 66 | return False 67 | 68 | 69 | def get_cvc4(): 70 | cvc4_link = "https://github.com/CVC4/CVC4/releases/download/1.8/cvc4-1.8-x86_64-linux-opt" # noqa: E501 71 | subprocess.getoutput("wget " + cvc4_link) 72 | subprocess.getoutput("chmod +x cvc4-1.8-x86_64-linux-opt") 73 | return os.path.abspath("cvc4-1.8-x86_64-linux-opt") 74 | 75 | 76 | def get_z3(): 77 | z3_link = "https://github.com/Z3Prover/z3/releases/download/z3-4.8.10/z3-4.8.10-x64-ubuntu-18.04.zip" # noqa: E501 78 | subprocess.getoutput("wget " + z3_link) 79 | subprocess.getoutput("unzip z3-4.8.10-x64-ubuntu-18.04.zip") 80 | return os.path.abspath("z3-4.8.10-x64-ubuntu-18.04/bin/z3") 81 | 82 | 83 | def cleanup(): 84 | subprocess.getoutput("rm -rf cvc4*") 85 | subprocess.getoutput("rm -rf z3*") 86 | subprocess.getoutput("rm -rf QF_LIA") 87 | 88 | 89 | def get_dir(benchmark): 90 | if "incremental" in benchmark: 91 | return benchmark.split(" ")[-1] 92 | else: 93 | return benchmark.split("/")[-1].split(".")[0] 94 | 95 | 96 | # 1. Get SMT-LIB 2 benchmarks. 97 | cleanup() 98 | 99 | print("(1) Get SMT-LIB 2 benchmark", flush=True) 100 | cmd = "git clone https://clc-gitlab.cs.uiowa.edu:2443/SMT-LIB-benchmarks/QF_LIA.git" # noqa: E501 101 | print(cmd) 102 | subprocess.getoutput(cmd) 103 | print("-" * 100) 104 | 105 | print("(2) Get and build SMT solvers.", flush=True) 106 | z3 = get_z3() 107 | cvc4 = get_cvc4() 108 | print("-" * 100) 109 | 110 | print("(3) Run Yin-Yang on the benchmarks e.g. with Z3 and CVC4.", flush=True) 111 | first_config = z3 + " model_validate=true" 112 | second_config = cvc4 + " --check-models -m -i -q" 113 | output, cmd = run_opfuzz(first_config, second_config, "QF_LIA", "", TIME_LIMIT) 114 | print(output, flush=True) 115 | if error(output): 116 | print("An error occurred!") 117 | print("cmd=" + cmd) 118 | exit(1) 119 | cleanup() 120 | print("-" * 100) 121 | -------------------------------------------------------------------------------- /tests/integration/misc/mock_benchmarks/invalid.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun x () Int) 2 | (declare-fun w () Bool) 3 | (assert (= x (- 1 4 | (assert (= w (= x (- 1)))) 5 | (assert w) 6 | (check-sat) 7 | -------------------------------------------------------------------------------- /tests/integration/misc/mock_benchmarks/valid.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun x () Int) 2 | (declare-fun w () Bool) 3 | (assert (= x (- 1))) 4 | (assert (= w (= x (- 1)))) 5 | (assert w) 6 | (check-sat) 7 | -------------------------------------------------------------------------------- /tests/integration/misc/pypi.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | 3 | if ! pip uninstall -y antlr4-python3-runtime; then 4 | exit 1 5 | fi 6 | 7 | if ! pip install yinyang; then 8 | exit 1 9 | fi 10 | 11 | yinyang 12 | 13 | if [ $? -ne 2 ]; then 14 | exit 1 15 | fi 16 | 17 | opfuzz 18 | 19 | if [ $? -ne 2 ]; then 20 | exit 1 21 | fi 22 | 23 | typefuzz 24 | 25 | if [ $? -ne 2 ]; then 26 | exit 1 27 | fi 28 | 29 | sudo apt-get install -y cvc4 z3 30 | 31 | cd .. 32 | yinyang -o sat "z3 model_validate=true;cvc4 --check-models -m -i -q" yinyang/examples/phi1.smt2 yinyang/examples/phi2.smt2 33 | 34 | if [ $? -eq 3 ]; then 35 | exit 1 36 | fi 37 | 38 | opfuzz "z3 model_validate=true;cvc4 --check-models -m -i -q" yinyang/examples/phi1.smt2 39 | 40 | if [ $? -eq 3 ]; then 41 | exit 1 42 | fi 43 | 44 | typefuzz "z3 model_validate=true;cvc4 --check-models -m -i -q" yinyang/examples/phi1.smt2 45 | 46 | if [ $? -eq 3 ]; then 47 | exit 1 48 | fi 49 | -------------------------------------------------------------------------------- /tests/integration/opfuzz/SanityOpFuzz.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import subprocess 25 | import sys 26 | 27 | N = 300 28 | python = sys.executable 29 | 30 | 31 | def call_fuzzer(first_config, second_config, fn, opts): 32 | cmd = ( 33 | python 34 | + " bin/opfuzz " 35 | + '"' 36 | + first_config 37 | + ";" 38 | + second_config 39 | + '" ' 40 | + opts 41 | + " " 42 | + fn 43 | ) 44 | output = subprocess.getoutput(cmd) 45 | soundness_issues = 0 46 | crash_issues = 0 47 | for line in output.split("\n"): 48 | if "Detected soundness bug" in line: 49 | soundness_issues += 1 50 | if "Detected crash bug" in line or "Detected segfault": 51 | crash_issues += 1 52 | 53 | return soundness_issues, crash_issues, cmd 54 | 55 | 56 | def get_cvc4(): 57 | cvc4_link = ( 58 | "https://github.com/CVC4/CVC4/releases/download/1.7/" 59 | + "cvc4-1.7-x86_64-linux-opt" 60 | ) 61 | subprocess.getoutput("wget " + cvc4_link) 62 | subprocess.getoutput("chmod +x cvc4-1.7-x86_64-linux-opt") 63 | return os.path.abspath("cvc4-1.7-x86_64-linux-opt") 64 | 65 | 66 | def get_z3(): 67 | z3_link = ( 68 | "https://github.com/Z3Prover/z3/releases/download/z3-4.8.6/" 69 | + "z3-4.8.6-x64-ubuntu-16.04.zip" 70 | ) 71 | subprocess.getoutput("wget " + z3_link) 72 | subprocess.getoutput("unzip z3-4.8.6-x64-ubuntu-16.04.zip") 73 | return os.path.abspath("z3-4.8.6-x64-ubuntu-16.04/bin/z3") 74 | 75 | 76 | def cleanup(): 77 | subprocess.getoutput("rm -rf cvc4*") 78 | subprocess.getoutput("rm -rf z3*") 79 | 80 | 81 | cleanup() 82 | # 83 | # 1. download z3 and cvc4 84 | # 85 | print("Downloading solvers...") 86 | print("Get cvc4") 87 | cvc4 = get_cvc4() 88 | 89 | print("Get z3") 90 | z3 = get_z3() 91 | 92 | # 2. check whether bugs can be retriggered 93 | # 94 | first_config = cvc4 + " -q" 95 | second_config = cvc4 + " --sygus-inference -q" 96 | fn = "tests/integration/opfuzz/cvc4_wrong_3564_hidden.smt2" 97 | opts = "-i 1 -m 1" 98 | 99 | print("Trying to retrigger soundness bug...") 100 | bug_catched = False 101 | for _ in range(N): 102 | soundness_issues, crash_issues, cmd = call_fuzzer( 103 | first_config, second_config, fn, opts 104 | ) 105 | if soundness_issues == 1: 106 | bug_catched = True 107 | break 108 | 109 | if not bug_catched: 110 | print("[ERROR] Soundness bug could not be reproduced.") 111 | print(cmd) 112 | exit(1) 113 | 114 | first_config = z3 + " model_validate=true" 115 | second_config = cvc4 + " --incremental --produce-models -q" 116 | fn = "tests/integration/opfuzz/z3_invmodel_3118_hidden.smt2" 117 | opts = "-i 1 -m 1" 118 | 119 | print("Trying to retrigger invalid model bug...") 120 | bug_catched = False 121 | for _ in range(N): 122 | soundness_issues, crash_issues, cmd = call_fuzzer( 123 | first_config, second_config, fn, opts 124 | ) 125 | if crash_issues != 0: 126 | bug_catched = True 127 | break 128 | 129 | if not bug_catched: 130 | print("[ERROR] Invalid model bug could not be reproduced.") 131 | print(cmd) 132 | exit(1) 133 | 134 | first_config = z3 + " model_validate=true" 135 | second_config = cvc4 + " --incremental --produce-models -q" 136 | fn = "tests/integration/opfuzz/z3-segfault-3549.smt2" 137 | opts = "-i 1 -m 1" 138 | 139 | print("Trying to retrigger segfault...") 140 | bug_catched = False 141 | for _ in range(N): 142 | soundness_issues, crash_issues, cmd = call_fuzzer( 143 | first_config, second_config, fn, opts 144 | ) 145 | if crash_issues != 0: 146 | bug_catched = True 147 | break 148 | 149 | if not bug_catched: 150 | print("[ERROR] Crash bug could not be reproduced.") 151 | print(cmd) 152 | exit(1) 153 | 154 | cleanup() 155 | 156 | print("[SUCCESS] All bugs retriggered.") 157 | -------------------------------------------------------------------------------- /tests/integration/opfuzz/cvc4_wrong_3564_hidden.smt2: -------------------------------------------------------------------------------- 1 | ; Bug hidden by or -> and 2 | (assert (and (< 60.3 (exp 4.1) 60.4) (< (exp 5.1) 164.1))) 3 | (check-sat) 4 | -------------------------------------------------------------------------------- /tests/integration/opfuzz/z3-segfault-3549.smt2: -------------------------------------------------------------------------------- 1 | ; Bug hidden by distinct -> = 2 | (set-option :trace true) 3 | (declare-fun a () (_ FloatingPoint 11 53)) 4 | (declare-fun b () (_ FloatingPoint 8 24)) 5 | (assert (= b ((_ to_fp 8 24) RTP a))) 6 | (check-sat) 7 | -------------------------------------------------------------------------------- /tests/integration/opfuzz/z3_invmodel_3118_hidden.smt2: -------------------------------------------------------------------------------- 1 | ; Bug hidden by = -> distinct 2 | (declare-fun a () Int) 3 | (declare-fun b () Real) 4 | (declare-fun c () Real) 5 | (assert (> a 0)) 6 | (assert (distinct (* (/ b b) c) 2.0)) 7 | (check-sat) 8 | (check-sat) 9 | (get-model) 10 | -------------------------------------------------------------------------------- /tests/integration/parsing/ast/Ast.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | 25 | from antlr4.CommonTokenStream import FileStream, CommonTokenStream 26 | 27 | from yinyang.src.parsing.SMTLIBv2Lexer import SMTLIBv2Lexer 28 | from yinyang.src.parsing.SMTLIBv2Parser import SMTLIBv2Parser 29 | from yinyang.src.parsing.AstVisitor import AstVisitor 30 | from yinyang.src.parsing.Parse import parse_file 31 | 32 | sys.setrecursionlimit(100000) 33 | sys.path.append("../../../../") 34 | 35 | 36 | def ast_gen(fn): 37 | istream = FileStream(fn, encoding="utf8") 38 | lexer = SMTLIBv2Lexer(istream) 39 | stream = CommonTokenStream(lexer) 40 | parser = SMTLIBv2Parser(stream) 41 | tree = parser.start() 42 | vis = AstVisitor() 43 | script = vis.visitStart(tree) 44 | return script 45 | 46 | 47 | if __name__ == "__main__": 48 | if len(sys.argv) != 2: 49 | print("Usage: ./ast.py ") 50 | exit(0) 51 | fn = sys.argv[1] 52 | try: 53 | parse_file(fn, silent=False) 54 | except Exception as e: 55 | print(e) 56 | exit(1) 57 | -------------------------------------------------------------------------------- /tests/integration/parsing/ast/CheckOutput.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | # additional requirements: racket 24 | 25 | import sys 26 | import random 27 | import string 28 | import subprocess as sp 29 | import os 30 | 31 | from antlr4.CommonTokenStream import FileStream, CommonTokenStream 32 | 33 | from yinyang.src.parsing.SMTLIBv2Lexer import SMTLIBv2Lexer 34 | from yinyang.src.parsing.SMTLIBv2Parser import SMTLIBv2Parser 35 | from yinyang.src.parsing.AstVisitor import AstVisitor 36 | 37 | 38 | sys.setrecursionlimit(100000) 39 | sys.path.append("../../") 40 | 41 | 42 | def random_string(length=5): 43 | return "".join(random.sample(string.ascii_letters + string.digits, length)) 44 | 45 | 46 | def ast_gen(fn): 47 | istream = FileStream(fn, encoding="utf8") 48 | lexer = SMTLIBv2Lexer(istream) 49 | stream = CommonTokenStream(lexer) 50 | parser = SMTLIBv2Parser(stream) 51 | tree = parser.start() 52 | vis = AstVisitor() 53 | script = vis.visitStart(tree) 54 | return script 55 | 56 | 57 | def show_diff(inp, parsed): 58 | with open("input.smt2", "w") as f: 59 | f.write(inp) 60 | 61 | with open("parsed.smt2", "w") as f: 62 | f.write(parsed) 63 | 64 | 65 | if __name__ == "__main__": 66 | if len(sys.argv) != 2: 67 | print("Usage: ./check_output.py ") 68 | exit(0) 69 | fn = sys.argv[1] 70 | parsed_fn = random_string() + ".smt2" 71 | with open(parsed_fn, "w") as f: 72 | f.write(ast_gen(fn).__str__()) 73 | cmd = "raco read " + parsed_fn 74 | parsed = sp.getoutput(cmd) 75 | cmd = "raco read " + fn 76 | inp = sp.getoutput(cmd) 77 | os.system("rm -rf " + parsed_fn) 78 | if inp == parsed: 79 | exit(0) 80 | show_diff(inp, parsed) 81 | exit(1) 82 | -------------------------------------------------------------------------------- /tests/integration/parsing/ast/Run.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | import subprocess as sp 26 | from multiprocessing import Pool 27 | 28 | sys.path.append("../../") 29 | 30 | os.system("rm -rf errors.txt timeouts.txt") 31 | BENCHMARK = "/local/disk1/dominik-exp/yinyang/benchmarks" 32 | 33 | N = 128 34 | 35 | 36 | def do_comparison(fn): 37 | if not os.path.exists(fn): 38 | os.system("rm -rf " + fn) 39 | cmd = "timeout -s 9 5 python3.7 check_output.py " + fn + "; echo $?" 40 | out = sp.getoutput(cmd) 41 | if "137" in out: 42 | return 137 43 | if "1" in out: 44 | return 1 45 | return 0 46 | 47 | 48 | def collect(res, files): 49 | errs, timeouts = [], [] 50 | for i in range(len(res)): 51 | if res[i] == 1: 52 | errs.append(files[i]) 53 | if res[i] == 137: 54 | timeouts.append(files[i]) 55 | return errs, timeouts 56 | 57 | 58 | def append_to_file(fn, line): 59 | flag = "a" 60 | if not os.path.exists(fn): 61 | flag = "w" 62 | with open(fn, flag) as f: 63 | f.write("\n".join(line)) 64 | 65 | 66 | files = sp.getoutput("find " + BENCHMARK + ' -name "*.smt2"').split("\n") 67 | print(files) 68 | batch_size = 100 69 | n = len(files) // batch_size 70 | n_err = 0 71 | n_timeout = 0 72 | with Pool(N) as p: 73 | for i in range(n): 74 | res = p.map( 75 | do_comparison, files[i * batch_size: (i + 1) * batch_size]) 76 | e, t = collect(res, files[i * batch_size: (i + 1) * batch_size]) 77 | n_err += len(e) 78 | n_timeout += len(t) 79 | append_to_file("errors.txt", e) 80 | append_to_file("timeouts.txt", t) 81 | print( 82 | (i + 1) * batch_size, 83 | "/", 84 | len(files), 85 | "err=", 86 | n_err, 87 | "timeouts=", 88 | n_timeout, 89 | flush=True, 90 | ) 91 | -------------------------------------------------------------------------------- /tests/integration/parsing/parser/Parse.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | 25 | from antlr4.CommonTokenStream import CommonTokenStream, FileStream 26 | from yinyang.src.parsing.SMTLIBv2Lexer import SMTLIBv2Lexer 27 | from yinyang.src.parsing.SMTLIBv2Parser import SMTLIBv2Parser 28 | 29 | sys.setrecursionlimit(100000) 30 | sys.path.append("../../") 31 | 32 | 33 | def antlr_parsing(fn): 34 | istream = FileStream(fn, encoding="utf8") 35 | lexer = SMTLIBv2Lexer(istream) 36 | stream = CommonTokenStream(lexer) 37 | parser = SMTLIBv2Parser(stream) 38 | parser.start() 39 | 40 | 41 | if __name__ == "__main__": 42 | if len(sys.argv) != 2: 43 | print("Usage: ./parse.py ") 44 | exit(0) 45 | fn = sys.argv[1] 46 | try: 47 | antlr_parsing(fn) 48 | except Exception as e: 49 | print(e) 50 | exit(1) 51 | -------------------------------------------------------------------------------- /tests/integration/parsing/parser/Run.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | import subprocess as sp 25 | import os 26 | from multiprocessing import Pool 27 | 28 | sys.path.append("../../") 29 | os.system("rm -rf errors.txt timeouts.txt") 30 | BENCHMARK = "/local/disk1/dominik-exp/benchmarks/" 31 | 32 | N = 128 33 | 34 | 35 | def do_parsing(fn): 36 | if not os.path.exists(fn): 37 | os.system("rm -rf " + fn) 38 | cmd = "timeout -s 9 1 python3.7 parse.py " + fn + ";echo $?" 39 | out = sp.getoutput(cmd) 40 | 41 | # To suppress debug related issues 42 | if "dbg" in out: 43 | return 0 44 | 45 | if "137" in out: 46 | return 137 47 | if "error" in out or len(out) > 3: 48 | print(fn) 49 | print(out) 50 | return 1 51 | if "1" in out: 52 | print(fn) 53 | print(out) 54 | return 1 55 | return 0 56 | 57 | 58 | def collect(res, files): 59 | errs, timeouts = [], [] 60 | for i in range(len(res)): 61 | if res[i] == 1: 62 | errs.append(files[i]) 63 | if res[i] == 137: 64 | timeouts.append(files[i]) 65 | return errs, timeouts 66 | 67 | 68 | def append_to_file(fn, line): 69 | flag = "a" 70 | if not os.path.exists(fn): 71 | flag = "w" 72 | with open(fn, flag) as f: 73 | f.write("\n".join(line)) 74 | 75 | 76 | files = sp.getoutput("find " + BENCHMARK + ' -name "*.smt2"').split("\n") 77 | # files = [f[:-1] for f in open("sorted_errors.txt").readlines()] 78 | batch_size = 100 79 | n = len(files) // batch_size 80 | n_err = 0 81 | n_timeout = 0 82 | with Pool(N) as p: 83 | for i in range(n): 84 | res = p.map(do_parsing, files[i * batch_size: (i + 1) * batch_size]) 85 | e, t = collect(res, files[i * batch_size: (i + 1) * batch_size]) 86 | n_err += len(e) 87 | n_timeout += len(t) 88 | append_to_file("errors.txt", e) 89 | append_to_file("timeouts.txt", t) 90 | print( 91 | (i + 1) * batch_size, "/", 92 | len(files), "err=", n_err, "timeouts=", n_timeout 93 | ) 94 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/37315_issue-1694.smt2: -------------------------------------------------------------------------------- 1 | ; Copyright (c) 2016 Microsoft Corporation 2 | 3 | (declare-const x Real) 4 | (assert (< x 1.0)) 5 | (assert (forall ((y Real)) (or (< y 0.0) (> y 0.1) (> x (* y y))))) 6 | (check-sat) 7 | (exit) 8 | 9 | (assert (not (forall ((x Real)) 10 | (=> (< x 1.0) 11 | (exists ((y Real)) 12 | (and (>= y 0.0) (<= y 0.1) (<= x (* y y)))))))) 13 | (check-sat) 14 | (exit) 15 | 16 | (assert (forall ((x Real)) 17 | (=> (< x 1.0) 18 | (exists ((y Real)) 19 | (and (>= y 0.0) (<= y 0.1) (<= x (* y y))))))) 20 | (check-sat) -------------------------------------------------------------------------------- /tests/integration/semanticfusion/5jby0_z3_bug_incorrect_script1.smt2: -------------------------------------------------------------------------------- 1 | (declare-const x String) 2 | (declare-const y String) 3 | (declare-const m String) 4 | (declare-const n String) 5 | (assert (str.in.re x (re.union (str.to.re "b") (re.* (str.to.re "a"))))) 6 | (assert (str.in.re x (re.union (str.to.re "a") (re.+ (str.to.re ""))))) 7 | (assert (str.in.re x (re.++ (re.+ (str.to.re "")) (re.* (re.++ (str.to.re "L") (str.to.re "g")))))) 8 | (check-sat) 9 | (get-model) 10 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/5jby0_z3_bug_incorrect_script2.smt2: -------------------------------------------------------------------------------- 1 | (declare-const x String) 2 | (declare-const y String) 3 | (declare-const m String) 4 | (declare-const n String) 5 | (assert (= (str.++ x y) (str.++ m n))) 6 | (assert (str.in.re n (re.* (str.to.re "_o|'\t'}RC+:'\t'\\^S_c")))) 7 | (assert (> (str.to.int x) (str.len m))) 8 | (check-sat) 9 | (get-model) 10 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/SanitySemanticFusion.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | import subprocess 26 | 27 | N = 2 28 | python = sys.executable 29 | 30 | 31 | def call_fuzzer(first_config, fn, opts): 32 | cmd = python + " bin/yinyang "\ 33 | + '"' + first_config + '" ' + opts + " " + fn 34 | print(cmd) 35 | output = subprocess.getoutput(cmd) 36 | print(output) 37 | soundness_issues = 0 38 | crash_issues = 0 39 | for line in output.split("\n"): 40 | if "soundness" in line: 41 | soundness_issues += 1 42 | if "crash" in line or "invalid model" in line: 43 | crash_issues += 1 44 | 45 | return soundness_issues, crash_issues, cmd 46 | 47 | 48 | def get_z3(): 49 | z3_link = ( 50 | "https://github.com/Z3Prover/z3/releases/download/z3-4.8.6/" 51 | + "z3-4.8.6-x64-ubuntu-16.04.zip" 52 | ) 53 | subprocess.getoutput("wget " + z3_link) 54 | subprocess.getoutput("unzip z3-4.8.6-x64-ubuntu-16.04.zip") 55 | return os.path.abspath("z3-4.8.6-x64-ubuntu-16.04/bin/z3") 56 | 57 | 58 | def get_cvc4(): 59 | cvc4_link = ( 60 | "http://cvc4.cs.stanford.edu/downloads/builds/" 61 | + "x86_64-linux-opt/cvc4-1.6-x86_64-linux-opt" 62 | ) 63 | subprocess.getoutput("wget " + cvc4_link) 64 | subprocess.getoutput("chmod +x cvc4-1.6-x86_64-linux-opt") 65 | return os.path.abspath("cvc4-1.6-x86_64-linux-opt") 66 | 67 | 68 | def cleanup(): 69 | subprocess.getoutput("rm -rf z3*") 70 | subprocess.getoutput("rm -rf cvc4*") 71 | 72 | 73 | cleanup() 74 | # 75 | # 1. download z3 and cvc4 76 | # 77 | print("Downloading solvers...") 78 | print("Get z3") 79 | z3 = get_z3() 80 | 81 | print("Get cvc4") 82 | cvc4 = get_cvc4() 83 | 84 | # 2. ensure no soundness bugs in Semantic Fusion. 85 | # 86 | first_config = z3 87 | fn = "tests/integration/semanticfusion/intersection-example-simple.proof-node75884.smt2 tests/integration/semanticfusion/water_tank-node5020.smt2" # noqa: E501 88 | opts = "-o unsat -s fusion -k" 89 | 90 | print("Trying to sanitize unsat fusion...") 91 | bug_catched = False 92 | for _ in range(N): 93 | soundness_issues, crash_issues, cmd = call_fuzzer(first_config, fn, opts) 94 | if soundness_issues != 0 or crash_issues != 0: 95 | bug_catched = True 96 | break 97 | 98 | if bug_catched: 99 | print("[ERROR] Unexpected bugs found.") 100 | print(cmd) 101 | exit(1) 102 | 103 | first_config = z3 104 | fn = "tests/integration/semanticfusion/37315_issue-1694.smt2 tests/integration/semanticfusion/37315_issue-1694.smt2" # noqa: E501 105 | opts = "-o sat -s fusion -k" 106 | 107 | print("Trying to sanitize sat fusion...") 108 | bug_catched = False 109 | for _ in range(N): 110 | soundness_issues, crash_issues, cmd = call_fuzzer(first_config, fn, opts) 111 | if soundness_issues != 0 or crash_issues != 0: 112 | bug_catched = True 113 | break 114 | 115 | if bug_catched: 116 | print("[ERROR] Unexpected bugs found.") 117 | print(cmd) 118 | exit(1) 119 | 120 | 121 | # 3. retrigger bug with unsat fusion 122 | # 123 | print("Trying to retrigger bug with unsat fusion...") 124 | first_config = cvc4 + " --strings-exp -q" 125 | fn = "tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script1.smt2 tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script2.smt2" # noqa: E501 126 | opts = "-o unsat -s fusion -k" 127 | 128 | for _ in range(1000): 129 | soundness_issues, crash_issues, cmd = call_fuzzer(first_config, fn, opts) 130 | if soundness_issues != 0: 131 | bug_catched = True 132 | break 133 | 134 | if not bug_catched: 135 | print("[ERROR] Bug not found by unsat fusion.") 136 | print(cmd) 137 | exit(1) 138 | 139 | # 4. retrigger bug with sat fusion 140 | # 141 | print("Trying to retrigger bug with sat fusion...") 142 | first_config = z3 143 | fn = "tests/integration/semanticfusion/5jby0_z3_bug_incorrect_script1.smt2 tests/integration/semanticfusion/5jby0_z3_bug_incorrect_script2.smt2" # noqa: E501 144 | opts = "-o sat -s fusion -k" 145 | 146 | for _ in range(1000): 147 | soundness_issues, crash_issues, cmd = call_fuzzer(first_config, fn, opts) 148 | if soundness_issues != 0: 149 | bug_catched = True 150 | break 151 | 152 | if not bug_catched: 153 | print("[ERROR] Bug not found by sat fusion.") 154 | print(cmd) 155 | exit(1) 156 | 157 | cleanup() 158 | 159 | print("[SUCCESS] All sanitizer passed.") 160 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script1.smt2: -------------------------------------------------------------------------------- 1 | (set-info :smt-lib-version 2.6) 2 | (set-logic QF_SLIA) 3 | (set-info :source | 4 | Generated by: Andres Noetzli, Andrew Reynolds, Haniel Barbosa, Aina Niemetz, Mathias Preiner, Clark Barrett, Cesare Tinelli 5 | Generated on: 2018-11-08 6 | Generator: CVC4 7 | Application: Rewrite rule verification 8 | Publications: "Syntax-Guided Rewrite Rule Enumeration for SMT Solvers" by A. Noetzli, A. Reynolds, H. Barbosa, A. Niemetz, M. Preiner, C. Barrett, and C. Tinelli, SAT 2019. 9 | |) 10 | (set-info :license "https://creativecommons.org/licenses/by/4.0/") 11 | (set-info :category "industrial") 12 | (set-info :status unknown) 13 | (declare-fun x () String) 14 | (declare-fun y () String) 15 | (declare-fun z () Int) 16 | (assert (not (= ( str.replace "B" ( str.at "A" z) "") "B"))) 17 | (check-sat) 18 | (exit) 19 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/gIxXB_cvc4_bug_incorrect_script2.smt2: -------------------------------------------------------------------------------- 1 | (set-info :smt-lib-version 2.6) 2 | (set-logic QF_SLIA) 3 | (set-info :source | 4 | Generated by: Andres Noetzli, Andrew Reynolds, Haniel Barbosa, Aina Niemetz, Mathias Preiner, Clark Barrett, Cesare Tinelli 5 | Generated on: 2018-11-08 6 | Generator: CVC4 7 | Application: Rewrite rule verification 8 | Publications: "Syntax-Guided Rewrite Rule Enumeration for SMT Solvers" by A. Noetzli, A. Reynolds, H. Barbosa, A. Niemetz, M. Preiner, C. Barrett, and C. Tinelli, SAT 2019. 9 | |) 10 | (set-info :license "https://creativecommons.org/licenses/by/4.0/") 11 | (set-info :category "industrial") 12 | (set-info :status unknown) 13 | (declare-fun x () String) 14 | (declare-fun y () String) 15 | (declare-fun z () Int) 16 | (assert (not (= ( str.replace "B" ( str.replace "B" x "") "") ( str.at x ( str.indexof "B" x 0))))) 17 | (check-sat) 18 | (exit) 19 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/intersection-example-simple.proof-node75884.smt2: -------------------------------------------------------------------------------- 1 | (set-info :smt-lib-version 2.6) 2 | (set-logic NRA) 3 | (set-info :source | 4 | These benchmarks used in the paper: 5 | 6 | Dejan Jovanovic and Leonardo de Moura. Solving Non-Linear Arithmetic. 7 | In IJCAR 2012, published as LNCS volume 7364, pp. 339--354. 8 | 9 | The keymaera family contains VCs from Keymaera verification, see: 10 | 11 | A. Platzer, J.-D. Quesel, and P. Rummer. Real world verification. 12 | In CADE 2009, pages 485-501. Springer, 2009. 13 | 14 | Submitted by Dejan Jovanovic for SMT-LIB. 15 | 16 | KeYmaera example: intersection-example-simple.proof, node 75884 For more info see: @see "Sarah M. Loos and Andre Platzer. Safe intersections: At the crossing of hybrid systems and verification. In Kyongsu Yi, editor, 14th International IEEE Conference on Intelligent Transportation Systems, ITSC 2011, Washington, DC, USA, Proceedings. 2011." 17 | |) 18 | (set-info :category "industrial") 19 | (set-info :status unsat) 20 | (declare-fun v1 () Real) 21 | (declare-fun t349uscore0 () Real) 22 | (declare-fun A () Real) 23 | (declare-fun B () Real) 24 | (declare-fun v2 () Real) 25 | (declare-fun v1uscore1dollarskuscore339 () Real) 26 | (declare-fun I1uscore1dollarskuscore339 () Real) 27 | (declare-fun I1 () Real) 28 | (declare-fun I2 () Real) 29 | (declare-fun I2uscore1dollarskuscore339 () Real) 30 | (declare-fun x2 () Real) 31 | (declare-fun v2uscore1dollarskuscore339 () Real) 32 | (declare-fun x1 () Real) 33 | (declare-fun xI1 () Real) 34 | (declare-fun V () Real) 35 | (declare-fun xI2 () Real) 36 | (declare-fun ts349uscore0 () Real) 37 | (declare-fun ep () Real) 38 | (assert (not (exists ((ts349uscore0 Real)) (let ((?v_1 (= I1uscore1dollarskuscore339 2)) (?v_0 (+ (* (* (- 1) B) ts349uscore0) v2uscore1dollarskuscore339))) (=> (and (and (and (and (and (and (and (and (and (and (and (and (and (and (= v1uscore1dollarskuscore339 V) (= I1uscore1dollarskuscore339 0)) ?v_1) (= I1 2)) (< xI1 x1)) (= I2 2)) (< xI2 x2)) (> B 0)) (>= v1 0)) (<= v1 V)) (>= v2 0)) (<= v2 V)) (>= A 0)) (> V 0)) (> ep 0)) (=> (>= t349uscore0 0) (=> (=> (and (<= 0 ts349uscore0) (<= ts349uscore0 t349uscore0)) (and (and (and (and (>= v1uscore1dollarskuscore339 0) (<= v1uscore1dollarskuscore339 V)) (>= ?v_0 0)) (<= ?v_0 V)) (<= (+ ts349uscore0 0) ep))) (or ?v_1 (= I2uscore1dollarskuscore339 2))))))))) 39 | (check-sat) 40 | (exit) 41 | -------------------------------------------------------------------------------- /tests/integration/semanticfusion/water_tank-node5020.smt2: -------------------------------------------------------------------------------- 1 | (set-info :smt-lib-version 2.6) 2 | (set-logic LRA) 3 | (set-info :source | 4 | These benchmarks used in the paper: 5 | 6 | Dejan Jovanovic and Leonardo de Moura. Solving Non-Linear Arithmetic. 7 | In IJCAR 2012, published as LNCS volume 7364, pp. 339--354. 8 | 9 | The keymaera family contains VCs from Keymaera verification, see: 10 | 11 | A. Platzer, J.-D. Quesel, and P. Rummer. Real world verification. 12 | In CADE 2009, pages 485-501. Springer, 2009. 13 | 14 | Submitted by Dejan Jovanovic for SMT-LIB. 15 | 16 | KeYmaera example: water_tank, node 5020 For more info see: No further information available. 17 | |) 18 | (set-info :category "industrial") 19 | (set-info :status unsat) 20 | (declare-fun stuscore2dollarskuscore2 () Real) 21 | (declare-fun t1uscore0dollarskuscore1 () Real) 22 | (declare-fun yuscore2dollarskuscore2 () Real) 23 | (declare-fun ts1uscore1 () Real) 24 | (assert (not (exists ((ts1uscore1 Real)) (=> (and (and (and (and (and (=> (and (<= 0 ts1uscore1) (<= ts1uscore1 t1uscore0dollarskuscore1)) (<= (+ ts1uscore1 yuscore2dollarskuscore2) 10)) (>= t1uscore0dollarskuscore1 0)) (< yuscore2dollarskuscore2 10)) (= stuscore2dollarskuscore2 0)) (>= yuscore2dollarskuscore2 1)) (<= yuscore2dollarskuscore2 12)) (or (or (= stuscore2dollarskuscore2 1) (= stuscore2dollarskuscore2 3)) (<= (+ t1uscore0dollarskuscore1 yuscore2dollarskuscore2) 12)))))) 25 | (check-sat) 26 | (exit) 27 | -------------------------------------------------------------------------------- /tests/integration/typefuzz/BasicUsage.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | """ 24 | Integration test for usage part in README.md. 25 | """ 26 | import os 27 | import sys 28 | import subprocess 29 | 30 | import_path = os.path.dirname( 31 | os.path.dirname( 32 | os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) 33 | ) 34 | sys.path.append(import_path) 35 | 36 | python = sys.executable 37 | 38 | TIME_LIMIT = 30 39 | 40 | 41 | def run_opfuzz(first_config, second_config, directory, opts, timeout_limit): 42 | timeout = "timeout --signal=INT " + str(timeout_limit) + " " 43 | cmd = ( 44 | timeout 45 | + python 46 | + " bin/typefuzz " 47 | + '"' 48 | + first_config 49 | + ";" 50 | + second_config 51 | + '" ' 52 | + opts 53 | + " " 54 | + directory 55 | ) 56 | print(cmd, flush=True) 57 | output = subprocess.getoutput(cmd) 58 | return output, cmd 59 | 60 | 61 | def error(output): 62 | if "Traceback" in output: 63 | return True 64 | if "error" in output or "Error" in output: 65 | return True 66 | return False 67 | 68 | 69 | def get_cvc4(): 70 | cvc4_link = "https://github.com/CVC4/CVC4/releases/download/1.8/cvc4-1.8-x86_64-linux-opt" # noqa: E501 71 | subprocess.getoutput("wget " + cvc4_link) 72 | subprocess.getoutput("chmod +x cvc4-1.8-x86_64-linux-opt") 73 | return os.path.abspath("cvc4-1.8-x86_64-linux-opt") 74 | 75 | 76 | def get_z3(): 77 | z3_link = "https://github.com/Z3Prover/z3/releases/download/z3-4.8.10/z3-4.8.10-x64-ubuntu-18.04.zip" # noqa: E501 78 | subprocess.getoutput("wget " + z3_link) 79 | subprocess.getoutput("unzip z3-4.8.10-x64-ubuntu-18.04.zip") 80 | return os.path.abspath("z3-4.8.10-x64-ubuntu-18.04/bin/z3") 81 | 82 | 83 | def cleanup(): 84 | subprocess.getoutput("rm -rf cvc4*") 85 | subprocess.getoutput("rm -rf z3*") 86 | 87 | 88 | def get_dir(benchmark): 89 | if "incremental" in benchmark: 90 | return benchmark.split(" ")[-1] 91 | else: 92 | return benchmark.split("/")[-1].split(".")[0] 93 | 94 | 95 | cleanup() 96 | 97 | print("Getting solvers...") 98 | z3 = get_z3() 99 | cvc4 = get_cvc4() 100 | 101 | print("Running TypeFuzz for 30 secs...") 102 | 103 | first_config = z3 + " model_validate=true" 104 | second_config = cvc4 + " --check-models -m -i -q" 105 | output, cmd = run_opfuzz( 106 | first_config, second_config, "examples", "", TIME_LIMIT) 107 | print(output, flush=True) 108 | if error(output): 109 | print("An error occurred!") 110 | print("cmd=" + cmd) 111 | exit(1) 112 | cleanup() 113 | print("-" * 100) 114 | -------------------------------------------------------------------------------- /tests/integration/typefuzz/SanityTypeFuzz.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | import subprocess 26 | 27 | python = sys.executable 28 | 29 | 30 | def call_fuzzer(first_config, second_config, fn, opts): 31 | cmd = ( 32 | "timeout -s 9 1 " 33 | + python 34 | + " bin/typefuzz " 35 | + '"' 36 | + first_config 37 | + ";" 38 | + second_config 39 | + '" ' 40 | + opts 41 | + " " 42 | + fn 43 | ) 44 | print(cmd) 45 | output = subprocess.getoutput(cmd) 46 | print(output) 47 | soundness_issues = 0 48 | crash_issues = 0 49 | for line in output.split("\n"): 50 | if "Detected soundness bug" in line: 51 | soundness_issues += 1 52 | if "Detected crash bug" in line or "Detected segfault": 53 | crash_issues += 1 54 | 55 | return soundness_issues, crash_issues, cmd 56 | 57 | 58 | def get_cvc4_1_8(): 59 | cvc4_link = ( 60 | "https://github.com/CVC4/CVC4/releases/download/1.8/" 61 | + "cvc4-1.8-x86_64-linux-opt" 62 | ) 63 | subprocess.getoutput("wget " + cvc4_link) 64 | subprocess.getoutput("chmod +x cvc4-1.8-x86_64-linux-opt") 65 | return os.path.abspath("cvc4-1.8-x86_64-linux-opt") 66 | 67 | 68 | def get_z3_4_8_6(): 69 | z3_link = ( 70 | "https://github.com/Z3Prover/z3/releases/download/z3-4.8.6/" 71 | + "z3-4.8.6-x64-ubuntu-16.04.zip" 72 | ) 73 | subprocess.getoutput("wget " + z3_link) 74 | subprocess.getoutput("unzip z3-4.8.6-x64-ubuntu-16.04.zip") 75 | return os.path.abspath("z3-4.8.6-x64-ubuntu-16.04/bin/z3") 76 | 77 | 78 | def execute(cmd): 79 | print(cmd, flush=True) 80 | out = os.system(cmd) 81 | 82 | 83 | def get_z3_trunk(commit_id): 84 | execute("git clone https://github.com/Z3Prover/z3.git " + commit_id) 85 | cmd = ("cd " + commit_id + ";" 86 | + "git checkout " + commit_id + ";" 87 | + "./configure;" 88 | + "cd build;" 89 | + "make -j 10;" 90 | + "mv z3 ../../z3-" + commit_id) 91 | execute(cmd) 92 | return os.path.abspath("z3-" + commit_id) 93 | 94 | 95 | def get_cvc4_trunk(commit_id): 96 | execute("git clone https://github.com/cvc5/cvc5 " + commit_id) 97 | cmd = ("cd " + commit_id + ";" 98 | + "git checkout " + commit_id + ";" 99 | + "./contrib/get-antlr-3.4; ./configure.sh " 100 | + "--static production --assertions --symfpu; cd build;" 101 | + "make -j 10;" 102 | + "mv bin/cvc4 ../../cvc4-" + commit_id) 103 | execute(cmd) 104 | return os.path.abspath("cvc4-" + commit_id) 105 | 106 | 107 | def cleanup(): 108 | subprocess.getoutput("rm -rf cvc4*") 109 | subprocess.getoutput("rm -rf z3*") 110 | 111 | 112 | cvc4 = get_cvc4_1_8() 113 | z3 = get_z3_trunk("d0515dc") 114 | 115 | first_config = z3 116 | second_config = cvc4 + " --strings-exp -q" 117 | fn = "examples/seed27.smt2" 118 | opts = "-i 1 -c examples/c27.txt" 119 | 120 | print("Trying to retrigger soundness bug...", flush=True) 121 | 122 | bug_catched = False 123 | for _ in range(400): 124 | soundness_issues, crash_issues, cmd = call_fuzzer( 125 | first_config, second_config, fn, opts 126 | ) 127 | if soundness_issues == 1: 128 | bug_catched = True 129 | break 130 | 131 | if not bug_catched: 132 | print("[ERROR] Soundness bug could not be reproduced.") 133 | print(cmd) 134 | exit(1) 135 | -------------------------------------------------------------------------------- /tests/regression/issue42.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | import glob 26 | import subprocess 27 | 28 | python = sys.executable 29 | 30 | 31 | def call_fuzzer(first_config, fn, opts): 32 | cmd = python + " bin/yinyang "\ 33 | + '"' + first_config + '" ' + opts + " " + fn 34 | print(cmd) 35 | output = subprocess.getoutput(cmd) 36 | 37 | 38 | def cleanup(): 39 | subprocess.getoutput("rm -rf z3*") 40 | subprocess.getoutput("rm -rf logs") 41 | 42 | 43 | def get_z3(): 44 | z3_link = ( 45 | "https://github.com/Z3Prover/z3/releases/download/z3-4.8.6/" 46 | + "z3-4.8.6-x64-ubuntu-16.04.zip" 47 | ) 48 | os.system("wget " + z3_link) 49 | os.system("unzip z3-4.8.6-x64-ubuntu-16.04.zip") 50 | return os.path.abspath("z3-4.8.6-x64-ubuntu-16.04/bin/z3") 51 | 52 | 53 | cleanup() 54 | print("Download Z3") 55 | z3 = get_z3() 56 | print("Call fuzzer") 57 | call_fuzzer(z3, "tests/regression/53.smt2 tests/regression/55.smt2", "-o sat") 58 | 59 | logfile = glob.glob("logs/*")[0] 60 | if "Invalid mutant:ignore_list" in open(logfile).read(): 61 | exit(1) 62 | -------------------------------------------------------------------------------- /tests/regression/scoping_bug.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | 25 | sys.path.append("../../") 26 | 27 | from yinyang.src.parsing.Parse import parse_str 28 | 29 | script, _ = parse_str("""\ 30 | (declare-fun t () String) 31 | (declare-fun t1 () String) 32 | (declare-fun t2 () String) 33 | (assert (forall ((t1 String) (t2 String))(=> (= (str.++ t1 t2) t) 34 | (= (= t1 s) false)))) 35 | (check-sat)""") 36 | script.prefix_vars("scr1_") 37 | assert ("(str.++ t1 t2)" in script.__str__()) 38 | -------------------------------------------------------------------------------- /tests/res/formula1.smt2: -------------------------------------------------------------------------------- 1 | (declare-const x Int) 2 | (assert (= x (- 1))) 3 | (check-sat) 4 | -------------------------------------------------------------------------------- /tests/res/formula2.smt2: -------------------------------------------------------------------------------- 1 | (declare-const y Int) 2 | (declare-const v Bool) 3 | (assert (= v (not (= y (- 1))))) 4 | (assert (ite v false (= y (- 1)))) 5 | (check-sat) 6 | -------------------------------------------------------------------------------- /tests/res/formula_file.smt2: -------------------------------------------------------------------------------- 1 | (declare-const x Int) 2 | (declare-const y Int) 3 | (declare-const w Bool) 4 | (assert (= x (- x))) 5 | (assert (distinct w (= x (- y)))) 6 | (assert w) 7 | (check-sat) 8 | -------------------------------------------------------------------------------- /tests/res/fusion_functions.txt: -------------------------------------------------------------------------------- 1 | #begin 2 | (declare-const x Int) 3 | (declare-const y Int) 4 | (declare-const z Int) 5 | (declare-const c Int) 6 | (assert (= z (+ x c) y)) 7 | (assert (= x (- (- z c) y))) 8 | (assert (= y (- (- z c) x))) 9 | #end 10 | -------------------------------------------------------------------------------- /tests/res/issue18.smt2: -------------------------------------------------------------------------------- 1 | (declare-fun a () String) 2 | (declare-fun b () String) 3 | (assert (= a b)) 4 | (check-sat) 5 | (simplify (= a b)) 6 | (simplify (str.++ a b)) 7 | (assert (= a b)) 8 | (check-sat) 9 | (get-model) 10 | -------------------------------------------------------------------------------- /tests/res/issue7.smt2: -------------------------------------------------------------------------------- 1 | (define-const a String "\x0a") 2 | (define-const c String "\n") 3 | (simplify (= a b)) 4 | (simplify (str.++ a b)) 5 | (check-sat) 6 | -------------------------------------------------------------------------------- /tests/res/operators.txt: -------------------------------------------------------------------------------- 1 | =,distinct 2 | exists,forall 3 | and,or,=> 4 | <=, >=,<,> 5 | +,-,*,/ :arity 2+ 6 | div,mod 7 | -------------------------------------------------------------------------------- /tests/unit/TestGenTypeAwareMutation.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import unittest 24 | import sys 25 | 26 | sys.path.append("../../") 27 | import os 28 | 29 | from yinyang.src.parsing.Parse import * 30 | from yinyang.src.parsing.Typechecker import Context, typecheck 31 | from yinyang.src.mutators.GenTypeAwareMutation.GenTypeAwareMutation import * 32 | from yinyang.src.mutators.GenTypeAwareMutation.Util import * 33 | 34 | 35 | class Mockargs: 36 | modulo = 3 37 | config = "yinyang/config/typefuzz_config.txt" 38 | 39 | 40 | class GenTypeAwareMutationTestCase(unittest.TestCase): 41 | def test_ta(self): 42 | formulafile = "formula.smt2" 43 | formula = """ 44 | (declare-fun x () Int) 45 | (declare-fun y () Int) 46 | (declare-fun z () Int) 47 | (assert (> (* (+ 3 x) (- y 2)) (div 5 z))) 48 | (assert (= (+ 7 y) x)) 49 | (assert (< 6 (div (+ 4 x) z))) 50 | (check-sat) 51 | """ 52 | with open(formulafile, "w") as f: 53 | f.write(formula) 54 | script, glob = parse_str(formula) 55 | typecheck(script, glob) 56 | args = Mockargs() 57 | args.name = formulafile.strip(".smt2") 58 | script, glob = parse_file(formulafile, silent=True) 59 | typecheck(script, glob) 60 | self.av_expr, self.expr_type = get_all_subterms(script) 61 | unique_expr = get_unique_subterms(script) 62 | gen = GenTypeAwareMutation(script, args, unique_expr) 63 | gen.generate() 64 | os.system("rm " + formulafile) 65 | 66 | 67 | if __name__ == "__main__": 68 | unittest.main() 69 | -------------------------------------------------------------------------------- /tests/unit/TestParsing.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import unittest 24 | import sys 25 | 26 | from yinyang.src.parsing.Parse import parse_str, parse_file 27 | 28 | sys.path.append("../../") 29 | 30 | 31 | # Dominik: These are all regression. If these become more, it would make sense 32 | # to put them their own folder. 33 | class ParsingTestCase(unittest.TestCase): 34 | def test_issue9(self): 35 | formula, _ = parse_file("tests/res/issue7.smt2") 36 | self.assertTrue( 37 | "\x0a" in formula.__str__() and "\n" in formula.__str__()) 38 | 39 | def test_issue18(self): 40 | formula, _ = parse_file("tests/res/issue18.smt2", silent=False) 41 | oracle = """\ 42 | (declare-fun a () String) 43 | (declare-fun b () String) 44 | (assert (= a b)) 45 | (check-sat) 46 | (assert (= a b)) 47 | (check-sat)""" 48 | self.assertEqual(oracle, formula.__str__()) 49 | 50 | 51 | # def test_issue25(self): 52 | # script = """\ 53 | # (declare-fun a () Bool) 54 | # (assert (= ((_ extract 5 3) (_ bv96 8)))) 55 | # (check-sat)""" 56 | # script, _ = parse_str(script, silent=False) 57 | # t = type(script.commands[1].term.subterms[0].subterms[0]) 58 | # self.assertTrue("Term" in str(t)) 59 | # script = """\ 60 | # (declare-fun bv () (_ BitVec 10)) 61 | # (declare-fun a () Bool) 62 | # (assert (not (and (= ((_ extract 5 3) (_ bv96 8)) ((_ extract 4 2) 63 | # (concat (_ bv121 7)((_ extract 0 0) bv)))) (= (concat (_ bv1 1) (ite a 64 | # (_ bv0 1) (_ bv1 1))) ((_ extract 1 0) 65 | # (ite a (_ bv6 3) (_ bv3 3))))))) 66 | # (check-sat)""" 67 | # script, _ = parse_str(script, silent=False) 68 | # self.assertTrue(script) 69 | 70 | 71 | if __name__ == "__main__": 72 | unittest.main() 73 | -------------------------------------------------------------------------------- /tests/unit/TestSemanticFusion.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | import unittest 25 | 26 | from yinyang.src.parsing.Parse import parse_file 27 | from yinyang.src.mutators.SemanticFusion.SemanticFusion import SemanticFusion 28 | 29 | sys.path.append("../../") 30 | 31 | 32 | class Mockargs: 33 | oracle = "" 34 | config = "" 35 | generate_functions = 0 36 | multiple_variables = 2 37 | 38 | 39 | class SemanticFusionTestCase(unittest.TestCase): 40 | def test_sf_sat(self): 41 | fn1 = "tests/res/formula1.smt2" 42 | fn2 = "tests/res/formula2.smt2" 43 | fn_fcts = "tests/res/fusion_functions.txt" 44 | 45 | args = Mockargs() 46 | args.oracle = "sat" 47 | args.config = fn_fcts 48 | script1, _ = parse_file(fn1, silent=True) 49 | script2, _ = parse_file(fn2, silent=True) 50 | sf_sat = SemanticFusion(script1, script2, args) 51 | args.oracle = "unsat" 52 | script1, _ = parse_file(fn1, silent=True) 53 | script2, _ = parse_file(fn2, silent=True) 54 | sf_sat.mutate() 55 | 56 | 57 | if __name__ == "__main__": 58 | unittest.main() 59 | -------------------------------------------------------------------------------- /tests/unit/TestTypeAwareOpMutation.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import sys 24 | import unittest 25 | 26 | from yinyang.src.parsing.Parse import parse_str, parse_file 27 | from yinyang.src.mutators.TypeAwareOpMutation import TypeAwareOpMutation 28 | 29 | sys.path.append("../../") 30 | 31 | 32 | class Mockargs: 33 | config = "" 34 | scratchfolder = "." 35 | name = "" 36 | 37 | 38 | class TypeAwareOpMutationTestCase(unittest.TestCase): 39 | def test_ta(self): 40 | configfile = "tests/res/operators.txt" 41 | formulafile = "tests/res/formula_file.smt2" 42 | script, _ = parse_file(formulafile) 43 | 44 | args = Mockargs() 45 | args.config = configfile 46 | args.name = formulafile.strip(".smt2") 47 | args.config = configfile 48 | args.modulo = 2 49 | 50 | script, _ = parse_file(formulafile, silent=True) 51 | mutator = TypeAwareOpMutation(script, args) 52 | mutator.mutate() 53 | 54 | 55 | if __name__ == "__main__": 56 | unittest.main() 57 | -------------------------------------------------------------------------------- /tests/unit/test.smt2: -------------------------------------------------------------------------------- 1 | (set-info :smt-lib-version 2.6) 2 | (set-logic LRA) 3 | (set-info :source | 4 | Monniaux, David; Quantifier Elimination by Lazy Model Enumeration, CAV 2010 5 | |) 6 | (set-info :category "random") 7 | ; ./Mjollnir_examples/B1/formula_062.m 8 | (set-info :status unsat) 9 | (assert 10 | (forall ((|v9:0| Real) )(exists ((|v8:1| Real) )(forall ((|v7:2| Real) )(exists ((|v6:3| Real) )(forall ((|v5:4| Real) )(exists ((|v4:5| Real) )(forall ((|v3:6| Real) )(exists ((|v2:7| Real) )(forall ((|v1:8| Real) )(exists ((|v0:9| Real) )(let ((?x166 (- 11))) 11 | (let ((?x193 (* (- 17) |v3:6|))) 12 | (let (($x223 (<= (+ (+ (* (- 15) |v8:1|) (* (- 6) |v5:4|)) ?x193) ?x166))) 13 | (let ((?x43 (- 19))) 14 | (let ((?x218 (+ (+ (* 17 |v6:3|) (* ?x166 |v4:5|)) (* (- 15) |v6:3|)))) 15 | (let ((?x69 (- 10))) 16 | (let ((?x211 (+ (+ (* ?x69 |v7:2|) (* 11 |v6:3|)) (* 15 |v5:4|)))) 17 | (let ((?x92 19)) 18 | (let ((?x206 (+ (+ (* 10 |v1:8|) (* (- 3) |v3:6|)) (* (- 1) |v2:7|)))) 19 | (let (($x197 (<= (+ (+ ?x193 (* (- 1) |v4:5|)) (* 5 |v6:3|)) ?x92))) 20 | (let ((?x191 (+ (+ (* 4 |v1:8|) (* (- 5) |v3:6|)) (* (- 12) |v8:1|)))) 21 | (let ((?x99 (- 1))) 22 | (let ((?x137 (* ?x99 |v4:5|))) 23 | (let (($x183 (<= (+ (+ (* 11 |v8:1|) (* 11 |v7:2|)) ?x137) (- 8)))) 24 | (let ((?x130 (- 16))) 25 | (let (($x177 (<= (+ (+ (* 7 |v8:1|) |v9:0|) (* 3 |v5:4|)) ?x130))) 26 | (let (($x226 (or (or (and $x177 $x183) (or (<= ?x191 2) $x197)) (and (and (<= ?x206 ?x92) (<= ?x211 ?x69)) (or (<= ?x218 ?x43) $x223))))) 27 | (let ((?x33 (- 20))) 28 | (let ((?x168 (+ (+ (* (- 9) |v9:0|) (* 18 |v7:2|)) (* ?x166 |v2:7|)))) 29 | (let ((?x160 (+ (+ (* 17 |v7:2|) (* 9 |v9:0|)) (* (- 6) |v9:0|)))) 30 | (let ((?x152 (+ (+ (* (- 3) |v6:3|) (* 9 |v8:1|)) (* (- 17) |v0:9|)))) 31 | (let (($x144 (<= (+ (+ ?x137 (* (- 14) |v2:7|)) (* (- 5) |v4:5|)) ?x130))) 32 | (let (($x171 (or (or $x144 (<= ?x152 (- 12))) (or (<= ?x160 ?x43) (<= ?x168 ?x33))))) 33 | (let (($x136 (<= (+ (+ (* (- 2) |v7:2|) (* ?x130 |v7:2|)) (* ?x43 |v0:9|)) 2))) 34 | (let (($x125 (<= (+ (+ (* ?x43 |v1:8|) (* 0 |v9:0|)) (* ?x99 |v3:6|)) 18))) 35 | (let ((?x111 (+ (+ (* (- 18) |v3:6|) (* (- 3) |v4:5|)) (* (- 2) |v9:0|)))) 36 | (let (($x103 (<= (+ (+ (* ?x92 |v7:2|) (* 3 |v8:1|)) (* ?x99 |v6:3|)) 15))) 37 | (let ((?x87 17)) 38 | (let ((?x86 (+ (+ (* 9 |v1:8|) (* (- 5) |v2:7|)) (* 7 |v9:0|)))) 39 | (let ((?x27 (- 15))) 40 | (let (($x75 (<= (+ (+ (* ?x69 |v2:7|) (* 11 |v7:2|)) (* ?x69 |v8:1|)) ?x27))) 41 | (let ((?x63 (+ (+ (* (- 5) |v8:1|) (* 5 |v7:2|)) (* ?x33 |v0:9|)))) 42 | (let ((?x49 (+ (+ (* 11 |v6:3|) (* ?x43 |v9:0|)) (* (- 3) |v2:7|)))) 43 | (let ((?x16 (- 6))) 44 | (let ((?x31 (* ?x16 |v5:4|))) 45 | (let ((?x18 (+ (+ (* 12 |v2:7|) (* 12 |v3:6|)) (* ?x16 |v2:7|)))) 46 | (let (($x35 (and (<= ?x18 (- 9)) (<= (+ (+ (* 8 |v3:6|) (* ?x27 |v7:2|)) ?x31) ?x33)))) 47 | (let (($x115 (and (or $x35 (and (<= ?x49 13) (<= ?x63 (- 18)))) (and (or $x75 (<= ?x86 ?x87)) (or $x103 (<= ?x111 ?x99)))))) 48 | (and (and $x115 $x125) (and (and $x136 $x171) $x226))))))))))))))))))))))))))))))))))))))))) 49 | ) 50 | ) 51 | ) 52 | ) 53 | ) 54 | ) 55 | ) 56 | ) 57 | ) 58 | ) 59 | (check-sat) 60 | (exit) 61 | 62 | -------------------------------------------------------------------------------- /yinyang/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/__init__.py -------------------------------------------------------------------------------- /yinyang/config/Config.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | solvers = [] 24 | 25 | crash_list = [ 26 | "Exception", 27 | "lang.AssertionError", 28 | "lang.Error", 29 | "runtime error", 30 | "LEAKED", 31 | "Leaked", 32 | "Segmentation fault", 33 | "segmentation fault", 34 | "segfault", 35 | "ASSERTION", 36 | "Assertion", 37 | "Fatal failure", 38 | "Internal error detected", 39 | "an invalid model was generated", 40 | "Failed to verify", 41 | "failed to verify", 42 | "ERROR: AddressSanitizer:", 43 | "invalid expression", 44 | "Aborted" 45 | ] 46 | 47 | duplicate_list = [ 48 | "src/smt/smt_mock.cpp:1489" 49 | ] 50 | 51 | ignore_list = [ 52 | "(error ", 53 | "unsupported", 54 | "unexpected char", 55 | "failed to open file", 56 | "Expected result sat but got unsat", 57 | "Expected result unsat but got sat", 58 | "Parse Error", 59 | "Cannot get model", 60 | "Symbol 'str.to-re' not declared as a variable", 61 | "Symbol 'str.to.re' not declared as a variable", 62 | "Unimplemented code encountered", 63 | ] 64 | -------------------------------------------------------------------------------- /yinyang/config/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/config/__init__.py -------------------------------------------------------------------------------- /yinyang/config/fusion_functions.txt: -------------------------------------------------------------------------------- 1 | ; Configuration file for fusion and inversion functions as described in PLDI 2020 2 | ; paper's Definition 1 and Definition 2 which we will repeat here. 3 | ; 4 | ; Definition 1 (Fusion function). 5 | ; Let phi1, phi2 be formulas and x and y be variables of phi1 and phi2 6 | ; respectively, and z a fresh variable which does not occur in neither phi1 nor 7 | ; phi2. We define z := f(x,y) and call f a fusion function. 8 | ; 9 | ; 10 | ; Definition 2 (Inversion function). 11 | ; Let phi1, phi2 be formulas and f be a fusion function. For two variables x and 12 | ; y be variables of phi1 and phi2 and z = f(x,y), we define 13 | ; x = r_x(y,z); y = r_y (x,z) and call them inversion functions. 14 | ; 15 | ; ** File format: 16 | ; 17 | ; Each triplet of a fusion and two inversion functions is contained within a 18 | ; "#begin-#end" block. Note, variables x,y,z are hard-coded to reflect Definition 1 19 | ; and Definition 2 closely and should be declared as three constants. An additional 20 | ; constant "c" represents a randomly chosen constant. The first assert represents 21 | ; the equation "z := f(x,y)", the second and third represent the equations 22 | ; x = r_x(y,z) and y = r_y (x,z) respectively. 23 | ; 24 | ; The below fusion and inversion function triplets are based on the PLDI 2020 paper. 25 | ; 26 | ; Int 27 | ; 28 | #begin 29 | (declare-const x Int) 30 | (declare-const y Int) 31 | (declare-const z Int) 32 | (assert (= z (* x y))) 33 | (assert (= x (div z y))) 34 | (assert (= y (div z x))) 35 | #end 36 | 37 | #begin 38 | (declare-const x Int) 39 | (declare-const y Int) 40 | (declare-const z Int) 41 | (assert (= z (+ x y))) 42 | (assert (= x (- z y))) 43 | (assert (= y (- z x))) 44 | #end 45 | 46 | #begin 47 | (declare-const x Int) 48 | (declare-const y Int) 49 | (declare-const z Int) 50 | (declare-const c Int) 51 | (assert (= z (+ (+ x y) c))) 52 | (assert (= x (- (- z y) c))) 53 | (assert (= y (- (- z x) c))) 54 | #end 55 | 56 | ; Real 57 | ; 58 | #begin 59 | (declare-const x Real) 60 | (declare-const y Real) 61 | (declare-const z Real) 62 | (assert (= z (* x y))) 63 | (assert (= x (/ z y))) 64 | (assert (= y (/ z x))) 65 | #end 66 | 67 | #begin 68 | (declare-const x Real) 69 | (declare-const y Real) 70 | (declare-const z Real) 71 | (declare-const c Real) 72 | (assert (= z (+ (+ x y) c))) 73 | (assert (= x (- (- z y) c))) 74 | (assert (= y (- (- z x) c))) 75 | #end 76 | 77 | #begin 78 | (declare-const x Real) 79 | (declare-const y Real) 80 | (declare-const z Real) 81 | (assert (= z (+ x y))) 82 | (assert (= x (- z y))) 83 | (assert (= y (- z x))) 84 | #end 85 | 86 | #begin 87 | (declare-const x Real) 88 | (declare-const y Real) 89 | (declare-const z Real) 90 | (declare-const c Real) 91 | (assert (= z (+ x c) y)) 92 | (assert (= x (- (- z c) y))) 93 | (assert (= y (- (- z c) x))) 94 | #end 95 | 96 | ; BV 97 | ; 98 | #begin 99 | (declare-const x (_ BitVec 8)) 100 | (declare-const y (_ BitVec 8)) 101 | (declare-const z (_ BitVec 8)) 102 | (assert (= z (bvxor x y))) 103 | (assert (= x (bvxor z y))) 104 | (assert (= y (bvxor z x))) 105 | #end 106 | 107 | ; String 108 | ; 109 | #begin 110 | (declare-const x String) 111 | (declare-const y String) 112 | (declare-const z String) 113 | (assert (= z (str.++ x y))) 114 | (assert (= x (str.substr z 0 (str.len x)))) 115 | (assert (= y (str.substr z (str.len x) (str.len y)))) 116 | #end 117 | 118 | #begin 119 | (declare-const x String) 120 | (declare-const y String) 121 | (declare-const z String) 122 | (assert (= z (str.++ x y))) 123 | (assert (= x (str.substr z 0 (str.len x)))) 124 | (assert (= y (str.replace z x ""))) 125 | #end 126 | 127 | #begin 128 | (declare-const x String) 129 | (declare-const y String) 130 | (declare-const z String) 131 | (declare-const c String) 132 | (assert (= z (str.++ x c y))) 133 | (assert (= x (str.substr z 0 (str.len x)))) 134 | (assert (= y (str.replace (str.replace z x "") c ""))) 135 | #end 136 | -------------------------------------------------------------------------------- /yinyang/config/operator_mutations.txt: -------------------------------------------------------------------------------- 1 | ; Configuration file for the type-aware operator mutations based on the operators 2 | ; as specified in the OOPSLA '20 paper. 3 | ; 4 | ; Format: 5 | ; 6 | ; op1, op2, ... ,op_n 7 | ; 8 | ; Operators op_i in the same line form an equivalence class and can mutually 9 | ; replace each other. 10 | ; 11 | ; Example: 12 | ; +, -, * 13 | ; 14 | ; Operator mutations can be conditioned on operator's arity. 15 | ; 16 | ; Example: 17 | ; =,distinct: arity: 2+ 18 | ; -,abs: arity: 1- 19 | ; 20 | ; This requires operators "=" and "distinct" to have at least two arguments to trigger the 21 | ; mutation, and "-","abs" to have at most one argument. At the moment, only the arities 22 | ; 2+ ("two or more") and 1- (one or less) are supported 23 | ; 24 | ; Unidirectional mutations can be specified as 25 | ; 26 | ; abs -> - 27 | ; 28 | ; which corresponds to a one-way mutation from operator "abs" to operator "-" 29 | ; 30 | =,distinct 31 | exists,forall 32 | not -> and,or 33 | and,or,=> :arity 3+ 34 | and,or,=>,xor :arity 2 35 | <=,>=,<,> 36 | +,-,* :arity 2+ 37 | mod,div 38 | abs,- :arity 1 39 | re.++,re.union,re.inter,re.diff 40 | str.<=,str.<,str.prefixof,str.suffixof,str.contains 41 | str.replace,str.replace_all 42 | str.replace_re,str.replace_re_all 43 | re.comp,re.+,re.opt,re.* 44 | re.none,re.all,re.allchar 45 | str.to_code,str.to_int 46 | str.from_code,str.from_int 47 | union,intersection,setminus 48 | bvnot,bvneg 49 | bvand,bvor,bvnand,bvnor,bvxor,bvxnor,bvsub,bvsdiv,bvsmod,bvadd,bvmul,bvudiv,bvurem,bvshl,bvlshr,bvashr 50 | bvule,bvugt,bvuge,bvslt,bvsle,bvsgt,bvsge 51 | fp.abs,fp.neg 52 | fp.add,fp.sub,fp.mul,fp.div 53 | fp.min,fp.max 54 | fp.leq,fp.lt,fp.geq,fp.gt,fp.eq 55 | fp.isNormal,fp.isSubnormal,fp.isZero,fp.isInfinite,fp.isNaN,fp.isNegative,fp.isPositive 56 | -------------------------------------------------------------------------------- /yinyang/config/typefuzz_config.txt: -------------------------------------------------------------------------------- 1 | ; 2 | (par (A) (id A A)) 3 | ; 4 | ; ### funs from core theory 5 | ;(true Bool) 6 | ;(false Bool) 7 | (not Bool Bool) 8 | (=> Bool Bool Bool :right-assoc) 9 | (and Bool Bool Bool :left-assoc) 10 | (or Bool Bool Bool :left-assoc) 11 | (xor Bool Bool Bool :left-assoc) 12 | ;(par (A) (= A A Bool :chainable)) 13 | ;(par (A) (distinct A A Bool :pairwise)) 14 | ;(par (A) (ite Bool A A A)) 15 | 16 | ; ### funs from ints 17 | ;(NUMERAL Int) 18 | (- Int Int) ; negation 19 | (- Int Int Int :left-assoc) ; subtraction 20 | (+ Int Int Int :left-assoc) 21 | (* Int Int Int :left-assoc) 22 | (div Int Int Int :left-assoc) 23 | (mod Int Int Int) 24 | (abs Int Int) 25 | (<= Int Int Bool :chainable) 26 | (< Int Int Bool :chainable) 27 | (>= Int Int Bool :chainable) 28 | (> Int Int Bool :chainable) 29 | 30 | ; ### funs from reals 31 | ;(NUMERAL Real) 32 | ;(DECIMAL Real) 33 | (- Real Real) ; negation 34 | (- Real Real Real :left-assoc) ; subtraction 35 | (+ Real Real Real :left-assoc) 36 | (* Real Real Real :left-assoc) 37 | (/ Real Real Real :left-assoc) 38 | (<= Real Real Bool :chainable) 39 | (< Real Real Bool :chainable) 40 | (>= Real Real Bool :chainable) 41 | (> Real Real Bool :chainable) 42 | 43 | ; ### funs from real-ints 44 | ;(NUMERAL Int) 45 | ;(- Int Int) ; negation 46 | (- Int Int Int :left-assoc) ; subtraction 47 | (+ Int Int Int :left-assoc) 48 | (* Int Int Int :left-assoc) 49 | (div Int Int Int :left-assoc) 50 | (mod Int Int Int) 51 | (abs Int Int) 52 | (<= Int Int Bool :chainable) 53 | (< Int Int Bool :chainable) 54 | (>= Int Int Bool :chainable) 55 | (> Int Int Bool :chainable) 56 | ;(DECIMAL Real) 57 | (- Real Real) ; negation 58 | (- Real Real Real :left-assoc) ; subtraction 59 | (+ Real Real Real :left-assoc) 60 | (* Real Real Real :left-assoc) 61 | (/ Real Real Real :left-assoc) 62 | (<= Real Real Bool :chainable) 63 | (< Real Real Bool :chainable) 64 | (>= Real Real Bool :chainable) 65 | (> Real Real Bool :chainable) 66 | (to_real Int Real) 67 | (to_int Real Int) 68 | (is_int Real Bool) 69 | 70 | ; ### funs from strings 71 | ; 72 | ; ## Core functions 73 | (str.++ String String String :left-assoc) 74 | (str.len String Int) 75 | (str.< String String Bool :chainable) 76 | ; 77 | ; ## Regular expression functions 78 | (str.to_re String RegLan) 79 | (str.in_re String RegLan Bool) 80 | (re.none RegLan) 81 | (re.all RegLan) 82 | (re.allchar RegLan) 83 | (re.++ RegLan RegLan RegLan :left-assoc) 84 | (re.union RegLan RegLan RegLan :left-assoc) 85 | (re.inter RegLan RegLan RegLan :left-assoc) 86 | (re.* RegLan RegLan) 87 | ; 88 | ; ## Regular expression functions 89 | (str.<= String String Bool :chainable) 90 | (str.at String Int String) 91 | (str.substr String Int Int String) 92 | (str.prefixof String String Bool) 93 | (str.suffixof String String Bool) 94 | (str.contains String String Bool) 95 | (str.indexof String String Int Int) 96 | (str.replace String String String String) 97 | (str.replace_all String String String String) 98 | (str.replace_re String RegLan String String) 99 | (str.replace_re_all String RegLan String String) 100 | (re.comp RegLan RegLan) 101 | (re.diff RegLan RegLan RegLan :left-assoc) 102 | (re.+ RegLan RegLan) 103 | (re.opt RegLan RegLan) 104 | (re.range String String RegLan) 105 | ; 106 | ; ## Maps to and from integers 107 | (str.is_digit String Bool) 108 | (str.to_code String Int) 109 | (str.from_code Int String) 110 | (str.to_int String Int) 111 | (str.from_int Int String) 112 | -------------------------------------------------------------------------------- /yinyang/src/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/__init__.py -------------------------------------------------------------------------------- /yinyang/src/base/Driver.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import os 24 | import sys 25 | from pathlib import Path 26 | from yinyang.src.base.Exitcodes import ERR_USAGE, ERR_EXHAUSTED_DISK 27 | 28 | path = Path(__file__) 29 | rootpath = str(path.parent.absolute().parent) 30 | 31 | try: 32 | sys.path.insert(1, os.getcwd() + "/.yinyang") 33 | from yinyang.config import solvers 34 | except Exception as e: 35 | from yinyang.config.Config import solvers 36 | 37 | 38 | def check_solver_clis(): 39 | if args.SOLVER_CLIS == "": 40 | if len(solvers) == 0: 41 | print("error: no solver specified", flush=True) 42 | exit(ERR_USAGE) 43 | args.SOLVER_CLIS = solvers 44 | else: 45 | args.SOLVER_CLIS = args.SOLVER_CLIS.split(";") + solvers 46 | 47 | 48 | def check_timeout(): 49 | if args.timeout <= 0: 50 | print("error: timeout should not be a negative number or zero", 51 | flush=True) 52 | exit(ERR_USAGE) 53 | 54 | 55 | def check_iterations(): 56 | if args.iterations <= 0: 57 | print("error: iterations should not be a negative number zero", 58 | flush=True) 59 | exit(ERR_USAGE) 60 | 61 | 62 | def create_bug_folder(): 63 | if not os.path.isdir(args.bugsfolder): 64 | try: 65 | os.mkdir(args.bugsfolder) 66 | except Exception: 67 | print("error: bug folder cannot be created", flush=True) 68 | exit(ERR_EXHAUSTED_DISK) 69 | 70 | 71 | def create_log_folder(): 72 | if not os.path.isdir(args.logfolder): 73 | try: 74 | os.mkdir(args.logfolder) 75 | except Exception: 76 | print("error: log folder cannot be created", flush=True) 77 | exit(ERR_EXHAUSTED_DISK) 78 | 79 | 80 | def create_scratch_folder(): 81 | if not os.path.isdir(args.scratchfolder): 82 | try: 83 | os.mkdir(args.scratchfolder) 84 | except Exception: 85 | print("error: scratch folder cannot be created", flush=True) 86 | exit(ERR_EXHAUSTED_DISK) 87 | 88 | 89 | def get_seeds(): 90 | temp_seeds = [] 91 | for path in args.PATH_TO_SEEDS: 92 | if not os.path.exists(path): 93 | print('error: folder/file "%s" does not exist' % (path), 94 | flush=True) 95 | exit(ERR_USAGE) 96 | if os.path.isfile(path): 97 | temp_seeds.append(path) 98 | elif os.path.isdir(path): 99 | for subdir, dirs, files in os.walk(path): 100 | for filename in files: 101 | filepath = subdir + os.sep + filename 102 | if filepath.endswith(".smt2"): 103 | temp_seeds.append(filepath) 104 | else: 105 | print("error: %s is neither a file nor a directory", flush=True) 106 | exit(ERR_USAGE) 107 | 108 | args.PATH_TO_SEEDS = temp_seeds 109 | 110 | 111 | def check_opfuzz(): 112 | if len(args.PATH_TO_SEEDS) < 1: 113 | print("error: please provide at least one seed", flush=True) 114 | exit(ERR_USAGE) 115 | 116 | if len(args.SOLVER_CLIS) < 2: 117 | print("error: please provide at least two SMT solvers", flush=True) 118 | exit(ERR_USAGE) 119 | 120 | 121 | def check_fusion(): 122 | if len(args.PATH_TO_SEEDS) < 2: 123 | print( 124 | "error: please provide at least two seeds for the fusion strategy", 125 | flush=True, 126 | ) 127 | exit(ERR_USAGE) 128 | 129 | if len(args.SOLVER_CLIS) < 1: 130 | print("error: please provide at one SMT solvers", flush=True) 131 | exit(ERR_USAGE) 132 | 133 | 134 | def run_checks(parser, strategy): 135 | global args 136 | args = parser.parse_args() 137 | if not args.PATH_TO_SEEDS: 138 | parser.error("no seed-file/seed folder specified") 139 | 140 | check_solver_clis() 141 | check_timeout() 142 | check_iterations() 143 | create_bug_folder() 144 | create_log_folder() 145 | create_scratch_folder() 146 | get_seeds() 147 | if strategy in ["opfuzz", "typefuzz"]: 148 | check_opfuzz() 149 | else: 150 | check_fusion() 151 | return args 152 | -------------------------------------------------------------------------------- /yinyang/src/base/Error.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | from yinyang.src.base.Version import VERSION, COMMIT 24 | 25 | 26 | def raise_runtime_error(trace, argv, e): 27 | fn = trace[-1].filename 28 | lineno = trace[-1].lineno 29 | print("Runtime error at %s:%s" % (fn, lineno), flush=True) 30 | print("msg: " + str(e), flush=True) 31 | print( 32 | "cmd: " 33 | + " ".join(argv[:-2]) 34 | + " " 35 | + '"' + argv[-2] 36 | + '"' + " " + argv[-1], 37 | flush=True, 38 | ) 39 | print("version: yinyang " + VERSION + " " + COMMIT, flush=True) 40 | print("Please file an issue: https://github.com/testsmt/yinyang/issues", 41 | flush=True) 42 | -------------------------------------------------------------------------------- /yinyang/src/base/Exitcodes.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | OK_NOBUGS = 0 # no error and no bugs 24 | OK_BUGS = 10 # no error and bugs 25 | ERR_USAGE = 2 # commandline usage error 26 | ERR_INTERNAL = 3 # internal error within the tool 27 | ERR_SOLVER_CFG = 4 # usage error of one or more solver configurations 28 | ERR_EXHAUSTED_DISK = 5 # disk space exhaustion error 29 | -------------------------------------------------------------------------------- /yinyang/src/base/Utils.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import random 24 | import string 25 | 26 | 27 | def random_string(length=5): 28 | return "".join(random.sample(string.ascii_letters + string.digits, length)) 29 | 30 | 31 | def plain(cli): 32 | plain_cli = "" 33 | for token in cli.split(" "): 34 | plain_cli += token.split("/")[-1] 35 | return escape(plain_cli) 36 | 37 | 38 | def escape(s): 39 | s = s.replace(".", "") 40 | s = s.replace("=", "") 41 | return s 42 | 43 | 44 | def in_list(stdout, stderr, lst): 45 | stdstream = stdout + " " + stderr 46 | for err in lst: 47 | if err in stdstream: 48 | return True 49 | return False 50 | -------------------------------------------------------------------------------- /yinyang/src/base/Version.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | VERSION = "0.3.0" 24 | COMMIT = "unknown" 25 | -------------------------------------------------------------------------------- /yinyang/src/base/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/base/__init__.py -------------------------------------------------------------------------------- /yinyang/src/core/FuzzerUtil.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | import random 23 | import re 24 | import pathlib 25 | 26 | from yinyang.src.base.Utils import in_list 27 | 28 | try: 29 | sys.path.insert(1, os.getcwd() + "/.yinyang") 30 | from yinyang.config import crash_list, duplicate_list, ignore_list 31 | except Exception as e: 32 | from yinyang.config.Config import crash_list, duplicate_list, ignore_list 33 | 34 | from yinyang.src.core.Solver import SolverResult, SolverQueryResult 35 | 36 | 37 | def in_crash_list(stdout, stderr): 38 | return in_list(stdout, stderr, crash_list) 39 | 40 | 41 | def in_duplicate_list(stdout, stderr): 42 | return in_list(stdout, stderr, duplicate_list) 43 | 44 | 45 | def in_ignore_list(stdout, stderr): 46 | return in_list(stdout, stderr, ignore_list) 47 | 48 | 49 | def admissible_seed_size(seed, args): 50 | """ 51 | Checks if seed size is below file_size_limit. 52 | :returns: True if that is the case and False otherwise. 53 | """ 54 | seed_size_in_bytes = pathlib.Path(seed).stat().st_size 55 | return seed_size_in_bytes < args.file_size_limit 56 | 57 | 58 | def grep_result(stdout): 59 | """ 60 | Grep the result from the stdout of a solver. 61 | """ 62 | result = SolverResult() 63 | for line in stdout.splitlines(): 64 | if re.search("^unsat$", line, flags=re.MULTILINE): 65 | result.append(SolverQueryResult.UNSAT) 66 | elif re.search("^sat$", line, flags=re.MULTILINE): 67 | result.append(SolverQueryResult.SAT) 68 | elif re.search("^unknown$", line, flags=re.MULTILINE): 69 | result.append(SolverQueryResult.UNKNOWN) 70 | return result 71 | 72 | 73 | def get_seeds(args, strategy): 74 | initial_seeds = args.PATH_TO_SEEDS 75 | num_initial = len(initial_seeds) 76 | random.shuffle(initial_seeds) 77 | 78 | if strategy == "yinyang": 79 | assert len(initial_seeds) >= 2 80 | gen = get_permutation_generator(initial_seeds) 81 | return gen, num_initial**2 82 | else: 83 | assert strategy in ["opfuzz", "typefuzz"] 84 | return initial_seeds, num_initial 85 | 86 | 87 | def get_permutation_generator(seeds): 88 | seeds_copy = [seed for seed in seeds] 89 | for a in seeds: 90 | random.shuffle(seeds_copy) 91 | for b in seeds_copy: 92 | yield a, b 93 | 94 | 95 | def init_oracle(args): 96 | """ 97 | Initialize the oracle. For SemanticFusion the oracle is either sat or 98 | unsat. For TypeAwareOpMutation the oracle is unknown 99 | """ 100 | if args.oracle == "unknown": 101 | return SolverResult(SolverQueryResult.UNKNOWN) 102 | elif args.oracle == "sat": 103 | return SolverResult(SolverQueryResult.SAT) 104 | elif args.oracle == "unsat": 105 | return SolverResult(SolverQueryResult.UNSAT) 106 | assert False 107 | -------------------------------------------------------------------------------- /yinyang/src/core/Logger.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import logging 24 | import datetime 25 | 26 | from logging.handlers import RotatingFileHandler 27 | 28 | RED = "\033[91m" 29 | BOLD = "\033[1m" 30 | WARNING = "\033[91m" 31 | ENDC = "\033[0m" 32 | 33 | 34 | def init_logging(strategy, quiet_mode, name, args): 35 | fn = ( 36 | datetime.datetime.now().strftime(strategy + "-%Y-%m-%d-%M:%S-%p") 37 | + "-" 38 | + str(name) 39 | + ".log" 40 | ) 41 | log_fn = args.logfolder + "/" + fn 42 | logging.basicConfig( 43 | handlers=[ 44 | RotatingFileHandler(filename=log_fn, 45 | maxBytes=1024 * 1024, backupCount=5) 46 | ], 47 | format="%(asctime)s %(message)s", 48 | datefmt="[%Y/%m/%d %I:%M:%S %p]", 49 | level=logging.DEBUG, 50 | ) 51 | 52 | if not quiet_mode: 53 | console = logging.StreamHandler() 54 | formatter = logging.Formatter( 55 | "%(asctime)s %(message)s", datefmt="[%Y/%m/%d %I:%M:%S %p]" 56 | ) 57 | console.setLevel(logging.INFO) 58 | console.setFormatter(formatter) 59 | logging.getLogger().addHandler(console) 60 | 61 | 62 | def log_strategy_num_seeds(strategy, num_seeds, num_targets): 63 | logging.info( 64 | "Strategy: " 65 | + strategy 66 | + ", " 67 | + str(num_targets) 68 | + " testing targets, " 69 | + str(num_seeds) 70 | + " seeds" 71 | ) 72 | 73 | 74 | def log_generation_attempt(args): 75 | logging.debug( 76 | "Attempting to generate " + str(args.iterations) + " mutants" 77 | ) 78 | 79 | 80 | def log_finished_generations(successful, unsuccessful): 81 | logging.debug( 82 | "Finished generations: " 83 | + str(successful) 84 | + " successful, " 85 | + str(unsuccessful) 86 | + " unsuccessful" 87 | ) 88 | 89 | 90 | def log_crash_trigger(path): 91 | logging.debug("Crash! Stop testing on this seed.") 92 | logging.info(BOLD + WARNING + "Detected crash bug: " + path + ENDC) 93 | 94 | 95 | def log_ignore_list_mutant(solver_cli): 96 | logging.debug("Invalid mutant:ignore_list. solver=" + str(solver_cli)) 97 | 98 | 99 | def log_duplicate_trigger(): 100 | logging.debug("Duplicate. Stop testing on this seed.") 101 | 102 | 103 | def log_segfault_trigger(args, path, i): 104 | logging.debug( 105 | str(i) + "/" + str(args.iterations) 106 | + " Segfault! Stop testing on this seed." 107 | ) 108 | logging.info(BOLD + WARNING + "Detected segfault: " + path + ENDC) 109 | 110 | 111 | def log_solver_timeout(args, solver_cli, i): 112 | logging.debug( 113 | str(i) 114 | + "/" 115 | + str(args.iterations) 116 | + " Solver timeout occurred. sol=" 117 | + str(solver_cli) 118 | ) 119 | 120 | 121 | def log_soundness_trigger(args, i, path): 122 | logging.debug( 123 | str(i) 124 | + "/" 125 | + str(args.iterations) 126 | + " Soundness bug! Stop testing on this seed." 127 | ) 128 | logging.info(BOLD + WARNING + "Detected soundness bug! " + path + ENDC) 129 | 130 | 131 | def log_invalid_mutant(args, i): 132 | logging.debug( 133 | str(i) 134 | + "/" 135 | + str(args.iterations) 136 | + " Invalid mutant:no '^sat$' or '^unsat$' in output." 137 | ) 138 | 139 | 140 | def log_skip_seed_mutator(args, i): 141 | logging.debug( 142 | str(i) 143 | + "/" 144 | + str(args.iterations) 145 | + " Mutator indicated to skip the seed." 146 | ) 147 | 148 | 149 | def log_skip_seed_test(args, i): 150 | logging.debug( 151 | str(i) 152 | + "/" 153 | + str(args.iterations) 154 | + " Fuzzer::test indicated to skip the seed." 155 | ) 156 | -------------------------------------------------------------------------------- /yinyang/src/core/Solver.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2020] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import subprocess 24 | from enum import Enum 25 | 26 | from yinyang.src.base.Exitcodes import ERR_USAGE 27 | 28 | 29 | class SolverQueryResult(Enum): 30 | """ 31 | Enum storing the result of a single solver check-sat query. 32 | """ 33 | 34 | SAT = 0 # solver query returns "sat" 35 | UNSAT = 1 # solver query returns "unsat" 36 | UNKNOWN = 2 # solver query reports "unknown" 37 | 38 | 39 | def sr2str(sol_res): 40 | if sol_res == SolverQueryResult.SAT: 41 | return "sat" 42 | if sol_res == SolverQueryResult.UNSAT: 43 | return "unsat" 44 | if sol_res == SolverQueryResult.UNKNOWN: 45 | return "unknown" 46 | 47 | 48 | class SolverResult: 49 | """ 50 | Class to store the result of multiple solver check-sat queries. 51 | :lst a list of multiple "SolverQueryResult" items 52 | """ 53 | 54 | def __init__(self, result=None): 55 | self.lst = [] 56 | if result: 57 | self.lst.append(result) 58 | 59 | def append(self, result): 60 | self.lst.append(result) 61 | 62 | def equals(self, rhs): 63 | if type(rhs) == SolverQueryResult: 64 | return len(self.lst) == 1 and self.lst[0] == rhs 65 | elif type(rhs) == SolverResult: 66 | if len(self.lst) != len(rhs.lst): 67 | return False 68 | for index in range(0, len(self.lst)): 69 | if ( 70 | self.lst[index] != SolverQueryResult.UNKNOWN 71 | and rhs.lst[index] != SolverQueryResult.UNKNOWN 72 | and self.lst[index] != rhs.lst[index] 73 | ): 74 | return False 75 | return True 76 | else: 77 | return False 78 | 79 | def __str__(self): 80 | s = sr2str(self.lst[0]) 81 | for res in self.lst[1:]: 82 | s += "\n" + sr2str(res) 83 | return s 84 | 85 | 86 | class Solver: 87 | def __init__(self, cil): 88 | self.cil = cil 89 | 90 | def solve(self, file, timeout, debug=False): 91 | try: 92 | cmd = list(filter(None, self.cil.split(" "))) + [file] 93 | if debug: 94 | print("cmd: " + " ".join(cmd), flush=True) 95 | output = subprocess.run( 96 | cmd, 97 | timeout=timeout, 98 | stdout=subprocess.PIPE, 99 | stderr=subprocess.PIPE, 100 | shell=False, 101 | ) 102 | 103 | except subprocess.TimeoutExpired as te: 104 | if te.stdout and te.stderr: 105 | stdout = te.stdout.decode() 106 | stderr = te.stderr.decode() 107 | else: 108 | stdout = "" 109 | stderr = "" 110 | return stdout, stderr, 137 111 | 112 | except ValueError: 113 | stdout = "" 114 | stderr = "" 115 | return stdout, stderr, 0 116 | 117 | except FileNotFoundError: 118 | print('error: solver "' + cmd[0] + '" not found', flush=True) 119 | exit(ERR_USAGE) 120 | 121 | stdout = output.stdout.decode() 122 | stderr = output.stderr.decode() 123 | returncode = output.returncode 124 | 125 | if debug: 126 | print("output: " + stdout + "\n" + stderr) 127 | 128 | return stdout, stderr, returncode 129 | -------------------------------------------------------------------------------- /yinyang/src/core/Statistic.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2020] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import time 24 | import logging 25 | 26 | 27 | class Statistic: 28 | def __init__(self): 29 | self.starttime = time.time() 30 | self.total_seeds = 0 31 | self.invalid_seeds = 0 32 | self.total_generations = 0 33 | self.unsuccessful_generations = 0 34 | self.mutants = 0 35 | self.invalid_mutants = 0 36 | self.crashes = 0 37 | self.soundness = 0 38 | self.duplicates = 0 39 | self.timeout = 0 40 | self.solver_calls = 0 41 | self.effective_calls = 0 42 | 43 | def printbar(self, start_time): 44 | total_time = time.time() - start_time 45 | if self.solver_calls != 0: 46 | eff = round( 47 | (float(self.effective_calls) / float(self.solver_calls)) * 100, 48 | 1 49 | ) 50 | eff_str = str(eff) + "%" 51 | else: 52 | eff_str = "NaN" 53 | 54 | solver_calls_per_sec = round( 55 | float(self.solver_calls) / float(total_time), 1) 56 | 57 | mutants_per_sec = round(float(self.mutants) / float(total_time), 1) 58 | mutants_per_sec_str = str(mutants_per_sec) 59 | bar = "Performed %d solver calls \ 60 | (%s calls/s, eff: %s, %s mutants/s)" % ( 61 | self.solver_calls, 62 | solver_calls_per_sec, 63 | eff_str, 64 | mutants_per_sec_str, 65 | ) 66 | logging.info(bar) 67 | 68 | def printsum(self): 69 | valid_seeds = self.total_seeds - self.invalid_seeds 70 | num_bugs = self.crashes + self.soundness 71 | summary = ( 72 | "\b\b%d seeds processed, \ 73 | %d valid, %d invalid \n%d bug triggers found" 74 | % (self.total_seeds, valid_seeds, self.invalid_seeds, num_bugs) 75 | ) 76 | print(summary) 77 | -------------------------------------------------------------------------------- /yinyang/src/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/core/__init__.py -------------------------------------------------------------------------------- /yinyang/src/mutators/GenTypeAwareMutation/Operator.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | from yinyang.src.parsing.Types import sort2type 24 | 25 | 26 | class Operator: 27 | def __init__(self, name, types, attributes, parameters=[]): 28 | self.name = name 29 | self.arg_types = [sort2type(t) for t in types[:-1]] 30 | self.rtype = sort2type(types[-1]) 31 | self.attributes = attributes 32 | 33 | def __str__(self): 34 | s = self.name + ":" + ",".join(self.arg_types) + " -> " + self.rtype 35 | if self.attributes != []: 36 | s += " " + " ".join(self.attributes) 37 | return s 38 | 39 | def __repr__(self): 40 | return self.__str__() 41 | 42 | 43 | def handle_non_parametric_op(tokens): 44 | op_name, type_strings, attributes = "", [], [] 45 | for idx, tok in enumerate(tokens): 46 | if tok == "": 47 | continue # ignore empty token 48 | if idx == 0: # first token is the operator name 49 | op_name = tok[1:] 50 | elif ":" != tok[0]: 51 | type_strings.append(tok.strip(")")) 52 | else: 53 | attributes.append(tok.strip(")")) 54 | return op_name, type_strings, attributes 55 | 56 | 57 | def handle_parametric_op(tokens): 58 | op_name, type_strings, attributes, parameters = "", [], [], [] 59 | for idx, tok in enumerate(tokens): 60 | if idx == 0: 61 | continue 62 | if idx == 1: 63 | parameters.append(tok.strip("(").strip(")")) 64 | continue 65 | if idx == 2: 66 | op_name = tok[1:] 67 | elif ":" != tok[0]: 68 | type_strings.append(tok.strip(")")) 69 | else: 70 | attributes.append(tok.strip(")")) 71 | return op_name, type_strings, attributes, parameters 72 | -------------------------------------------------------------------------------- /yinyang/src/mutators/GenTypeAwareMutation/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/mutators/GenTypeAwareMutation/__init__.py -------------------------------------------------------------------------------- /yinyang/src/mutators/Mutator.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | 24 | class Mutator: 25 | def __init__(self, seeds, args): 26 | self.seeds = seeds 27 | self.args = args 28 | 29 | def generate(self): 30 | pass 31 | -------------------------------------------------------------------------------- /yinyang/src/mutators/SemanticFusion/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/mutators/SemanticFusion/__init__.py -------------------------------------------------------------------------------- /yinyang/src/mutators/TypeAwareOpMutation.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in 13 | # all copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | 23 | import random 24 | 25 | from yinyang.src.mutators.Mutator import Mutator 26 | 27 | 28 | class TypeAwareOpMutation(Mutator): 29 | def __init__(self, formula, args): 30 | self.args = args 31 | self.formula = formula 32 | self.bidirectional = [] 33 | self.unidirectional = [] 34 | 35 | self.parse_config_file() 36 | 37 | def parse_config_file(self): 38 | with open(self.args.config) as f: 39 | lines = f.readlines() 40 | 41 | for line in lines: 42 | if ";" in line: 43 | continue 44 | if not line.strip(): 45 | continue 46 | arity = -1 47 | if ":arity" in line: 48 | arity = line.split(":arity")[-1].split(" ")[-1].strip() 49 | line = " ".join(line.split(" ")[:-2]) 50 | if "->" in line: 51 | op_from = line.split("->")[0].strip() 52 | op_to = line.split("->")[1].strip() 53 | self.unidirectional.append((arity, op_from, op_to)) 54 | continue 55 | 56 | op_class = [op.strip() for op in line.split(",")] 57 | self.bidirectional.append((arity, op_class)) 58 | 59 | def arities_mismatch(self, arity, op_occ): 60 | if arity == "2+" and len(op_occ.subterms) < 2: 61 | return True 62 | 63 | if arity == "1-" and len(op_occ.subterms) > 2: 64 | return True 65 | return False 66 | 67 | def get_replacee(self, op_occ): 68 | for b in self.bidirectional: 69 | arity, op_class = b[0], b[1] 70 | if self.arities_mismatch(arity, op_occ): 71 | continue 72 | 73 | if op_occ.op in op_class: 74 | diff = op_class.copy() 75 | diff.remove(op_occ.op) 76 | replacee = random.choice(diff) 77 | return replacee 78 | 79 | if op_occ.quantifier in op_class: 80 | diff = op_class.copy() 81 | diff.remove(op_occ.quantifier) 82 | replacee = random.choice(diff) 83 | return replacee 84 | 85 | for u in self.unidirectional: 86 | arity, op, replacee = u[0], u[1], u[2] 87 | if op_occ.op != op or op_occ.quantifier != op: 88 | continue 89 | if self.arities_mismatch(arity, op_occ): 90 | continue 91 | return replacee 92 | return None 93 | 94 | def mutate(self): 95 | success = False 96 | for _ in range(self.args.modulo): 97 | max_choices = len(self.formula.op_occs) 98 | for _ in range(max_choices): 99 | op_occ = random.choice(self.formula.op_occs) 100 | replacee = self.get_replacee(op_occ) 101 | if replacee: 102 | success = True 103 | op_occ.op = replacee 104 | break 105 | return self.formula, success, False 106 | -------------------------------------------------------------------------------- /yinyang/src/mutators/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/mutators/__init__.py -------------------------------------------------------------------------------- /yinyang/src/parsing/SMTLIBv2.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | Comment=2 3 | ParOpen=3 4 | ParClose=4 5 | Semicolon=5 6 | String=6 7 | QuotedSymbol=7 8 | RegConst=8 9 | PS_Not=9 10 | PS_Bool=10 11 | PS_Int=11 12 | PS_Real=12 13 | PS_ContinuedExecution=13 14 | PS_Error=14 15 | PS_False=15 16 | PS_ImmediateExit=16 17 | PS_Incomplete=17 18 | PS_Logic=18 19 | PS_Memout=19 20 | PS_Sat=20 21 | PS_Success=21 22 | PS_Theory=22 23 | PS_True=23 24 | PS_Unknown=24 25 | PS_Unsupported=25 26 | PS_Unsat=26 27 | CMD_Assert=27 28 | CMD_AssertSoft=28 29 | Simplify=29 30 | CMD_CheckSat=30 31 | CMD_CheckSatAssuming=31 32 | CMD_CheckSatUsing=32 33 | CMD_Labels=33 34 | CMD_Minimize=34 35 | CMD_Maximize=35 36 | CMD_DeclareConst=36 37 | CMD_DeclareDatatype=37 38 | CMD_DeclareCodatatype=38 39 | CMD_DeclareDatatypes=39 40 | CMD_DeclareCodatatypes=40 41 | CMD_DeclareFun=41 42 | CMD_DeclareSort=42 43 | CMD_Define=43 44 | CMD_DefineFun=44 45 | CMD_DefineConst=45 46 | CMD_DefineFunRec=46 47 | CMD_DefineFunsRec=47 48 | CMD_DefineSort=48 49 | CMD_Display=49 50 | CMD_Echo=50 51 | CMD_Eval=51 52 | CMD_Exit=52 53 | CMD_GetObjectives=53 54 | CMD_GetAssertions=54 55 | CMD_GetAssignment=55 56 | CMD_GetInfo=56 57 | CMD_GetModel=57 58 | CMD_BlockModel=58 59 | CMD_GetOption=59 60 | CMD_PolyFactor=60 61 | CMD_GetProof=61 62 | CMD_GetUnsatAssumptions=62 63 | CMD_GetUnsatCore=63 64 | CMD_GetValue=64 65 | CMD_Pop=65 66 | CMD_Push=66 67 | CMD_Reset=67 68 | CMD_ResetAssertions=68 69 | CMD_SetInfo=69 70 | CMD_SetLogic=70 71 | CMD_SetOption=71 72 | TAC_Then=72 73 | TAC_AndThen=73 74 | TAC_ParThen=74 75 | TAC_OrElse=75 76 | TAC_ParOrElse=76 77 | TAC_ParOr=77 78 | TAC_TryFor=78 79 | TAC_UsingParams=79 80 | GRW_Exclamation=80 81 | GRW_Underscore=81 82 | GRW_As=82 83 | GRW_Binary=83 84 | GRW_Decimal=84 85 | GRW_Exists=85 86 | GRW_Hexadecimal=86 87 | GRW_Forall=87 88 | GRW_Let=88 89 | GRW_Match=89 90 | GRW_Numeral=90 91 | GRW_Par=91 92 | Numeral=92 93 | Binary=93 94 | HexDecimal=94 95 | Decimal=95 96 | Colon=96 97 | PK_AllStatistics=97 98 | PK_AssertionStackLevels=98 99 | PK_Authors=99 100 | PK_Category=100 101 | PK_Chainable=101 102 | PK_Definition=102 103 | PK_DiagnosticOutputChannel=103 104 | PK_ErrorBehaviour=104 105 | PK_Extension=105 106 | PK_Funs=106 107 | PK_FunsDescription=107 108 | PK_GlobalDeclarations=108 109 | PK_InteractiveMode=109 110 | PK_Language=110 111 | PK_LeftAssoc=111 112 | PK_License=112 113 | PK_Named=113 114 | PK_Name=114 115 | PK_Notes=115 116 | PK_Pattern=116 117 | PK_PrintSuccess=117 118 | PK_ProduceAssertions=118 119 | PK_ProduceAssignments=119 120 | PK_ProduceModels=120 121 | PK_ProduceProofs=121 122 | PK_ProduceUnsatAssumptions=122 123 | PK_ProduceUnsatCores=123 124 | PK_RandomSeed=124 125 | PK_ReasonUnknown=125 126 | PK_RegularOutputChannel=126 127 | PK_ReproducibleResourceLimit=127 128 | PK_RightAssoc=128 129 | PK_SmtLibVersion=129 130 | PK_Sorts=130 131 | PK_SortsDescription=131 132 | PK_Source=132 133 | PK_Status=133 134 | PK_Theories=134 135 | PK_Values=135 136 | PK_Verbosity=136 137 | PK_Version=137 138 | UndefinedSymbol=138 139 | WS=139 140 | ' bv'=1 141 | '('=3 142 | ')'=4 143 | ';'=5 144 | 'not'=9 145 | 'Bool'=10 146 | 'Int'=11 147 | 'Real'=12 148 | 'continued-execution'=13 149 | 'error'=14 150 | 'false'=15 151 | 'immediate-exit'=16 152 | 'incomplete'=17 153 | 'logic'=18 154 | 'memout'=19 155 | 'sat'=20 156 | 'success'=21 157 | 'theory'=22 158 | 'true'=23 159 | 'unknown'=24 160 | 'unsupported'=25 161 | 'unsat'=26 162 | 'assert'=27 163 | 'assert-soft'=28 164 | 'simplify'=29 165 | 'check-sat'=30 166 | 'check-sat-assuming'=31 167 | 'check-sat-using'=32 168 | 'labels'=33 169 | 'minimize'=34 170 | 'maximize'=35 171 | 'declare-const'=36 172 | 'declare-datatype'=37 173 | 'declare-codatatype'=38 174 | 'declare-datatypes'=39 175 | 'declare-codatatypes'=40 176 | 'declare-fun'=41 177 | 'declare-sort'=42 178 | 'define'=43 179 | 'define-fun'=44 180 | 'define-const'=45 181 | 'define-fun-rec'=46 182 | 'define-funs-rec'=47 183 | 'define-sort'=48 184 | 'display'=49 185 | 'echo'=50 186 | 'eval'=51 187 | 'exit'=52 188 | 'get-objectives'=53 189 | 'get-assertions'=54 190 | 'get-assignment'=55 191 | 'get-info'=56 192 | 'get-model'=57 193 | 'block-model'=58 194 | 'get-option'=59 195 | 'poly/factor'=60 196 | 'get-proof'=61 197 | 'get-unsat-assumptions'=62 198 | 'get-unsat-core'=63 199 | 'get-value'=64 200 | 'pop'=65 201 | 'push'=66 202 | 'reset'=67 203 | 'reset-assertions'=68 204 | 'set-info'=69 205 | 'set-logic'=70 206 | 'set-option'=71 207 | 'then'=72 208 | 'and-then'=73 209 | 'par-then'=74 210 | 'or-else'=75 211 | 'par-or-else'=76 212 | 'par-or'=77 213 | 'try-for'=78 214 | 'using-params'=79 215 | '!'=80 216 | '_'=81 217 | 'as'=82 218 | 'BINARY'=83 219 | 'DECIMAL'=84 220 | 'exists'=85 221 | 'HEXADECIMAL'=86 222 | 'forall'=87 223 | 'let'=88 224 | 'match'=89 225 | 'NUMERAL'=90 226 | 'par'=91 227 | ':'=96 228 | ':all-statistics'=97 229 | ':assertion-stack-levels'=98 230 | ':authors'=99 231 | ':category'=100 232 | ':chainable'=101 233 | ':definition'=102 234 | ':diagnostic-output-channel'=103 235 | ':error-behavior'=104 236 | ':extensions'=105 237 | ':funs'=106 238 | ':funs-description'=107 239 | ':global-declarations'=108 240 | ':interactive-mode'=109 241 | ':language'=110 242 | ':left-assoc'=111 243 | ':license'=112 244 | ':named'=113 245 | ':name'=114 246 | ':notes'=115 247 | ':pattern'=116 248 | ':print-success'=117 249 | ':produce-assertions'=118 250 | ':produce-assignments'=119 251 | ':produce-models'=120 252 | ':produce-proofs'=121 253 | ':produce-unsat-assumptions'=122 254 | ':produce-unsat-cores'=123 255 | ':random-seed'=124 256 | ':reason-unknown'=125 257 | ':regular-output-channel'=126 258 | ':reproducible-resource-limit'=127 259 | ':right-assoc'=128 260 | ':smt-lib-version'=129 261 | ':sorts'=130 262 | ':sorts-description'=131 263 | ':source'=132 264 | ':status'=133 265 | ':theories'=134 266 | ':values'=135 267 | ':verbosity'=136 268 | ':version'=137 269 | -------------------------------------------------------------------------------- /yinyang/src/parsing/SMTLIBv2Lexer.tokens: -------------------------------------------------------------------------------- 1 | T__0=1 2 | Comment=2 3 | ParOpen=3 4 | ParClose=4 5 | Semicolon=5 6 | String=6 7 | QuotedSymbol=7 8 | RegConst=8 9 | PS_Not=9 10 | PS_Bool=10 11 | PS_Int=11 12 | PS_Real=12 13 | PS_ContinuedExecution=13 14 | PS_Error=14 15 | PS_False=15 16 | PS_ImmediateExit=16 17 | PS_Incomplete=17 18 | PS_Logic=18 19 | PS_Memout=19 20 | PS_Sat=20 21 | PS_Success=21 22 | PS_Theory=22 23 | PS_True=23 24 | PS_Unknown=24 25 | PS_Unsupported=25 26 | PS_Unsat=26 27 | CMD_Assert=27 28 | CMD_AssertSoft=28 29 | Simplify=29 30 | CMD_CheckSat=30 31 | CMD_CheckSatAssuming=31 32 | CMD_CheckSatUsing=32 33 | CMD_Labels=33 34 | CMD_Minimize=34 35 | CMD_Maximize=35 36 | CMD_DeclareConst=36 37 | CMD_DeclareDatatype=37 38 | CMD_DeclareCodatatype=38 39 | CMD_DeclareDatatypes=39 40 | CMD_DeclareCodatatypes=40 41 | CMD_DeclareFun=41 42 | CMD_DeclareSort=42 43 | CMD_Define=43 44 | CMD_DefineFun=44 45 | CMD_DefineConst=45 46 | CMD_DefineFunRec=46 47 | CMD_DefineFunsRec=47 48 | CMD_DefineSort=48 49 | CMD_Display=49 50 | CMD_Echo=50 51 | CMD_Eval=51 52 | CMD_Exit=52 53 | CMD_GetObjectives=53 54 | CMD_GetAssertions=54 55 | CMD_GetAssignment=55 56 | CMD_GetInfo=56 57 | CMD_GetModel=57 58 | CMD_BlockModel=58 59 | CMD_GetOption=59 60 | CMD_PolyFactor=60 61 | CMD_GetProof=61 62 | CMD_GetUnsatAssumptions=62 63 | CMD_GetUnsatCore=63 64 | CMD_GetValue=64 65 | CMD_Pop=65 66 | CMD_Push=66 67 | CMD_Reset=67 68 | CMD_ResetAssertions=68 69 | CMD_SetInfo=69 70 | CMD_SetLogic=70 71 | CMD_SetOption=71 72 | TAC_Then=72 73 | TAC_AndThen=73 74 | TAC_ParThen=74 75 | TAC_OrElse=75 76 | TAC_ParOrElse=76 77 | TAC_ParOr=77 78 | TAC_TryFor=78 79 | TAC_UsingParams=79 80 | GRW_Exclamation=80 81 | GRW_Underscore=81 82 | GRW_As=82 83 | GRW_Binary=83 84 | GRW_Decimal=84 85 | GRW_Exists=85 86 | GRW_Hexadecimal=86 87 | GRW_Forall=87 88 | GRW_Let=88 89 | GRW_Match=89 90 | GRW_Numeral=90 91 | GRW_Par=91 92 | Numeral=92 93 | Binary=93 94 | HexDecimal=94 95 | Decimal=95 96 | Colon=96 97 | PK_AllStatistics=97 98 | PK_AssertionStackLevels=98 99 | PK_Authors=99 100 | PK_Category=100 101 | PK_Chainable=101 102 | PK_Definition=102 103 | PK_DiagnosticOutputChannel=103 104 | PK_ErrorBehaviour=104 105 | PK_Extension=105 106 | PK_Funs=106 107 | PK_FunsDescription=107 108 | PK_GlobalDeclarations=108 109 | PK_InteractiveMode=109 110 | PK_Language=110 111 | PK_LeftAssoc=111 112 | PK_License=112 113 | PK_Named=113 114 | PK_Name=114 115 | PK_Notes=115 116 | PK_Pattern=116 117 | PK_PrintSuccess=117 118 | PK_ProduceAssertions=118 119 | PK_ProduceAssignments=119 120 | PK_ProduceModels=120 121 | PK_ProduceProofs=121 122 | PK_ProduceUnsatAssumptions=122 123 | PK_ProduceUnsatCores=123 124 | PK_RandomSeed=124 125 | PK_ReasonUnknown=125 126 | PK_RegularOutputChannel=126 127 | PK_ReproducibleResourceLimit=127 128 | PK_RightAssoc=128 129 | PK_SmtLibVersion=129 130 | PK_Sorts=130 131 | PK_SortsDescription=131 132 | PK_Source=132 133 | PK_Status=133 134 | PK_Theories=134 135 | PK_Values=135 136 | PK_Verbosity=136 137 | PK_Version=137 138 | UndefinedSymbol=138 139 | WS=139 140 | ' bv'=1 141 | '('=3 142 | ')'=4 143 | ';'=5 144 | 'not'=9 145 | 'Bool'=10 146 | 'Int'=11 147 | 'Real'=12 148 | 'continued-execution'=13 149 | 'error'=14 150 | 'false'=15 151 | 'immediate-exit'=16 152 | 'incomplete'=17 153 | 'logic'=18 154 | 'memout'=19 155 | 'sat'=20 156 | 'success'=21 157 | 'theory'=22 158 | 'true'=23 159 | 'unknown'=24 160 | 'unsupported'=25 161 | 'unsat'=26 162 | 'assert'=27 163 | 'assert-soft'=28 164 | 'simplify'=29 165 | 'check-sat'=30 166 | 'check-sat-assuming'=31 167 | 'check-sat-using'=32 168 | 'labels'=33 169 | 'minimize'=34 170 | 'maximize'=35 171 | 'declare-const'=36 172 | 'declare-datatype'=37 173 | 'declare-codatatype'=38 174 | 'declare-datatypes'=39 175 | 'declare-codatatypes'=40 176 | 'declare-fun'=41 177 | 'declare-sort'=42 178 | 'define'=43 179 | 'define-fun'=44 180 | 'define-const'=45 181 | 'define-fun-rec'=46 182 | 'define-funs-rec'=47 183 | 'define-sort'=48 184 | 'display'=49 185 | 'echo'=50 186 | 'eval'=51 187 | 'exit'=52 188 | 'get-objectives'=53 189 | 'get-assertions'=54 190 | 'get-assignment'=55 191 | 'get-info'=56 192 | 'get-model'=57 193 | 'block-model'=58 194 | 'get-option'=59 195 | 'poly/factor'=60 196 | 'get-proof'=61 197 | 'get-unsat-assumptions'=62 198 | 'get-unsat-core'=63 199 | 'get-value'=64 200 | 'pop'=65 201 | 'push'=66 202 | 'reset'=67 203 | 'reset-assertions'=68 204 | 'set-info'=69 205 | 'set-logic'=70 206 | 'set-option'=71 207 | 'then'=72 208 | 'and-then'=73 209 | 'par-then'=74 210 | 'or-else'=75 211 | 'par-or-else'=76 212 | 'par-or'=77 213 | 'try-for'=78 214 | 'using-params'=79 215 | '!'=80 216 | '_'=81 217 | 'as'=82 218 | 'BINARY'=83 219 | 'DECIMAL'=84 220 | 'exists'=85 221 | 'HEXADECIMAL'=86 222 | 'forall'=87 223 | 'let'=88 224 | 'match'=89 225 | 'NUMERAL'=90 226 | 'par'=91 227 | ':'=96 228 | ':all-statistics'=97 229 | ':assertion-stack-levels'=98 230 | ':authors'=99 231 | ':category'=100 232 | ':chainable'=101 233 | ':definition'=102 234 | ':diagnostic-output-channel'=103 235 | ':error-behavior'=104 236 | ':extensions'=105 237 | ':funs'=106 238 | ':funs-description'=107 239 | ':global-declarations'=108 240 | ':interactive-mode'=109 241 | ':language'=110 242 | ':left-assoc'=111 243 | ':license'=112 244 | ':named'=113 245 | ':name'=114 246 | ':notes'=115 247 | ':pattern'=116 248 | ':print-success'=117 249 | ':produce-assertions'=118 250 | ':produce-assignments'=119 251 | ':produce-models'=120 252 | ':produce-proofs'=121 253 | ':produce-unsat-assumptions'=122 254 | ':produce-unsat-cores'=123 255 | ':random-seed'=124 256 | ':reason-unknown'=125 257 | ':regular-output-channel'=126 258 | ':reproducible-resource-limit'=127 259 | ':right-assoc'=128 260 | ':smt-lib-version'=129 261 | ':sorts'=130 262 | ':sorts-description'=131 263 | ':source'=132 264 | ':status'=133 265 | ':theories'=134 266 | ':values'=135 267 | ':verbosity'=136 268 | ':version'=137 269 | -------------------------------------------------------------------------------- /yinyang/src/parsing/TimeoutDecorator.py: -------------------------------------------------------------------------------- 1 | """ 2 | MIT License 3 | 4 | Copyright (c) 2015 Aaron Hall 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | """ 21 | 22 | from __future__ import print_function 23 | 24 | import threading 25 | 26 | try: 27 | import thread 28 | except ImportError: 29 | import _thread as thread 30 | 31 | 32 | def cdquit(fn_name): 33 | thread.interrupt_main() # raises KeyboardInterrupt 34 | 35 | 36 | def exit_after(s): 37 | """ 38 | use as decorator to exit the process if 39 | function takes longer than s seconds 40 | """ 41 | 42 | def outer(fn): 43 | def inner(*args, **kwargs): 44 | timer = threading.Timer(s, cdquit, args=[fn.__name__]) 45 | timer.start() 46 | try: 47 | result = fn(*args, **kwargs) 48 | finally: 49 | timer.cancel() 50 | return result 51 | 52 | return inner 53 | 54 | return outer 55 | -------------------------------------------------------------------------------- /yinyang/src/parsing/__init__.py: -------------------------------------------------------------------------------- 1 | # MIT License 2 | # 3 | # Copyright (c) [2020 - 2021] The yinyang authors 4 | # 5 | # Permission is hereby granted, free of charge, to any person obtaining a copy 6 | # of this software and associated documentation files (the "Software"), to deal 7 | # in the Software without restriction, including without limitation the rights 8 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | # copies of the Software, and to permit persons to whom the Software is 10 | # furnished to do so, subject to the following conditions: 11 | # 12 | # The above copyright notice and this permission notice shall be included in all 13 | # copies or substantial portions of the Software. 14 | # 15 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | # SOFTWARE. 22 | -------------------------------------------------------------------------------- /yinyang/src/parsing/antlr-4.9.2-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/testsmt/yinyang/f38bb10ab603408fd4c0415a7d63a9c8b5b13d03/yinyang/src/parsing/antlr-4.9.2-complete.jar -------------------------------------------------------------------------------- /yinyang/src/parsing/regenerate_grammar.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | java -jar antlr-4.9.2-complete.jar -Dlanguage=Python3 SMTLIBv2.g4 3 | --------------------------------------------------------------------------------