Skip to content

Commit 8537480

Browse files
authored
Merge branch 'develop' into _update-deps/runtimeverification/haskell-backend
2 parents d641b1a + 7565620 commit 8537480

File tree

12 files changed

+159
-64
lines changed

12 files changed

+159
-64
lines changed

deps/pyproject-build-systems

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
dbfc0483b5952c6b86e36f8b3afeb9dde30ea4b5
1+
795a980d25301e5133eca37adae37283ec3c8e66

deps/uv2nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
b6ed0901aec29583532abe65117b18d86a49b617
1+
c8cf711802cb00b2e05d5c54d3486fce7bfc8f7c

deps/uv_release

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.9.2
1+
0.9.9

flake.lock

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
flake-utils.follows = "llvm-backend/utils";
1717

18-
uv2nix.url = "github:pyproject-nix/uv2nix/b6ed0901aec29583532abe65117b18d86a49b617";
18+
uv2nix.url = "github:pyproject-nix/uv2nix/c8cf711802cb00b2e05d5c54d3486fce7bfc8f7c";
1919
# uv2nix requires a newer version of nixpkgs
2020
# therefore, we pin uv2nix specifically to a newer version of nixpkgs
2121
# until we replaced our stale version of nixpkgs with an upstream one as well
@@ -24,7 +24,7 @@
2424
nixpkgs-unstable.url = "github:NixOS/nixpkgs/nixos-unstable";
2525
uv2nix.inputs.nixpkgs.follows = "nixpkgs-unstable";
2626
# uv2nix.inputs.nixpkgs.follows = "nixpkgs";
27-
pyproject-build-systems.url = "github:pyproject-nix/build-system-pkgs/dbfc0483b5952c6b86e36f8b3afeb9dde30ea4b5";
27+
pyproject-build-systems.url = "github:pyproject-nix/build-system-pkgs/795a980d25301e5133eca37adae37283ec3c8e66";
2828
pyproject-build-systems = {
2929
inputs.nixpkgs.follows = "nixpkgs";
3030
inputs.uv2nix.follows = "uv2nix";

pyk/src/pyk/kast/outer.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
top_down,
3131
)
3232
from .kast import kast_term
33+
from .prelude.k import K_ITEM, K
3334
from .rewrite import indexed_rewrite
3435

