All Projects → techcentaur → Krivine-Machine

techcentaur / Krivine-Machine

Licence: other
Abstract krivine machine implementing call-by-name semantics. In OCaml.

Programming Languages

ocaml
1615 projects

Projects that are alternatives of or similar to Krivine-Machine

lambda-zero
A minimalist pure lazy functional programming language
Stars: ✭ 65 (+91.18%)
Mutual labels:  lambda-calculus, krivine-machine
vanilla-lang
An implementation of a predicative polymorphic language with bidirectional type inference and algebraic data types
Stars: ✭ 73 (+114.71%)
Mutual labels:  lambda-calculus
BOHM1.1
Bologna Optimal Higher-Order Machine, Version 1.1
Stars: ✭ 45 (+32.35%)
Mutual labels:  lambda-calculus
lispkit
FUNCTIONAL PROGRAMMING: Application and Implementation, Peter Henderson, ISBN 0-13-331579-7
Stars: ✭ 33 (-2.94%)
Mutual labels:  secd
gidti
Book: Gentle Introduction to Dependent Types with Idris
Stars: ✭ 70 (+105.88%)
Mutual labels:  lambda-calculus
system-F
Formalization of the polymorphic lambda calculus and its parametricity theorem
Stars: ✭ 20 (-41.18%)
Mutual labels:  lambda-calculus
Curryhoward
Automatic code generation for Scala functions and expressions via the Curry-Howard isomorphism
Stars: ✭ 229 (+573.53%)
Mutual labels:  lambda-calculus
salt
The compilation target that functional programmers always wanted.
Stars: ✭ 62 (+82.35%)
Mutual labels:  lambda-calculus
SECD
Scheme on SECD
Stars: ✭ 38 (+11.76%)
Mutual labels:  secd
universe-of-syntax
A universe of scope- and type-safe syntaxes (syntices?). Includes generic implementation of type-preserving renaming/substitution with all the proofs you could possibly need.
Stars: ✭ 16 (-52.94%)
Mutual labels:  lambda-calculus
pomagma
An inference engine for extensional untyped λ-calculus
Stars: ✭ 15 (-55.88%)
Mutual labels:  lambda-calculus
lambda
Macro Lambda Calculus
Stars: ✭ 38 (+11.76%)
Mutual labels:  lambda-calculus
lambda-notebook
Lambda Notebook: Formal Semantics in Jupyter
Stars: ✭ 16 (-52.94%)
Mutual labels:  lambda-calculus
js-church-encoding
Church Encoding Implementation in JavaScript
Stars: ✭ 33 (-2.94%)
Mutual labels:  lambda-calculus
LambdaCalculusPlayground
An Android app that provides a visual interface for creating and evaluating lambda calculus expressions
Stars: ✭ 16 (-52.94%)
Mutual labels:  lambda-calculus
StepULC
Efficient and single-steppable ULC evaluation algorithm
Stars: ✭ 15 (-55.88%)
Mutual labels:  lambda-calculus
meta-cedille
Minimalistic dependent type theory with syntactic metaprogramming
Stars: ✭ 40 (+17.65%)
Mutual labels:  lambda-calculus
WebAssembly-illustrated
WebAssembly (Wasm) illustrated
Stars: ✭ 70 (+105.88%)
Mutual labels:  abstract-machine
lambda
lambda calculus interpreter
Stars: ✭ 23 (-32.35%)
Mutual labels:  lambda-calculus
lambda-calculus
An introduction to the Lambda Calculus
Stars: ✭ 59 (+73.53%)
Mutual labels:  lambda-calculus

Krivine-Machine

Following is the implementation of an abstract machine in OCaml namely krivine machine which implements call-by-name semantics. There exists another abstract machine namely secd machine which implements call-by-value semantics, whose code can be found here.

What are abstract machines?

Abstract machines got the name abstract because they permit step-by-step execution of programs and also because they omit the many details of real(hardware) machines. They bridge the gap between the high level of a programming language and the low level of a real machine. The instructions of an abstract machine are tailored to the particular operations required to implement operations of a specific source language or class of source languages.

More about it can be found here.

Krivine Machine

The Krivine machine is a simple and natural implementation of the weak-head call-by-name reduction strategy for pure λ-terms. More specifically it aims to define rigorously head normal form reduction of a lambda term using call-by-name reduction. On the other hand Krivine machine implements call-by-name because it evaluates the body of a β-redex before it evaluates its parameter

