Download idris/Main.idr from Snapkitty/unlambda-idris-spark: direct link, hf CLI and curl.
- Browser
- Download file 3.22 kB
-
https://huggingface.co/Snapkitty/unlambda-idris-spark/resolve/main/idris/Main.idr
- Command line
-
hf download hf://Snapkitty/unlambda-idris-spark/idris/Main.idr
-
curl -L -o Main.idr https://huggingface.co/Snapkitty/unlambda-idris-spark/resolve/main/idris/Main.idr
3.22 kB
| -- Copyright (c) 2026 Ahmad Ali Parr. All rights reserved. | |
| -- SPDX-License-Identifier: LicenseRef-Proprietary | |
| -- Public source visibility does not grant an open-source license. See LICENSE. | |
| module Main | |
| import Data.Nat | |
| %default total | |
| ||| Abstract execution status. Resource exhaustion is not successful termination. | |
| data Status = Running | Halted | OutOfFuel | OutOfMemory | Failed | |
| ||| Minimal control term for the first machine milestone. | |
| ||| Extend only after the selected Unlambda dialect is specified. | |
| data Term = PrimI | PrimK | PrimS | Apply Term Term | DelayedTerm Term | |
| record Machine where | |
| constructor MkMachine | |
| control : Term | |
| fuel : Nat | |
| status : Status | |
| ||| A transition outcome always records the next explicit machine status. | |
| data Transition = Advanced Machine | Finished Machine | |
| ||| Fuel is consumed exactly once for an ordinary transition. | |
| consumeRunning : Term -> Nat -> Machine | |
| consumeRunning t Z = MkMachine t Z OutOfFuel | |
| consumeRunning t (S k) = MkMachine t k Running | |
| consumeFuel : Machine -> Machine | |
| consumeFuel (MkMachine t n Running) = consumeRunning t n | |
| consumeFuel (MkMachine t n Halted) = MkMachine t n Halted | |
| consumeFuel (MkMachine t n OutOfFuel) = MkMachine t n OutOfFuel | |
| consumeFuel (MkMachine t n OutOfMemory) = MkMachine t n OutOfMemory | |
| consumeFuel (MkMachine t n Failed) = MkMachine t n Failed | |
| ||| The transition function is intentionally a control-model stub until | |
| ||| the full Unlambda operational semantics are fixed in spec/. | |
| stepControl : Machine -> Transition | |
| stepControl m@(MkMachine _ Z Running) = Finished (consumeFuel m) | |
| stepControl m@(MkMachine _ (S _) Running) = Advanced (consumeFuel m) | |
| stepControl m = Finished m | |
| ||| A structural fact: consuming fuel never increases the fuel counter. | |
| natLteRefl : (n : Nat) -> LTE n n | |
| natLteRefl Z = LTEZero | |
| natLteRefl (S n) = LTESucc (natLteRefl n) | |
| natLteNext : (n : Nat) -> LTE n (S n) | |
| natLteNext Z = LTEZero | |
| natLteNext (S n) = LTESucc (natLteNext n) | |
| fuelDoesNotIncrease : (m : Machine) -> fuel (consumeFuel m) `LTE` fuel m | |
| fuelDoesNotIncrease (MkMachine t Z Running) = LTEZero | |
| fuelDoesNotIncrease (MkMachine t (S k) Running) = natLteNext k | |
| fuelDoesNotIncrease (MkMachine t n Halted) = natLteRefl n | |
| fuelDoesNotIncrease (MkMachine t n OutOfFuel) = natLteRefl n | |
| fuelDoesNotIncrease (MkMachine t n OutOfMemory) = natLteRefl n | |
| fuelDoesNotIncrease (MkMachine t n Failed) = natLteRefl n | |
| ||| One running transition consumes exactly one unit, not two or zero. | |
| positiveFuelConsumesOne : (t : Term) -> (n : Nat) -> | |
| fuel (consumeFuel (MkMachine t (S n) Running)) = n | |
| positiveFuelConsumesOne t n = Refl | |
| ||| Heap exhaustion remains distinct from generic failure and termination. | |
| memoryExhaustionIsPreserved : (t : Term) -> (n : Nat) -> | |
| status (consumeFuel (MkMachine t n OutOfMemory)) = OutOfMemory | |
| memoryExhaustionIsPreserved t n = Refl | |
| ||| Resource exhaustion is explicit when a running machine has zero fuel. | |
| zeroFuelIsNotHalted : (t : Term) -> status (consumeFuel (MkMachine t Z Running)) = OutOfFuel | |
| zeroFuelIsNotHalted t = Refl | |
| main : IO () | |
| main = do | |
| let initial = MkMachine PrimI 1 Running | |
| case stepControl initial of | |
| Advanced next => putStrLn "step: advanced" | |
| Finished next => putStrLn "step: finished" | |