3536
if TYPE_CHECKING:
@@ -1460,13 +1461,15 @@ def transform(
14601461
for t, a in zip(prod.argument_sorts, term.args, strict=True):
14611462
if type(a) is KVariable:
14621463
occurrences[a.name].append(a.let_sort(t))
1463-
elif isinstance(term, KSequence) and term.arity > 0:
1464-
for a in term.items[0:-1]:
1465-
if type(a) is KVariable:
1466-
occurrences[a.name].append(a.let_sort(KSort('KItem')))
1467-
last_a = term.items[-1]
1468-
if type(last_a) is KVariable:
1469-
occurrences[last_a.name].append(last_a.let_sort(KSort('K')))
1464+
elif isinstance(term, KSequence):
1465+
for i, item in enumerate(term.items):
1466+
if isinstance(item, KVariable):
1467+
if item.sort is not None:
1468+
occurrences[item.name].append(item)
1469+
elif i == term.arity - 1:
1470+
occurrences[item.name].append(item.let_sort(K))
1471+
else:
1472+
occurrences[item.name].append(item.let_sort(K_ITEM))
14701473
return (term, occurrences)
14711474

14721475
(new_term, var_occurrences) = bottom_up_with_summary(transform, kast)

pyk/src/pyk/konvert/_kast_to_kore.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -82,41 +82,43 @@ def kast_to_kore(definition: KDefinition, kast: KInner, sort: KSort | None = Non
8282
kast = definition.sort_vars(kast, sort)
8383
kast = definition.add_cell_map_items(kast)
8484
kast = definition.add_sort_params(kast)
85-
kast = _replace_ksequence_by_kapply(kast)
85+
kast = _replace_ksequence_by_kapply(definition, kast)
8686
kast = _add_sort_injections(definition, kast, sort)
8787
kore = _kast_to_kore(kast)
8888
return kore
8989

9090

91-
def _replace_ksequence_by_kapply(term: KInner) -> KInner:
91+
def _replace_ksequence_by_kapply(definition: KDefinition, term: KInner) -> KInner:
9292
dotk = KApply('dotk')
9393
kseq = KLabel('kseq')
94+
append = KLabel('append')
9495

95-
def transform(term: KInner) -> KInner:
96-
match term:
97-
case KSequence(items):
98-
return transform_items(items)
99-
case _:
100-
return term
96+
def kapply(x: KInner, y: KInner) -> KApply:
97+
return append(x, y) if definition.sort_strict(x) == K else kseq(x, y)
98+
99+
def ksequence_to_kapply(term: KInner) -> KInner:
100+
if not isinstance(term, KSequence):
101+
return term
102+
103+
items = term.items
101104

102-
def transform_items(items: tuple[KInner, ...]) -> KInner:
103105
if not items:
104106
return dotk
105107

106108
unit: KInner
107109
args: tuple[KInner, ...]
108110

109111
last = items[-1]
110-
if isinstance(last, KVariable) and last.sort == K:
112+
if definition.sort_strict(last) == K:
111113
unit = last
112114
args = items[:-1]
113115
else:
114116
unit = dotk
115117
args = items
116118

117-
return reduce(lambda x, y: kseq(y, x), reversed(args), unit)
119+
return reduce(lambda x, y: kapply(y, x), reversed(args), unit)
118120

119-
return top_down(transform, term)
121+
return top_down(ksequence_to_kapply, term)
120122

121123

122124
def _add_sort_injections(definition: KDefinition, term: KInner, sort: KSort) -> KInner:
@@ -179,6 +181,8 @@ def _argument_sorts(definition: KDefinition, term: KInner) -> tuple[KSort, ...]:
179181
return (K_ITEM, K)
180182
case 'dotk':
181183
return ()
184+
case 'append':
185+
return (K, K)
182186
case '#Forall' | '#Exists':
183187
_, argument_sorts = definition.resolve_sorts(term.label)
184188
_, argument_sort = argument_sorts
@@ -202,7 +206,7 @@ def _let_arguments(term: KInner, args: list[KInner]) -> KInner:
202206
def _inject(definition: KDefinition, term: KInner, sort: KSort) -> KInner:
203207
actual_sort: KSort
204208
match term:
205-
case KApply(KLabel('kseq' | 'dotk')): # Special case: pseudo-labels
209+
case KApply(KLabel('kseq' | 'dotk' | 'append')): # Special case: pseudo-labels
206210
actual_sort = K
207211
case _:
208212
actual_sort = definition.sort_strict(term)
@@ -437,7 +441,7 @@ def _kapply_to_pattern(kapply: KApply, patterns: list[Pattern]) -> Pattern:
437441

438442

439443
def _label_to_kore(label: str) -> str:
440-
if label in ['inj', 'kseq', 'dotk']: # pseudo-labels introduced during KAST-to-KORE tranformation
444+
if label in ['inj', 'kseq', 'dotk', 'append']: # pseudo-labels introduced during KAST-to-KORE tranformation
441445
return label
442446

443447
if label in ML_PATTERN_LABELS:

pyk/src/pyk/konvert/_kore_to_kast.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ def _pattern_to_kast(pattern: Pattern, terms: list[KInner]) -> KInner:
9393
_, _ = terms
9494
return KSequence(terms)
9595

96+
elif symbol == 'append':
97+
_, _ = terms
98+
return KSequence(terms)
99+
96100
else:
97101
klabel = KLabel(unmunge(symbol[3:]))
98102
return KApply(klabel, terms)

pyk/src/pyk/rpc/rpc.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
import json
44
import logging
55
from abc import ABC, abstractmethod
6+
from collections.abc import Iterator
67
from dataclasses import dataclass
78
from functools import partial
89
from http.server import BaseHTTPRequestHandler, HTTPServer
9-
from typing import TYPE_CHECKING, Any, Final, NamedTuple
10+
from typing import TYPE_CHECKING, NamedTuple
1011

1112
from typing_extensions import Protocol
1213

@@ -15,6 +16,7 @@
1516
if TYPE_CHECKING:
1617
from collections.abc import Callable
1718
from pathlib import Path
19+
from typing import Any, Final
1820

1921

2022
_LOGGER: Final = logging.getLogger(__name__)
@@ -86,7 +88,7 @@ class JsonRpcBatchRequest(NamedTuple):
8688
class JsonRpcResult(ABC):
8789

8890
@abstractmethod
89-
def encode(self) -> bytes: ...
91+
def encode(self) -> Iterator[bytes]: ...
9092

9193

9294
@dataclass(frozen=True)
@@ -96,7 +98,7 @@ class JsonRpcError(JsonRpcResult):
9698
message: str
9799
id: str | int | None
98100

99-
def to_json(self) -> dict[str, Any]:
101+
def wrap_response(self) -> dict[str, Any]:
100102
return {
101103
'jsonrpc': JsonRpcServer.JSONRPC_VERSION,
102104
'error': {
@@ -106,32 +108,40 @@ def to_json(self) -> dict[str, Any]:
106108
'id': self.id,
107109
}
108110

109-
def encode(self) -> bytes:
110-
return json.dumps(self.to_json()).encode('ascii')
111+
def encode(self) -> Iterator[bytes]:
112+
yield json.dumps(self.wrap_response()).encode('utf-8')
111113

112114

113115
@dataclass(frozen=True)
114116
class JsonRpcSuccess(JsonRpcResult):
115117
payload: Any
116118
id: Any
117119

118-
def to_json(self) -> dict[str, Any]:
119-
return {
120-
'jsonrpc': JsonRpcServer.JSONRPC_VERSION,
121-
'result': self.payload,
122-
'id': self.id,
123-
}
124-
125-
def encode(self) -> bytes:
126-
return json.dumps(self.to_json()).encode('ascii')
120+
def encode(self) -> Iterator[bytes]:
121+
id_encoded = json.dumps(self.id)
122+
version_encoded = json.dumps(JsonRpcServer.JSONRPC_VERSION)
123+
yield f'{{"jsonrpc": {version_encoded}, "id": {id_encoded}, "result": '.encode()
124+
if isinstance(self.payload, Iterator):
125+
yield from self.payload
126+
else:
127+
yield json.dumps(self.payload).encode('utf-8')
128+
yield b'}'
127129

128130

129131
@dataclass(frozen=True)
130132
class JsonRpcBatchResult(JsonRpcResult):
131133
results: tuple[JsonRpcError | JsonRpcSuccess, ...]
132134

133-
def encode(self) -> bytes:
134-
return json.dumps([result.to_json() for result in self.results]).encode('ascii')
135+
def encode(self) -> Iterator[bytes]:
136+
yield b'['
137+
first = True
138+
for result in self.results:
139+
if not first:
140+
yield b','
141+
else:
142+
first = False
143+
yield from result.encode()
144+
yield b']'
135145

136146

137147
class JsonRpcRequestHandler(BaseHTTPRequestHandler):
@@ -143,8 +153,10 @@ def __init__(self, methods: dict[str, JsonRpcMethod], *args: Any, **kwargs: Any)
143153

144154
def _send_response(self, response: JsonRpcResult) -> None:
145155
self.send_response_headers()
146-
response_bytes = response.encode()
147-
self.wfile.write(response_bytes)
156+
response_body = response.encode()
157+
for chunk in response_body:
158+
self.wfile.write(chunk)
159+
self.wfile.flush()
148160

149161
def send_response_headers(self) -> None:
150162
self.send_response(200)

0 commit comments

Comments
 (0)