What is a call-by-name startegy?

Call by name is an evaluation strategy where the arguments to a function are not evaluated before the function is called—rather, they are substituted directly into the function body(using the closures) and then left to be evaluated whenever they appear in the function. If an argument is not used in the function body, the argument is never evaluated; if it is used several times, it is re-evaluated each time it appears, which can be optimized more to be evaluated just once and put it over some stack from which it can called everytime there is a need. More about it can be found here

Language of expressions

For this implementation of krivine abstract machine, we consider a tiny language consisting of expressions, having the key operations of Lambda abstraction (lamba.x e), application of the abstraction (e1(e2)) and also some base operations on integer.

type exp = Int of int | Var of string | Abs of string * exp | App of exp * exp;;

Which can be extended to include operations like addition, subtraction, multiplication, division, absolution of a number on integers, and and, or, not operation on boolean types, and also some comparsion operations like greater than, less than, equal, greater than or equal, less than or equal, and also some conditional statements like if-then-else. The OCaml representations of which on expressions can be defined as -

type exp = Nil | Int of int | Bool of bool | Var of string | Abs of string * exp | App of exp * exp | Absolute of exp| Not of exp
	| Add of exp*exp| Sub of exp*exp| Div of exp*exp| Mul of exp*exp| Mod of exp*exp| Exp of exp*exp
	| And of exp*exp| Or of exp*exp| Imp of exp*exp
	| Equ of exp*exp| GTEqu of exp*exp| LTEqu of exp*exp| Grt of exp*exp| Lst of exp*exp
	| Ifthenelse of (exp*exp*exp);;

Krivine evaluation

Whenever we have a list of expressions (say program), we evaluate its each expression by defining it as an closure of the tuple of the expression and the environment closure. For the k-machine we also need an stack of closures.

Types

The type of the above syntax can be defined in OCaml as

type stackCLOS = closure list
	and closure = CLtype of exp*environmentCLOS
		and environmentCLOS = (exp*closure) list;;

Lookup of variable

On facing a base closure type, where the expression is a Integer, or boolean, or Nil; we return the some closure type. Whereas, when facing a closure type with a variable in it, we look up the variable in the attached enviornment and if found, we then insert that closure whose expression is the same as we looked up, into its environment and return the closure type. Implementation of such lookup function can be defined as

let rec lookup (e, env) = match (e, env) with
	| (e, (e1,cl)::c') -> if e1<>e then lookup (e, c') else
					(match cl with
					| CLtype (Abs (x,x1), env) -> CLtype (Abs (x, x1), (e1,cl)::env)
					| _ -> cl)
	| (e, []) -> raise Variable_not_intialized;;

Abstraction

Now, for abstraction on lambda-calculi, we define this function as

(* val absApplied : closure * closure list -> closure * closure list = <fun> *)

Whenver we face a closure with the expression as an abstraction, we put the 'binding variable' with the closure on the top of the stack, meaning the closure of 'bounded variable', and we return this new closure type. This absApplied function is performing the same functionality as stated above.

let absApplied (cl, s) = match (cl, s) with
	| (CLtype(Abs(x ,e), env), c::c') -> (CLtype(e, (Var x ,c)::env), c')
	| (_,[]) -> raise InvalidOperation
	| _ -> raise InvalidOperation;;

Applied function.

The application of function i.e. e1(e2) can be easily defined as

CLtype (App(e1, e2), env) -> krivinemachine (CLtype(e1, env)) (CLtype(e2, env)::s)

where CLtype is the closure.

The tiny krivine machine

All the functionality stated above can be combined to this tiny krivine machine evaluation function.

let rec krivinemachine cl (s:stackCLOS) = match cl with
	| CLtype (Int i, env) -> CLtype (Int i, env)
	| CLtype (Var v, env) -> krivinemachine (lookup (Var(v), env)) s
	| CLtype (Abs(x, e), env) -> 
					let (cl', s') = absApplied (cl, s) in
						krivinemachine cl' s'
	| CLtype (App(e1, e2), env) -> krivinemachine (CLtype(e1, env)) (CLtype(e2, env)::s)

The OCaml code of the krivine machine which various features can be found here.

Contributing

Found a bug or have a suggestion? Feel free to create an issue or make a pull request!

Attention

If this code is one of your assignments, I strongly recommend you to try it out first by yourself. Otherwise, feel free to use it if you want to expand the language or for any other purpose.

Documents for further information

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].