phino-0.0.154: test-resources/evaluate-packs/stops-an-accumulator-recursion-under-plausible.yaml
# SPDX-FileCopyrightText: Copyright (c) 2025 Objectionary.com
# SPDX-License-Identifier: MIT
---
# yamllint disable rule:line-length
# A factorial with an accumulator, under '--acyclic=plausible'. Every round
# wraps the accumulator in one more 'pair' and the counter in one more 'dec',
# so no two rounds are ever the same formation up to a renaming of symbols and
# '--acyclic=proven' never cuts it. The body of 'fact' dispatches 'Ο' off its
# 'if', so 'ml' fires it, and the 'morph' operand of 'L_if' reduces the
# recursive call the same way. The 'if' it reaches on the second round holds
# the one fired on the first, under the wrappers it gained, which is what the
# plausible guard compares by, so the second firing is cut before it opens and
# its 'looped' line names the mode that cut it (#1451). The operand hands back
# the term the cut left, which no 'join' can pair with the datum of the other
# branch, so the first 'L_if' gets stuck and '--partial' parks it.
symbolic: |
- Ξ»: L_zero
dataize:
πΏ1: $.x
π: β¦ Ξ» β€ π β§
- Ξ»: L_dec
dataize:
πΏ1: $.x
π: β¦ Ξ» β€ π β§
- Ξ»: L_if
dataize:
πΏ1: $.c
morph:
π1: $.left
π2: $.right
symbolize:
π3: π1
π4: π2
join:
π5: [π3, π4]
π: π5
location: 'Q.x'
acyclic: plausible
partial: true
input: >
β¦ if β¦ β¦ c β¦ β
, left β¦ β
, right β¦ β
, Ξ» β€ L_if β§,
zero β¦ β¦ x β¦ β
, Ξ» β€ L_zero β§,
dec β¦ β¦ x β¦ β
, Ξ» β€ L_dec β§,
pair β¦ β¦ head β¦ β
, tail β¦ β
β§,
fact β¦ β¦ n β¦ β
, acc β¦ β
, Ο β¦ Ξ¦.if( c β¦ Ξ¦.zero( x β¦ ΞΎ.n ), left β¦ ΞΎ.acc, right β¦ Ξ¦.fact( n β¦ Ξ¦.dec( x β¦ ΞΎ.n ), acc β¦ Ξ¦.pair( head β¦ ΞΎ.n, tail β¦ ΞΎ.acc ) ).Ο ).Ο β§,
x β¦ Ξ¦.fact( n β¦ β¦ Ξ» β€ π1 β§, acc β¦ β¦ Ξ β€ 00- β§ ).Ο β§
result: 'Ξ¦.if( c β¦ Ξ¦.zero( x β¦ π1:Ξ» ), left β¦ 00-:Ξ, right β¦ Ξ¦.fact( n β¦ Ξ¦.dec( x β¦ π1:Ξ» ), acc β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ 00-:Ξ ) ).Ο ).Ο'
protocol: |
π(Ξ¦.x):
πΒ·0Β·1 := Ξ¦.fact( n β¦ π1:Ξ» )
πΒ·0Β·2 := πΒ·0Β·1( acc β¦ 00-:Ξ )
πΒ·0Β·3 := Ξ¦.if( c β¦ Ξ¦.zero( x β¦ π1:Ξ» ) )
πΒ·0Β·4 := πΒ·0Β·3( left β¦ 00-:Ξ )
πΒ·0Β·5 := πΒ·0Β·4( right β¦ Ξ¦.fact( n β¦ Ξ¦.dec( x β¦ π1:Ξ» ), acc β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ 00-:Ξ ) ).Ο )
πΌ(L_if):
π»(Ξ¦.aπ΅0):
π(Ξ¦.aπ΅0):
πΒ·1Β·1 := Ξ¦.zero( x β¦ π1:Ξ» )
πΌ(L_zero):
πΏ1Β·2 := π»(π1:Ξ») # π»(ΞΎ.x)
πΒ·2Β·1 := π2:Ξ» # π
πΒ·2Β·2 := π2:Ξ» # π(πΒ·2Β·1)
πΏ1Β·1 := π»(π2:Ξ») # π»(ΞΎ.c)
π1Β·1 := 00-:Ξ # π(ΞΎ.left)
π(Ξ¦.aπ΅3):
πΒ·1Β·2 := Ξ¦.fact( n β¦ Ξ¦.dec( x β¦ π1:Ξ» ) )
πΒ·1Β·3 := πΒ·1Β·2( acc β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ 00-:Ξ ) )
πΒ·1Β·4 := Ξ¦.if( c β¦ Ξ¦.zero( x β¦ Ξ¦.dec( x β¦ π1:Ξ» ) ) )
πΒ·1Β·5 := πΒ·1Β·4( left β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ 00-:Ξ ) )
πΒ·1Β·6 := πΒ·1Β·5( right β¦ Ξ¦.fact( n β¦ Ξ¦.dec( x β¦ Ξ¦.dec( x β¦ π1:Ξ» ) ), acc β¦ Ξ¦.pair( head β¦ Ξ¦.dec( x β¦ π1:Ξ» ), tail β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ 00-:Ξ ) ) ).Ο )
looped(πΒ·0Β·5) # plausible
π2Β·1 := πΒ·1Β·3.Ο # π(ΞΎ.right)
π»(π3:Ξ») == 00-
π3Β·1 := π3:Ξ» # π1
π»(π4:Ξ») == 00-
π4Β·1 := πΒ·1Β·2( acc β¦ Ξ¦.pair( head β¦ π1:Ξ», tail β¦ π4:Ξ» ) ).Ο # π2
stuck(L_if)