Skip to content

Commit d21a280

Browse files
committed
docs: removing duplicated info from README.md
1 parent ff4fda6 commit d21a280

1 file changed

Lines changed: 8 additions & 178 deletions

File tree

README.md

Lines changed: 8 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,13 @@
1-
# Automated Analysis of UVL using Satisfiability Modulo Theories
1+
# flamapy-z3
22

3+
SMT-based analysis for [flamapy](https://flamapy.org) feature models with typed
4+
attributes (Integer, Real, String), built on the [Z3](https://github.com/Z3Prover/z3)
5+
solver.
36

4-
## Description
5-
This repository contains the plugin that supports z3 representations for feature models.
7+
**Documentation:** https://docs.flamapy.org/framework/plugins/z3_plugin
68

7-
The plugin is based on [flamapy](https://flamapy.github.io/), and relies on the [Z3 solver](https://github.com/Z3Prover/z3?tab=readme-ov-file) library. The architecture is as follows:
9+
## Installation
810

9-
<p align="center">
10-
<img width="750" src="resources/images/z3metamodel.png">
11-
</p>
12-
13-
14-
## Requirements and Installation
15-
- [Python 3.11+](https://www.python.org/)
16-
- [Flamapy](https://www.flamapy.org/)
17-
18-
The framework has been tested in Linux and Windows 11 with Python 3.12. Python 3.13+ may not be still supported.
19-
20-
### Download and installation
21-
1. Install [Python 3.11+](https://www.python.org/).
22-
2. Download/Clone this repository and enter into the main directory.
23-
3. Create a virtual environment: `python -m venv env`
24-
4. Activate the environment:
25-
26-
In Linux: `source env/bin/activate`
27-
28-
In Windows: `.\env\Scripts\Activate`
29-
30-
5. Install dependencies (flamapy): `pip install -r requirements.txt`
31-
32-
** In case that you are running Ubuntu and get an error installing flamapy, please install the package python3-dev with the command `sudo apt update && sudo apt install python3-dev` and update wheel and setuptools with the command `pip install --upgrade pip wheel setuptools` before step 5.
33-
34-
35-
## Functionality and usage
36-
The executable script [test.py](/test.py) serves as an entry point to show the plugin in action.
37-
38-
Simply run: `python test.py` to see it in action over the running feature model presented in the paper.
39-
40-
The following functionality is provided:
41-
42-
43-
### Load a feature model in UVL and translate to SMT
44-
```python
45-
from flamapy.metamodels.fm_metamodel.transformations import UVLReader
46-
from flamapy.metamodels.z3_metamodel.transformations import FmToZ3
47-
48-
# Load the feature model from UVL
49-
fm_model = UVLReader('resources/models/uvl_models/Pizza_z3.uvl').transform()
50-
# Transform the feature model to SMT
51-
z3_model = FmToZ3(fm_model).transform()
11+
```bash
12+
pip install flamapy-z3
5213
```
53-
54-
### Analysis operations
55-
The following operations are available:
56-
```python
57-
from flamapy.metamodels.z3_metamodel.operations import (
58-
Z3Satisfiable,
59-
Z3Configurations,
60-
Z3ConfigurationsNumber,
61-
Z3CoreFeatures,
62-
Z3DeadFeatures,
63-
Z3FalseOptionalFeatures,
64-
Z3AttributeOptimization,
65-
Z3SatisfiableConfiguration,
66-
Z3FeatureBounds,
67-
Z3AllFeatureBounds,
68-
)
69-
```
70-
71-
- **Satisfiable**
72-
73-
Return whether the model is satisfiable (valid):
74-
```python
75-
satisfiable = Z3Satisfiable().execute(z3_model).get_result()
76-
print(f'Satisfiable? (valid?): {satisfiable}')
77-
```
78-
79-
- **Core features**
80-
81-
Return the core features of the model:
82-
```python
83-
core_features = Z3CoreFeatures().execute(z3_model).get_result()
84-
print(f'Core features: {core_features}')
85-
```
86-
87-
- **Dead features**
88-
89-
Return the dead features of the model:
90-
```python
91-
dead_features = Z3DeadFeatures().execute(z3_model).get_result()
92-
print(f'Dead features: {dead_features}')
93-
```
94-
95-
- **False-Optional features**
96-
97-
Return the false-optional features of the model:
98-
```python
99-
false_optional_features = Z3FalseOptionalFeatures().execute(z3_model).get_result()
100-
print(f'False-optional features: {false_optional_features}')
101-
```
102-
103-
- **Configurations**
104-
105-
Enumerate the configurations of the model:
106-
```python
107-
configurations = Z3Configurations().execute(z3_model).get_result()
108-
print(f'Configurations: {len(configurations)}')
109-
for i, config in enumerate(configurations, 1):
110-
config_str = ', '.join(f'{f}={v}' if not isinstance(v, bool) else f'{f}' for f,v in config.elements.items() if config.is_selected(f))
111-
print(f'Config. {i}: {config_str}')
112-
```
113-
114-
- **Configurations number**
115-
116-
Return the number of configurations:
117-
```python
118-
n_configs = Z3ConfigurationsNumber().execute(z3_model).get_result()
119-
print(f'Configurations number: {n_configs}')
120-
```
121-
122-
- **Boundaries analysis of typed features**
123-
124-
Return the boundaries of the numerical features (Integer, Real, String) of the model:
125-
```python
126-
attributes = fm_model.get_attributes()
127-
print('Attributes in the model')
128-
for attr in attributes:
129-
print(f' - {attr.name} ({attr.attribute_type})')
130-
131-
variable_bounds = Z3AllFeatureBounds().execute(z3_model).get_result()
132-
print('Variable bounds for all typed variables:')
133-
for var_name, bounds in variable_bounds.items():
134-
print(f' - {var_name}: {bounds}')
135-
```
136-
137-
- **Configuration optimization based on feature attributes:**
138-
139-
Return the set of configurations that optimize the given goals (i.e., the pareto front):
140-
```python
141-
attribute_optimization_op = Z3AttributeOptimization()
142-
attributes = {'Price': OptimizationGoal.MAXIMIZE,
143-
'Kcal': OptimizationGoal.MINIMIZE}
144-
attribute_optimization_op.set_attributes(attributes)
145-
configurations_with_values = attribute_optimization_op.execute(z3_model).get_result()
146-
print(f'Optimum configurations: {len(configurations_with_values)} configs.')
147-
for i, config_value in enumerate(configurations_with_values, 1):
148-
config, values = config_value
149-
config_str = ', '.join(f'{f}={v}' if not isinstance(v, bool) else f'{f}' for f,v in config.elements.items() if config.is_selected(f))
150-
values_str = ', '.join(f'{k}={v}' for k,v in values.items())
151-
print(f'Config. {i}: {config_str} | Values: {values_str}')
152-
```
153-
154-
- Configuration validation:
155-
156-
Return whether a given partial or full configuration is valid:
157-
```python
158-
from flamapy.metamodels.configuration_metamodel.transformations import ConfigurationJSONReader
159-
configuration = ConfigurationJSONReader('resources/configs/pizza_z3_config1.json').transform()
160-
configuration.set_full(False)
161-
print(f'Configuration: {configuration.elements}')
162-
satisfiable_configuration_op = Z3SatisfiableConfiguration()
163-
satisfiable_configuration_op.set_configuration(configuration)
164-
is_satisfiable = satisfiable_configuration_op.execute(z3_model).get_result()
165-
print(f'Is the configuration satisfiable? {is_satisfiable}')
166-
```
167-
168-
**Note:** The Z3Configurations and Z3ConfigurationsNumber operations may takes longer if the number of configuration is huge, or even not finish if the model is unbounded.
169-
170-
**Note:** The Z3Configurations and Z3ConfigurationsNumber operations support also a partial configuration as an additional argument, so the operation will return the result taking into account the given partial configuration.
171-
For example:
172-
173-
```python
174-
from flamapy.core.models import Configuration
175-
# Create a partial configuration
176-
elements = {'Pizza': True, 'SpicyLvl': 5}
177-
partial_config = Configuration(elements)
178-
# Calculate the number of configuration from the partial configuration
179-
configs_number_op = Z3ConfigurationsNumber()
180-
configs_number_op.set_partial_configuration(partial_config)
181-
n_configs = configs_number_op.execute(z3_model).get_result()
182-
print(f'#Configurations: {n_configs}')
183-
```

0 commit comments

Comments
 (0)