Тип данных - это структура, которая может иметь несколько конструкторов: например, дерево (лист или ветвь), или список (ноль, или минусы), или любая другая, как правило, древовидная структура.
Из вашего описания видно, что на самом деле вам нужен не тип данных, а прямое значение записи. (Терминология сбивает с толку. То, что ОО люди называют типом данных, в большинстве случаев является просто структурой / записью, а то, что функциональное программирование или SMT-люди называют типом данных, является чем-то гораздо более богатым, поскольку многие конструкторы рекурсивны, как список. Это неудачно, но то, что вы изучаете однажды и легко запоминается.)
Очевидно, что не один размер подходит всем; и описание вашего вопроса довольно расплывчато. Но я предполагаю, что вы хотите представить какое-то понятие Variable
, которое имеет ассоциированное фиксированное имя, размер и какое-то инициализированное поле. Вам нужен просто класс Python, где вы можете полагаться на гибкую типизацию, чтобы использовать ее как конкретные переменные или как символические c переменные, которыми z3 может манипулировать. Исходя из этого, я был бы склонен закодировать вашу проблему следующим образом:
from z3 import *
class Variable:
def __init__(self, nm):
self.name = nm
self.size = Int(nm + '_size')
self.initialized = Bool(nm + '_initialized')
def __str__(self):
return "<Name: %s, Size: %s, Initialized: %s>" % (self.name, self.size, self.initialized)
# Helper function to grab a variable from a z3 model
def getVar(m, v):
var = Variable(v.name)
var.size = m[v.size]
var.initialized = m[v.initialized]
return var
# Declare a few vars
myVar1 = Variable('myVar1')
myVar2 = Variable('myVar2')
# Add some constraints
s = Solver()
s.add(myVar1.size == 12)
s.add(myVar2.initialized == True);
s.add(myVar1.size > myVar2.size)
s.add(myVar1.initialized == Not(myVar2.initialized))
# Get a satisfying model
if s.check() == sat:
m = s.model()
print getVar(m, myVar1)
print getVar(m, myVar2)
Я использую класс Variable
для представления как обычного значения, как в Python, так и того, что может хранить размер символов c (через Int(nm + '_size')
) и инициализированную информацию символов c (через Bool(nm + '_initialized')
). Синтаксис может показаться немного запутанным, но если вы go через программу, я уверен, вы увидите лог c. Функция getVar
является помощником для получения значения одной из этих переменных после вызова check
для доступа к значениям модели.
Я добавил несколько ограничений в программу, чтобы сделать ее интересной; очевидно, это та часть, где вы будете кодировать свою исходную проблему. Когда я запускаю эту программу, я получаю:
$ python a.py
<Name: myVar1, Size: 12, Initialized: False>
<Name: myVar2, Size: 11, Initialized: True>
, которая дает мне хорошую модель, которая удовлетворяет всем указанным мною ограничениям.
Надеюсь, это поможет!