├── .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 |

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 |
--------------------------------------------------------------------------------