bin
├── ablation_analysis.py
├── genetic_programming.py
├── local_search.py
├── minify_patch.py
├── revalidate.py
├── show_locations.py
└── show_patch.py
There are multiple ways to use these entry points.
Because they are located in a sub-folder and not at top-level, they must be loaded as modules using the -m option of the Python interpreter.
python3 -m bin.local_search --scenario examples/scenario/triangle-cpp_runtime.txt
For maximum convenience, you can also directly execute the main magpie source directory, which accepts the following equivalent commands:
python3 magpie bin/local_search.py --scenario examples/scenario/triangle-cpp_runtime.txt
python3 magpie bin/local_search --scenario examples/scenario/triangle-cpp_runtime.txt
python3 magpie local_search.py --scenario examples/scenario/triangle-cpp_runtime.txt
python3 magpie local_search --scenario examples/scenario/triangle-cpp_runtime.txt
python3 magpie local_search --scenario examples/scenario/triangle-cpp_runtime.txt
Alternatively, these entry points (as any custom-written ones) can be moved at top-level and run from there:
mv bin/local_search.py .
python3 local_search.py --scenario examples/scenario/triangle-cpp_runtime.txt
mv bin/local_search.py .
chmod +x local_search.py
./local_search.py --scenario examples/scenario/triangle-cpp_runtime.txt
Note on requirements of "triangle_XXX" scenario:
- the Python scenario require Python 3.7+ and pytest.
- the Ruby scenario requires Ruby and minitest.
- the Java scenario only requires Java, as both jUnit and the SrcML file are already provided.
- the C scenario require make.
- the C++ scenario require CMake.
Examples:
python3 magpie local_search --scenario examples/scenario/triangle-cpp_runtime.txt
python3 magpie local_search --scenario examples/scenario/triangle-java_repair.txt
python3 magpie local_search --scenario examples/scenario/triangle-rb_repair.txt
python3 magpie local_search --scenario examples/scenario/triangle-py_bloat.txt
Note: whilst the --seed option enables setting the initial random seed, which may lead to reproducible results in cases in which the fitness function is deterministic (bloat is fine, repair may be, but running time measurements are usually too noisy).
The show_patch.py utility provides a way to quickly (without evaluation) apply a Magpie patch and show the resulting diff.
A patch can either be provided directly or as a path to a file containing the patch representation.
Examples:
python3 magpie show_patch --scenario examples/scenario/triangle-cpp_runtime.txt --patch "StmtDeletion(('triangle.cpp.xml', 'stmt', 3))"
python3 magpie show_patch --scenario examples/scenario/triangle-py_runtime.txt --patch "LineInsertion(('triangle.py', '_inter_line', 31), ('triangle.py', 'line', 7)) | LineInsertion(('triangle.py', '_inter_line', 33), ('triangle.py', 'line', 21)) | LineReplacement(('triangle.py', 'line', 9), ('triangle.py', 'line', 37)) | LineInsertion(('triangle.py', '_inter_line', 4), ('triangle.py', 'line', 7))"
In addition, using the --keep option will also instruct Magpie to leave a copy of the mutated software for further manual investigation.
The show_location.py utility provides a way to quickly verify which location points are defined for a given software.
The --filename and --type options allow for specifying a specific subset of locations; by default all locations of all targeted files are showed.
Examples:
python3 magpie show_locations --scenario examples/scenario/triangle-rb_repair.txt
python3 magpie show_locations --scenario examples/scenario/triangle-rb_repair.txt --filename triangle.rb --type line
The revalidate_patch.py entry point allows for quickly assessing the fitness of a given patch.
A patch can either be provided directly or as a path to a file containing the patch representation.
Examples:
python3 magpie revalidate_patch --scenario examples/scenario/triangle-cpp_runtime.txt --patch "StmtReplacement(('triangle.cpp.xml', 'stmt', 3), ('triangle.cpp.xml', 'stmt', 12))"
python3 magpie revalidate_patch --scenario examples/scenario/triangle-py_runtime.txt --patch "LineInsertion(('triangle.py', '_inter_line', 31), ('triangle.py', 'line', 7)) | LineInsertion(('triangle.py', '_inter_line', 33), ('triangle.py', 'line', 21)) | LineReplacement(('triangle.py', 'line', 9), ('triangle.py', 'line', 37)) | LineInsertion(('triangle.py', '_inter_line', 4), ('triangle.py', 'line', 7))"
The patches generated by Magpie are seldom optimal and often contain bloat.
The minify_patch.py entry point processes the individual mutations of a given patch in order to obtain a leaner, cleaner, shorter, and more reliable patch.
A patch can either be provided directly or as a path to a file containing the patch representation.
In practice, every individual edit is separately evaluated and ranked, and a new patch is constructed by reintroducing every edit in order, only accepting it on fitness improvement. This new patch (or the original, in rare cases in which the rebuild is unsuccessful) is then made as small as possible by trying to remove every edit one by one.
Example:
python3 magpie minify_patch --scenario examples/scenario/triangle-py_runtime.txt --patch "LineInsertion(('triangle.py', '_inter_line', 31), ('triangle.py', 'line', 7)) | LineInsertion(('triangle.py', '_inter_line', 33), ('triangle.py', 'line', 21)) | LineReplacement(('triangle.py', 'line', 9), ('triangle.py', 'line', 37)) | LineInsertion(('triangle.py', '_inter_line', 4), ('triangle.py', 'line', 7))"
Note that noise in fitness measurement may lead to non-optimal patch being returned.
In contrary to the minify_patch.py entry point, which aims to minimise patch size, the ablation_analysis.py entry point aims to highlight the individual contribution of every edit in the overall fitness improvement.
A patch can either be provided directly or as a path to a file containing the patch representation.
Example:
python3 magpie ablation_analysis --scenario examples/scenario/triangle-py_runtime.txt --patch "LineInsertion(('triangle.py', '_inter_line', 31), ('triangle.py', 'line', 7)) | LineInsertion(('triangle.py', '_inter_line', 33), ('triangle.py', 'line', 21)) | LineReplacement(('triangle.py', 'line', 9), ('triangle.py', 'line', 37)) | LineInsertion(('triangle.py', '_inter_line', 4), ('triangle.py', 'line', 7))"
Example:
python3 utils/line_to_xml.py --file examples/code/triangle-java_slow/Triangle.java
Examples:
python3 utils/python_to_xml.py examples/code/triangle-py_bug/triangle.py
cat examples/code/triangle-py_bug/triangle.py | python3 utils/python_to_xml.py
Examples:
python3 utils/clear_xml.py examples/code/triangle-py_slow/triangle.py.xml
cat examples/code/triangle-py_bug/triangle.py | python3 utils/python_to_xml.py | python3 utils/clear_xml.py