Commit 349633ed authored by Bowen Wu's avatar Bowen Wu
Browse files

Modify read me and add mutants

parent 9d35b9c9
# FuzzOpt - Fuzzing LP/ILP Optimization Solvers
# FuzzOpt - Fuzzing LP/MIP Optimization Solvers
FuzzOpt is a light-weight black-box fuzzer for testing LP/MIP optimizers. It can run both locally and on Euler, ETH scientific computing platform. It is an extensible framework where you can easily test other solvers of interest, experiment with new mutation methods etc.
## Getting Started
......@@ -7,6 +9,7 @@ Therefore, it is desirable to deploy the fuzzing procedure on Euler.
First, we need to install the two optimizers of interest, Cplex and Gurobi.
### Cplex
To install Cplex, go to the download page of Cplex and choose the Linux version and download it to your local laptop.
Then you can copy the `.bin` file to the Euler whichever way you like (e.g., `scp` or FileZilla).
On Euler, execute the `.bin` file by
......@@ -18,7 +21,7 @@ chmod a+x <filename>
Follow the instructions shown on the screen and when it asks where to install the binary, instead of using its default option, make the installation into your local home directory.
For example, you can specify the installation path as `/cluster/home/<user name>/ibm/ILOG/CPLEX_Studio_Community221/`.
You do not have permission to install in `\opt`.
This is because you do not have permission to install in `\opt`.
Once the installation is done, install the Cplex python API by
```bash
......@@ -29,8 +32,8 @@ It is recommended to install your own python 3.8+ from Miniconda or alike.
Try if it works by typing `python -c "import cplex"`. If it prints nothing, it works.
### Gurobi
Moving on the Gurobi, Euler has Gurobi installed as modules so we only need to load them and install the python API.
For loading,
......@@ -56,18 +59,29 @@ Note: you will need to load the Gurobi module every time you log into Euler. To
module load gurobi/9.5.1
```
### python-mip with a CBC solver
Additionally we use python-mip with a CBC solver as a quorum for differences.
Additionally we use python-mip with a CBC solver as a quorum for differences.
Install it by
```bash
pip install mip
```
### Other dependencies
Most of our depending python packages are shipped with Miniconda.
Our repository contained a submodule that needs to be fetched.
After cloning the repo, `cd` into the repo and do
```bash
git submodule update --init
```
## Get Seed Inputs
Fuzzing needs a selected pool of seeds to start with.
We will use the linear programs in <https://miplib.zib.de/tag_benchmark.html>.
<!-- Fuzzing needs a selected pool of seeds to start with.
We will use the MIP test cases in <https://miplib.zib.de/tag_benchmark.html>.
To obtain the seeds, navigate to the root directory of the project
```bash
......@@ -79,4 +93,80 @@ rm ../benchmark.zip
```
Now in the `benchmark/` directory, you can see all 240 files in `.mps` format.
Since all inputs add up to over 1GB, it is ignored by git.
Since all inputs add up to over 1GB, it is ignored by git. -->
Fuzzing needs a selected pool of seeds to start with.
For simplicity, we prepared a pool of seeds by transforming the MIP test cases
in <https://miplib.zib.de/tag_benchmark.html>.
The seeds can be obtained from <https://polybox.ethz.ch/index.php/s/Prdzjx8LPMUyvTC>.
Download from the link, and uncompress it put it in a convenient place.
## Run the fuzzer
Finally, we are able to run the fuzzer. FuzzOpt provides a wide variety of options
to customize the fuzzing. In the project directory, execute `python opt_fuzz.py -h`
to see the available options.
```bash
usage: opt_fuzz.py [-h] [--mut_methods MUT_METHODS [MUT_METHODS ...]] [--ckpt_freq CKPT_FREQ] [--max_time MAX_TIME] [--seed_path SEED_PATH] [--schedule {fifo,pq}] [--save_path SAVE_PATH] [--ckpt_path CKPT_PATH] [--diff_path DIFF_PATH] [--mut_choice {fixed,round_robin,random}] [--solver1 {Cplex,Gurobi,CBC}] [--solver2 {Cplex,Gurobi,CBC}]
optional arguments:
-h, --help show this help message and exit
--mut_methods MUT_METHODS [MUT_METHODS ...]
Mutation strategies to be used. Available: ScaleMut, SparseMatMut, DenseMatMut, FlipSignMut
--ckpt_freq CKPT_FREQ
Number of iterations per checkpoint
--max_time MAX_TIME Maximum fuzzing time in seconds.
--seed_path SEED_PATH
Place where you store the seeds for fuzzing.
--schedule {fifo,pq} Scheduler policy, fifo or pq
--save_path SAVE_PATH
Place where you want to store the temporary mutants generated.
--ckpt_path CKPT_PATH
Place where you want to store the checkpoints.
--diff_path DIFF_PATH
Place where you want to store the mutants that cause differences.
--mut_choice {fixed,round_robin,random}
When having more than one mutating strategy, how to pick it. Available: fixed, round_robin, random.
--solver1 {Cplex,Gurobi,CBC}
Avaialble solvers are Cplex, Gurobi and CBC
--solver2 {Cplex,Gurobi,CBC}
Avaialble solvers are Cplex, Gurobi and CBC
```
If you use the CBC solver, we suggest redirect the standard output to `/dev/null`
because CBC logging messages cannot be disabled.
```bash
python opt_fuzz.py <options> 1>/dev/null
```
We also prepare a handy script `run.sh` to fuzz on Euler. It is recommended that to have
four cores at least for reasonable performance.
For each fuzzing run, we will create folders under `mutated/`, `ckpt/` and `diff/`
respectively to keep the all mutants and mutants that cause differences.
After fuzzing, you can replay the difference triggering mutants by first
finding the directory where the such mutants are stored and then run
```bash
python replay_diff.py <path_to_dir> 1</dev/null
```
## Customization
Adding a new solver to be tested or trying out a new mutation idea is fairly simple
in FuzzOpt.
To add a new solver, take a look at the existing solver wrappers in `optimizer.py`.
Make sure to (1) inherit the `Solver` class; (2) Match your solver's solution status
to our preset status codes.
To add a new mutation method, take a look at the existing mutations in `mps_mut.py`.
Make sure to inherit the `MutantMethod` class.
## Results
With FuzzOpt, we are able to find two different bugs in Cplex. The test inputs are
shown in `diff_mutants/`.
......@@ -30,6 +30,7 @@ def parse_args_function():
)
parser.add_argument(
"--schedule",
choices=["fifo", "pq"],
type=str,
default="fifo",
help="Scheduler policy, fifo or pq"
......@@ -54,6 +55,7 @@ def parse_args_function():
)
parser.add_argument(
"--mut_choice",
choices=["fixed", "round_robin", "random"],
type=str,
default="fixed",
help="When having more than one mutating strategy, how to pick it. \
......
NAME enlight_hard
ROWS
N OBJ
E inner_area_1
E inner_area_2
E inner_area_6
E inner_area_7
E inner_area_8
E inner_area_9
E inner_area_10
E inner_area_11
E inner_area_14
E inner_area_15
E inner_area_16
E inner_area_17
E inner_area_21
E inner_area_24
E inner_area_25
E inner_area_27
E inner_area_28
E inner_area_29
E inner_area_31
E inner_area_32
E inner_area_33
E inner_area_34
E inner_area_35
E inner_area_36
E inner_area_37
E inner_area_38
E inner_area_39
E inner_area_41
E inner_area_45
E inner_area_46
E inner_area_47
E inner_area_48
E inner_area_49
E inner_area_50
E inner_area_51
E inner_area_52
E inner_area_54
E inner_area_55
E inner_area_56
E inner_area_59
E inner_area_60
E inner_area_61
E upper_border_1
E upper_border_4
E upper_border_5
E upper_border_6
E upper_border_7
E upper_border_8
E lower_border_1
E lower_border_2
E lower_border_4
E lower_border_5
E lower_border_7
E left_border_1
E left_border_2
E left_border_5
E right_border_2
E right_border_3
E right_border_5
E right_border_6
E left_upper_co@60
E right_upper_c@62
E right_lower_c@63
COLUMNS
MARK0000 'MARKER' 'INTORG'
x#1#1 OBJ 1.0
x#1#1 upper_border_1 1.0
x#1#1 left_border_1 -1.0
x#1#1 left_upper_co@60 -1.0
x#1#2 OBJ 1.0
x#1#2 inner_area_1 -1.0
x#1#2 upper_border_1 1.0
x#1#2 left_upper_co@60 1.0
x#1#3 OBJ 1.0
x#1#3 inner_area_2 1.0
x#1#3 upper_border_1 1.0
x#1#4 OBJ 1.0
x#1#4 upper_border_4 1.0
x#1#5 OBJ 1.0
x#1#5 upper_border_4 -1.0
x#1#5 upper_border_5 1.0
x#1#6 OBJ 1.0
x#1#6 upper_border_4 -1.0
x#1#6 upper_border_5 1.0
x#1#6 upper_border_6 1.0
x#1#7 OBJ 1.0
x#1#7 inner_area_6 1.0
x#1#7 upper_border_5 -1.0
x#1#7 upper_border_6 -1.0
x#1#7 upper_border_7 -1.0
x#1#8 OBJ 1.0
x#1#8 inner_area_7 1.0
x#1#8 upper_border_6 -1.0
x#1#8 upper_border_7 -1.0
x#1#8 upper_border_8 -1.0
x#1#9 OBJ 1.0
x#1#9 inner_area_8 1.0
x#1#9 upper_border_7 1.0
x#1#9 upper_border_8 1.0
x#1#9 right_upper_c@62 1.0
x#1#10 OBJ 1.0
x#1#10 upper_border_8 -1.0
x#1#10 right_upper_c@62 -1.0
x#2#1 OBJ 1.0
x#2#1 inner_area_1 1.0
x#2#1 left_border_1 1.0
x#2#1 left_border_2 1.0
x#2#1 left_upper_co@60 1.0
x#2#2 OBJ 1.0
x#2#2 inner_area_1 -1.0
x#2#2 inner_area_2 -1.0
x#2#2 inner_area_9 1.0
x#2#2 upper_border_1 -1.0
x#2#2 left_border_1 -1.0
x#2#3 OBJ 1.0
x#2#3 inner_area_1 1.0
x#2#3 inner_area_2 1.0
x#2#3 inner_area_10 1.0
x#2#4 OBJ 1.0
x#2#4 inner_area_2 -1.0
x#2#4 inner_area_11 -1.0
x#2#5 OBJ 1.0
x#2#5 upper_border_4 1.0
x#2#6 OBJ 1.0
x#2#6 inner_area_6 1.0
x#2#6 upper_border_5 -1.0
x#2#7 OBJ 1.0
x#2#7 inner_area_6 1.0
x#2#7 inner_area_7 1.0
x#2#7 inner_area_14 1.0
x#2#7 upper_border_6 1.0
x#2#8 OBJ 1.0
x#2#8 inner_area_6 1.0
x#2#8 inner_area_7 -1.0
x#2#8 inner_area_8 1.0
x#2#8 inner_area_15 -1.0
x#2#8 upper_border_7 1.0
x#2#9 OBJ 1.0
x#2#9 inner_area_7 -1.0
x#2#9 inner_area_8 1.0
x#2#9 inner_area_16 1.0
x#2#9 upper_border_8 1.0
x#2#10 OBJ 1.0
x#2#10 inner_area_8 -1.0
x#2#10 right_border_2 -1.0
x#2#10 right_upper_c@62 1.0
x#3#1 OBJ 1.0
x#3#1 inner_area_9 1.0
x#3#1 left_border_1 -1.0
x#3#1 left_border_2 -1.0
x#3#2 OBJ 1.0
x#3#2 inner_area_1 1.0
x#3#2 inner_area_9 1.0
x#3#2 inner_area_10 1.0
x#3#2 inner_area_17 1.0
x#3#2 left_border_2 -1.0
x#3#3 OBJ 1.0
x#3#3 inner_area_2 1.0
x#3#3 inner_area_9 -1.0
x#3#3 inner_area_10 -1.0
x#3#3 inner_area_11 -1.0
x#3#4 OBJ 1.0
x#3#4 inner_area_10 -1.0
x#3#4 inner_area_11 1.0
x#3#5 OBJ 1.0
x#3#5 inner_area_11 -1.0
x#3#6 OBJ 1.0
x#3#6 inner_area_14 1.0
x#3#6 inner_area_21 1.0
x#3#7 OBJ 1.0
x#3#7 inner_area_6 1.0
x#3#7 inner_area_14 1.0
x#3#7 inner_area_15 -1.0
x#3#8 OBJ 1.0
x#3#8 inner_area_7 -1.0
x#3#8 inner_area_14 1.0
x#3#8 inner_area_15 1.0
x#3#8 inner_area_16 -1.0
x#3#9 OBJ 1.0
x#3#9 inner_area_8 -1.0
x#3#9 inner_area_15 1.0
x#3#9 inner_area_16 -1.0
x#3#9 inner_area_24 1.0
x#3#9 right_border_2 1.0
x#3#10 OBJ 1.0
x#3#10 inner_area_16 -1.0
x#3#10 right_border_2 -1.0
x#3#10 right_border_3 1.0
x#4#1 OBJ 1.0
x#4#1 inner_area_17 -1.0
x#4#1 left_border_2 1.0
x#4#2 OBJ 1.0
x#4#2 inner_area_9 -1.0
x#4#2 inner_area_17 1.0
x#4#2 inner_area_25 1.0
x#4#3 OBJ 1.0
x#4#3 inner_area_10 -1.0
x#4#3 inner_area_17 -1.0
x#4#4 OBJ 1.0
x#4#4 inner_area_11 1.0
x#4#4 inner_area_27 1.0
x#4#5 OBJ 1.0
x#4#5 inner_area_21 -1.0
x#4#5 inner_area_28 1.0
x#4#6 OBJ 1.0
x#4#6 inner_area_21 1.0
x#4#6 inner_area_29 -1.0
x#4#7 OBJ 1.0
x#4#7 inner_area_14 -1.0
x#4#7 inner_area_21 1.0
x#4#8 OBJ 1.0
x#4#8 inner_area_15 -1.0
x#4#8 inner_area_24 1.0
x#4#8 inner_area_31 1.0
x#4#9 OBJ 1.0
x#4#9 inner_area_16 -1.0
x#4#9 inner_area_24 1.0
x#4#9 inner_area_32 -1.0
x#4#9 right_border_3 1.0
x#4#10 OBJ 1.0
x#4#10 inner_area_24 -1.0
x#4#10 right_border_2 1.0
x#4#10 right_border_3 1.0
x#5#1 OBJ 1.0
x#5#1 inner_area_25 -1.0
x#5#1 left_border_5 -1.0
x#5#2 OBJ 1.0
x#5#2 inner_area_17 1.0
x#5#2 inner_area_25 1.0
x#5#2 inner_area_33 1.0
x#5#3 OBJ 1.0
x#5#3 inner_area_25 1.0
x#5#3 inner_area_27 -1.0
x#5#3 inner_area_34 -1.0
x#5#4 OBJ 1.0
x#5#4 inner_area_27 1.0
x#5#4 inner_area_28 1.0
x#5#4 inner_area_35 1.0
x#5#5 OBJ 1.0
x#5#5 inner_area_27 1.0
x#5#5 inner_area_28 1.0
x#5#5 inner_area_29 1.0
x#5#5 inner_area_36 1.0
x#5#6 OBJ 1.0
x#5#6 inner_area_21 1.0
x#5#6 inner_area_28 1.0
x#5#6 inner_area_29 -1.0
x#5#6 inner_area_37 -1.0
x#5#7 OBJ 1.0
x#5#7 inner_area_29 1.0
x#5#7 inner_area_31 -1.0
x#5#7 inner_area_38 -1.0
x#5#8 OBJ 1.0
x#5#8 inner_area_31 -1.0
x#5#8 inner_area_32 -1.0
x#5#8 inner_area_39 1.0
x#5#9 OBJ 1.0
x#5#9 inner_area_24 1.0
x#5#9 inner_area_31 1.0
x#5#9 inner_area_32 1.0
x#5#10 OBJ 1.0
x#5#10 inner_area_32 -1.0
x#5#10 right_border_3 1.0
x#5#10 right_border_5 1.0
x#6#1 OBJ 1.0
x#6#1 inner_area_33 1.0
x#6#1 left_border_5 1.0
x#6#2 OBJ 1.0
x#6#2 inner_area_25 1.0
x#6#2 inner_area_33 -1.0
x#6#2 inner_area_34 -1.0
x#6#2 inner_area_41 -1.0
x#6#2 left_border_5 1.0
x#6#3 OBJ 1.0
x#6#3 inner_area_33 1.0
x#6#3 inner_area_34 1.0
x#6#3 inner_area_35 1.0
x#6#4 OBJ 1.0
x#6#4 inner_area_27 1.0
x#6#4 inner_area_34 -1.0
x#6#4 inner_area_35 -1.0
x#6#4 inner_area_36 1.0
x#6#5 OBJ 1.0
x#6#5 inner_area_28 -1.0
x#6#5 inner_area_35 1.0
x#6#5 inner_area_36 -1.0
x#6#5 inner_area_37 1.0
x#6#6 OBJ 1.0
x#6#6 inner_area_29 -1.0
x#6#6 inner_area_36 1.0
x#6#6 inner_area_37 1.0
x#6#6 inner_area_38 -1.0
x#6#6 inner_area_45 1.0
x#6#7 OBJ 1.0
x#6#7 inner_area_37 1.0
x#6#7 inner_area_38 1.0
x#6#7 inner_area_39 -1.0
x#6#7 inner_area_46 -1.0
x#6#8 OBJ 1.0
x#6#8 inner_area_31 1.0
x#6#8 inner_area_38 1.0
x#6#8 inner_area_39 -1.0
x#6#8 inner_area_47 1.0
x#6#9 OBJ 1.0
x#6#9 inner_area_32 1.0
x#6#9 inner_area_39 -1.0
x#6#9 inner_area_48 1.0
x#6#9 right_border_5 1.0
x#6#10 OBJ 1.0
x#6#10 right_border_5 1.0
x#6#10 right_border_6 -1.0
x#7#1 OBJ 1.0
x#7#1 inner_area_41 1.0
x#7#1 left_border_5 1.0
x#7#2 OBJ 1.0
x#7#2 inner_area_33 -1.0
x#7#2 inner_area_41 -1.0
x#7#2 inner_area_49 -1.0
x#7#3 OBJ 1.0
x#7#3 inner_area_34 -1.0
x#7#3 inner_area_41 1.0
x#7#3 inner_area_50 1.0
x#7#4 OBJ 1.0
x#7#4 inner_area_35 1.0
x#7#4 inner_area_51 1.0
x#7#5 OBJ 1.0
x#7#5 inner_area_36 1.0
x#7#5 inner_area_45 -1.0
x#7#5 inner_area_52 1.0
x#7#6 OBJ 1.0
x#7#6 inner_area_37 -1.0
x#7#6 inner_area_45 -1.0
x#7#6 inner_area_46 1.0
x#7#7 OBJ 1.0
x#7#7 inner_area_38 -1.0
x#7#7 inner_area_45 1.0
x#7#7 inner_area_46 1.0
x#7#7 inner_area_47 1.0
x#7#7 inner_area_54 -1.0
x#7#8 OBJ 1.0
x#7#8 inner_area_39 -1.0
x#7#8 inner_area_46 -1.0
x#7#8 inner_area_47 -1.0
x#7#8 inner_area_48 -1.0
x#7#8 inner_area_55 -1.0
x#7#9 OBJ 1.0
x#7#9 inner_area_47 -1.0
x#7#9 inner_area_48 -1.0
x#7#9 inner_area_56 1.0
x#7#9 right_border_6 1.0
x#7#10 OBJ 1.0
x#7#10 inner_area_48 -1.0
x#7#10 right_border_5 -1.0
x#7#10 right_border_6 -1.0
x#8#1 OBJ 1.0
x#8#1 inner_area_49 -1.0
x#8#2 OBJ 1.0
x#8#2 inner_area_41 -1.0
x#8#2 inner_area_49 -1.0
x#8#2 inner_area_50 -1.0
x#8#3 OBJ 1.0
x#8#3 inner_area_49 1.0
x#8#3 inner_area_50 -1.0
x#8#3 inner_area_51 1.0
x#8#4 OBJ 1.0
x#8#4 inner_area_50 1.0
x#8#4 inner_area_51 1.0
x#8#4 inner_area_52 1.0
x#8#4 inner_area_59 1.0
x#8#5 OBJ 1.0
x#8#5 inner_area_51 -1.0
x#8#5 inner_area_52 -1.0
x#8#5 inner_area_60 1.0
x#8#6 OBJ 1.0
x#8#6 inner_area_45 1.0
x#8#6 inner_area_52 1.0
x#8#6 inner_area_54 1.0
x#8#6 inner_area_61 -1.0
x#8#7 OBJ 1.0
x#8#7 inner_area_46 -1.0
x#8#7 inner_area_54 1.0
x#8#7 inner_area_55 -1.0
x#8#8 OBJ 1.0
x#8#8 inner_area_47 -1.0
x#8#8 inner_area_54 1.0
x#8#8 inner_area_55 -1.0
x#8#8 inner_area_56 1.0
x#8#9 OBJ 1.0
x#8#9 inner_area_48 -1.0
x#8#9 inner_area_55 -1.0
x#8#9 inner_area_56 1.0
x#8#10 OBJ 1.0
x#8#10 inner_area_56 1.0
x#8#10 right_border_6 -1.0
x#9#2 OBJ 1.0
x#9#2 inner_area_49 1.0
x#9#2 lower_border_1 -1.0
x#9#3 OBJ 1.0
x#9#3 inner_area_50 -1.0
x#9#3 inner_area_59 1.0
x#9#3 lower_border_2 -1.0
x#9#4 OBJ 1.0
x#9#4 inner_area_51 1.0
x#9#4 inner_area_59 1.0
x#9#4 inner_area_60 -1.0
x#9#5 OBJ 1.0
x#9#5 inner_area_52 1.0
x#9#5 inner_area_59 -1.0
x#9#5 inner_area_60 -1.0
x#9#5 inner_area_61 1.0
x#9#5 lower_border_4 -1.0
x#9#6 OBJ 1.0
x#9#6 inner_area_60 1.0
x#9#6 inner_area_61 -1.0
x#9#6 lower_border_5 -1.0
x#9#7 OBJ 1.0
x#9#7 inner_area_54 1.0
x#9#7 inner_area_61 -1.0
x#9#8 OBJ 1.0
x#9#8 inner_area_55 1.0
x#9#8 lower_border_7 1.0
x#9#9 OBJ 1.0
x#9#9 inner_area_56 -1.0
x#9#10 OBJ 1.0
x#9#10 right_lower_c@63 -1.0
x#10#1 OBJ 1.0
x#10#1 lower_border_1 1.0
x#10#2 OBJ 1.0
x#10#2 lower_border_1 -1.0
x#10#2 lower_border_2 1.0
x#10#3 OBJ 1.0
x#10#3 lower_border_1 1.0
x#10#3 lower_border_2 -1.0
x#10#4 OBJ 1.0
x#10#4 inner_area_59 1.0
x#10#4 lower_border_2 1.0
x#10#4 lower_border_4 -1.0
x#10#5 OBJ 1.0
x#10#5 inner_area_60 -1.0
x#10#5 lower_border_4 1.0
x#10#5 lower_border_5 1.0
x#10#6 OBJ 1.0
x#10#6 inner_area_61 -1.0
x#10#6 lower_border_4 -1.0
x#10#6 lower_border_5 -1.0
x#10#7 OBJ 1.0
x#10#7 lower_border_5 1.0
x#10#7 lower_border_7 -1.0
x#10#8 OBJ 1.0
x#10#8 lower_border_7 -1.0
x#10#9 OBJ 1.0
x#10#9 lower_border_7 1.0
x#10#9 right_lower_c@63 -1.0
x#10#10 OBJ 1.0
x#10#10 right_lower_c@63 1.0
y#2#2 inner_area_1 -2.0
y#2#3 inner_area_2 -2.0
y#2#7 inner_area_6 -2.0
y#2#8 inner_area_7 2.0
y#2#9 inner_area_8 2.0
y#3#2 inner_area_9 -2.0
y#3#3 inner_area_10 2.0
y#3#4 inner_area_11 2.0
y#3#7 inner_area_14 2.0
y#3#8 inner_area_15 2.0
y#3#9 inner_area_16 -2.0
y#4#2 inner_area_17 -2.0
y#4#6 inner_area_21 2.0
y#4#9 inner_area_24 -2.0
y#5#2 inner_area_25 2.0
y#5#4 inner_area_27 2.0
y#5#5 inner_area_28 -2.0
y#5#6 inner_area_29 -2.0
y#5#8 inner_area_31 2.0
y#5#9 inner_area_32 -2.0
y#6#2 inner_area_33 -2.0
y#6#3 inner_area_34 -2.0
y#6#4 inner_area_35 2.0
y#6#5 inner_area_36 2.0
y#6#6 inner_area_37 -2.0
y#6#7 inner_area_38 -2.0
y#6#8 inner_area_39 2.0
y#7#2 inner_area_41 -2.0
y#7#6 inner_area_45 2.0
y#7#7 inner_area_46 2.0
y#7#8 inner_area_47 2.0
y#7#9 inner_area_48 -2.0
y#8#2 inner_area_49 -2.0
y#8#3 inner_area_50 -2.0
y#8#4 inner_area_51 -2.0
y#8#5 inner_area_52 -2.0