Skip to content

Commit 3025e82

Browse files
committed
Generate structure-s for cell sorts
1 parent a53995f commit 3025e82

File tree

2 files changed

+127
-1
lines changed

2 files changed

+127
-1
lines changed

pyk/src/pyk/k2lean4/k2lean4.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
Mutual,
2323
Signature,
2424
SimpleFieldVal,
25+
StructCtor,
26+
Structure,
2527
StructVal,
2628
Term,
2729
)
@@ -69,14 +71,17 @@ def _sort_block(self, sorts: list[str]) -> Command | None:
6971
def _transform_sort(self, sort: str) -> Declaration:
7072
def is_inductive(sort: str) -> bool:
7173
decl = self.defn.sorts[sort]
72-
return not decl.hooked and 'hasDomainValues' not in decl.attrs_by_key
74+
return not decl.hooked and 'hasDomainValues' not in decl.attrs_by_key and not self._is_cell(sort)
7375

7476
def is_collection(sort: str) -> bool:
7577
return sort in self.defn.collections
7678

7779
if is_inductive(sort):
7880
return self._inductive(sort)
7981

82+
if self._is_cell(sort):
83+
return self._cell(sort)
84+
8085
if is_collection(sort):
8186
return self._collection(sort)
8287

@@ -109,6 +114,32 @@ def _symbol_ident(symbol: str) -> str:
109114
symbol = f'«{symbol}»'
110115
return symbol
111116

117+
@staticmethod
118+
def _is_cell(sort: str) -> bool:
119+
return sort.endswith('Cell')
120+
121+
def _cell(self, sort: str) -> Structure:
122+
(cell_ctor,) = self.defn.constructors[sort]
123+
decl = self.defn.symbols[cell_ctor]
124+
param_sorts = _param_sorts(decl)
125+
126+
param_names: list[str]
127+
128+
if all(self._is_cell(sort) for sort in param_sorts):
129+
param_names = []
130+
for param_sort in param_sorts:
131+
assert param_sort.startswith('Sort')
132+
assert param_sort.endswith('Cell')
133+
name = param_sort[4:-4]
134+
name = name[0].lower() + name[1:]
135+
param_names.append(name)
136+
else:
137+
assert len(param_sorts) == 1
138+
param_names = ['val']
139+
140+
fields = tuple(ExplBinder((name,), Term(sort)) for name, sort in zip(param_names, param_sorts, strict=True))
141+
return Structure(sort, Signature((), Term('Type')), ctor=StructCtor(fields))
142+
112143
def _collection(self, sort: str) -> Inductive:
113144
coll = self.defn.collections[sort]
114145
elem = self.defn.symbols[coll.element]

pyk/src/pyk/k2lean4/model.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,101 @@ def __str__(self) -> str:
260260
return f'| {patterns} => {self.rhs}'
261261

262262

263+
@final
264+
@dataclass(frozen=True)
265+
class Structure(Declaration):
266+
ident: DeclId
267+
signature: Signature | None
268+
extends: tuple[Term, ...]
269+
ctor: StructCtor | None
270+
deriving: tuple[str, ...]
271+
modifiers: Modifiers | None
272+
273+
def __init__(
274+
self,
275+
ident: str | DeclId,
276+
signature: Signature | None = None,
277+
extends: Iterable[Term] | None = None,
278+
ctor: StructCtor | None = None,
279+
deriving: Iterable[str] | None = None,
280+
modifiers: Modifiers | None = None,
281+
):
282+
ident = DeclId(ident) if isinstance(ident, str) else ident
283+
extends = tuple(extends) if extends is not None else ()
284+
deriving = tuple(deriving) if deriving is not None else ()
285+
object.__setattr__(self, 'ident', ident)
286+
object.__setattr__(self, 'signature', signature)
287+
object.__setattr__(self, 'extends', extends)
288+
object.__setattr__(self, 'ctor', ctor)
289+
object.__setattr__(self, 'deriving', deriving)
290+
object.__setattr__(self, 'modifiers', modifiers)
291+
292+
def __str__(self) -> str:
293+
lines = []
294+
295+
modifiers = f'{self.modifiers} ' if self.modifiers else ''
296+
binders = (
297+
' '.join(str(binder) for binder in self.signature.binders)
298+
if self.signature and self.signature.binders
299+
else ''
300+
)
301+
binders = f' {binders}' if binders else ''
302+
extends = ', '.join(str(extend) for extend in self.extends)
303+
extends = f' extends {extends}' if extends else ''
304+
ty = f' : {self.signature.ty}' if self.signature and self.signature.ty else ''
305+
where = ' where' if self.ctor else ''
306+
lines.append(f'{modifiers}structure {self.ident}{binders}{extends}{ty}{where}')
307+
308+
if self.deriving:
309+
lines.append(f' deriving {self.deriving}')
310+
311+
if self.ctor:
312+
lines.extend(f' {line}' for line in str(self.ctor).splitlines())
313+
314+
return '\n'.join(lines)
315+
316+
317+
@final
318+
@dataclass(frozen=True)
319+
class StructCtor:
320+
fields: tuple[Binder, ...] # TODO implement StructField
321+
ident: StructIdent | None
322+
323+
def __init__(
324+
self,
325+
fields: Iterable[Binder],
326+
ident: str | StructIdent | None = None,
327+
):
328+
fields = tuple(fields)
329+
ident = StructIdent(ident) if isinstance(ident, str) else ident
330+
object.__setattr__(self, 'fields', fields)
331+
object.__setattr__(self, 'ident', ident)
332+
333+
def __str__(self) -> str:
334+
lines = []
335+
if self.ident:
336+
lines.append(f'{self.ident} ::')
337+
for field in self.fields:
338+
if isinstance(field, ExplBinder) and len(field.idents) == 1:
339+
(ident,) = field.idents
340+
ty = '' if field.ty is None else f' : {field.ty}'
341+
lines.append(f'{ident}{ty}')
342+
else:
343+
lines.append(str(field))
344+
return '\n'.join(lines)
345+
346+
347+
@final
348+
@dataclass(frozen=True)
349+
class StructIdent:
350+
ident: str
351+
modifiers: Modifiers | None = None
352+
353+
def __str__(self) -> str:
354+
modifiers = f'{self.modifiers} ' if self.modifiers else ''
355+
return f'{modifiers}{ self.ident}'
356+
357+
263358
@final
264359
@dataclass(frozen=True)
265360
class DeclId:

0 commit comments

Comments
 (0)