С помощью проекта я смог найти решение
from model import *
from z3 import *
import yaml
import pprint
import inspect
import linecache
import timeit
import itertools
classes_yaml = """
-
name: DataColumn
attribute: [{name: Value, type: Integer}]
-
name: DataTable
reference: [
{name: Rows, type: DataRowCollection}
]
-
name: DataRow
reference: [
{name: Columns, type: DataColumn, multiple: true}
]
-
name: DataRowCollection
reference: [
{name: Row, type: DataRow, multiple: true}
]
"""
classes = yaml.load(classes_yaml)
DataColumn, DataTable, DataRow, DataRowCollection = load_all_classes(classes)
dc = DefineObject('col1', DataColumn)
drc = DefineObject('drc', DataRowCollection)
dt = DefineObject('dt', DataTable).force_value('Rows', drc)
dr1 = DefineObject('dr1', DataRow)
dr2 = DefineObject('dr2', DataRow)
dr3 = DefineObject('dr3', DataRow)
generate_meta_constraints()
generate_config_constraints()
solver = Optimize()
solver = Solver()
solver.add(*get_all_meta_facts())
solver.add(*get_all_config_facts())
solver.add(dt.isinstance(DataTable))
solver.add(dt['Rows'] == drc)
solver.add(drc['Row'].count() == 1)
solver.add(dc['Value'] > 5);
solver.add(dr1['Columns'].count() == 1)
print(solver)
print(solver.check())
print(cast_all_objects(solver.model()))
Проблема, которую решает решатель, - найти DataTable
с одним DataRow
, который имеет значениебольше 5 в столбце с именем Value
.
Результирующая модель:
{
"dt":{
"name": "dt", "type": "DataTable", "alive": True,
"Rows": "drc"
},
"dr1":{
"name": "dr1", "type": "DataRow", "alive": True,
"Columns":[
"col1"
]
},
"col1": {
"name": "col1", "type":"DataColumn", "alive": True,
"Value":6
},
"dr3": {
"name": "dr3", "type": "DataRow", "alive": True,
"Columns": []
},
"dr2": {
"name": "dr2", "type": "DataRow", "alive": True,
"Columns": []
},
"drc": {
"name": "drc", "type": "DataRowCollection", "alive": True,
"Row": [
"dr2"
]
}
}
Это не универсальное решение, и класс предположений необходимо пересоздавать каждый раз, когда ограничение кода отличается, то есть предположения и инициализации будут разными дляЗадача «2 строки с двумя различными таблицами значений».Кроме того, определения классов для DataRow
также будут отличаться (но может быть хитрость, как немного обобщить это).