Skip to content

Commit 4746305

Browse files
committed
Only deduplicate safe deduplicators
1 parent b48a513 commit 4746305

2 files changed

Lines changed: 37 additions & 6 deletions

File tree

tests/test_roundtrips.py

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,33 @@ def test_preeval_no_semantic_change(self, p):
412412

413413
@hypothesis.given(uplc_program_valid, hst.one_of(hst.just(None)))
414414
@hypothesis.settings(max_examples=1000, deadline=datetime.timedelta(seconds=1))
415+
@hypothesis.example(
416+
Program(
417+
version=(1, 1, 0),
418+
term=Constr(
419+
tag=0,
420+
fields=[
421+
BuiltinPair(
422+
l_value=BuiltinString(value=""), r_value=BuiltinString(value="")
423+
),
424+
Lambda(
425+
var_name="_",
426+
term=Case(
427+
scrutinee=Variable(name="_"),
428+
branches=[
429+
BuiltinPair(
430+
l_value=BuiltinString(value=""),
431+
r_value=BuiltinString(value=""),
432+
)
433+
],
434+
),
435+
state=frozendict.frozendict({}),
436+
),
437+
],
438+
),
439+
),
440+
None,
441+
)
415442
@hypothesis.example(
416443
parse(
417444
"(program 1.0.0 [(lam v0 [(lam v1 [(lam v2 (lam v3 [(lam v4 [(lam v5 [(lam v6 [(lam v7 [(lam v8 [(lam v9 [[(force v8) v7] (delay v9)]) v3]) (delay (lam v10 (lam v11 [(lam v12 [(lam v13 [(lam v14 [(lam v15 [[[v15 v15] v13] v11]) (lam v16 (lam v17 (lam v18 (force [[[(force (builtin ifThenElse)) [(lam v19 [v1 (delay v19)]) [[v2 (force v18)] (con integer 0)]]] (delay [(lam v20 [(lam v21 [(lam v22 [(lam v23 [[[v16 v16] v21] v23]) (delay v22)]) [[(lam v24 (lam v25 [[(builtin subtractInteger) v24] v25])) (force v18)] (con integer 1)]]) (delay v20)]) [[(lam v26 (lam v27 [[(builtin multiplyInteger) v26] v27])) (force v17)] (force v18)]])] (delay [[v14 v17] v18])]))))]) (lam v28 (lam v29 (force v28)))]) (delay v12)]) (con integer 1)])))]) (delay [(lam v30 (error)) (con unit ())])]) (delay [(lam v31 (error)) (con unit ())])]) (delay [(lam v32 (error)) (con unit ())])]) (delay [(lam v33 (error)) (con unit ())])])) v0]) (lam v34 [(lam v35 v35) (force v34)])]) (lam v36 (lam v37 [[(builtin lessThanInteger) v37] v36]))])"
@@ -505,11 +532,12 @@ def test_deduplicate_no_semantic_change_and_size_increase(
505532
RuntimeError,
506533
"Original code resulted in something different than a runtime error (exceeding budget) and rewritten result is ok",
507534
)
508-
self.assertEqual(
509-
orig_res,
510-
rewrite_res,
511-
f"Two programs evaluate to different results after optimization in {code}",
512-
)
535+
if isinstance(rewrite_res, (Constant, BuiltInFun)):
536+
self.assertEqual(
537+
orig_res,
538+
rewrite_res,
539+
f"Two programs evaluate to different results after optimization in {code}",
540+
)
513541
else:
514542
self.assertIsInstance(
515543
orig_res,

uplc/optimizer/deduplicate.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ def generic_visit(self, node: AST):
3232
# or even their appearance (e.g. if we apply an error to a lambda in which the errors is not in the body)
3333
_CONSTANT_FINAL_RESULTS = (
3434
Constant,
35-
Variable,
3635
ForcedBuiltIn,
3736
BuiltIn,
3837
Lambda,
@@ -54,6 +53,10 @@ def generic_visit(self, node: AST):
5453
from ..tools import flatten
5554

5655
super().generic_visit(node)
56+
# check if it is a constant final result, if not we can not safely optimize it
57+
# TODO For others, we can wrap them into delay and force the called variable, but need to really check size impact then
58+
if not isinstance(node, _CONSTANT_FINAL_RESULTS):
59+
return
5760
# first check whether there are any unbound variables
5861
unbound = UnboundVariableVisitor()
5962
unbound.visit(node)

0 commit comments

Comments
 (0)