├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .mailmap ├── CHANGELOG.md ├── LICENSE ├── Makefile ├── README.md ├── SEMANTICS.md ├── benchmark ├── bench.ml ├── bench_de_bruijn.ml ├── church.ml ├── dune ├── lambdas.ml └── scott.ml ├── bindlib.opam ├── docs ├── 4.0.4-ocamldoc │ ├── Bindlib.Lift.html │ ├── Bindlib.Lift2.html │ ├── Bindlib.Map.html │ ├── Bindlib.Map2.html │ ├── Bindlib.html │ ├── html.stamp │ ├── index.html │ ├── index_attributes.html │ ├── index_class_types.html │ ├── index_classes.html │ ├── index_exceptions.html │ ├── index_extensions.html │ ├── index_methods.html │ ├── index_module_types.html │ ├── index_modules.html │ ├── index_types.html │ ├── index_values.html │ ├── style.css │ ├── type_Bindlib.Lift.html │ ├── type_Bindlib.Lift2.html │ ├── type_Bindlib.Map.html │ ├── type_Bindlib.Map2.html │ └── type_Bindlib.html ├── 4.0.5-ocamldoc │ ├── Bindlib.Lift.html │ ├── Bindlib.Lift2.html │ ├── Bindlib.Map.html │ ├── Bindlib.Map2.html │ ├── Bindlib.html │ ├── html.stamp │ ├── index.html │ ├── index_attributes.html │ ├── index_class_types.html │ ├── index_classes.html │ ├── index_exceptions.html │ ├── index_extensions.html │ ├── index_methods.html │ ├── index_module_types.html │ ├── index_modules.html │ ├── index_types.html │ ├── index_values.html │ ├── style.css │ ├── type_Bindlib.Lift.html │ ├── type_Bindlib.Lift2.html │ ├── type_Bindlib.Map.html │ ├── type_Bindlib.Map2.html │ └── type_Bindlib.html ├── 5.0.0-ocamldoc │ ├── Bindlib.Lift.html │ ├── Bindlib.Lift2.html │ ├── Bindlib.Map.html │ ├── Bindlib.Map2.html │ ├── Bindlib.html │ ├── html.stamp │ ├── index.html │ ├── index_attributes.html │ ├── index_class_types.html │ ├── index_classes.html │ ├── index_exceptions.html │ ├── index_extensions.html │ ├── index_methods.html │ ├── index_module_types.html │ ├── index_modules.html │ ├── index_types.html │ ├── index_values.html │ ├── style.css │ ├── type_Bindlib.Lift.html │ ├── type_Bindlib.Lift2.html │ ├── type_Bindlib.Map.html │ ├── type_Bindlib.Map2.html │ └── type_Bindlib.html ├── 5.0.1-ocamldoc │ ├── Bindlib.Lift.html │ ├── Bindlib.Lift2.html │ ├── Bindlib.Map.html │ ├── Bindlib.Map2.html │ ├── Bindlib.html │ ├── html.stamp │ ├── index.html │ ├── index_attributes.html │ ├── index_class_types.html │ ├── index_classes.html │ ├── index_exceptions.html │ ├── index_extensions.html │ ├── index_methods.html │ ├── index_module_types.html │ ├── index_modules.html │ ├── index_types.html │ ├── index_values.html │ ├── style.css │ ├── type_Bindlib.Lift.html │ ├── type_Bindlib.Lift2.html │ ├── type_Bindlib.Map.html │ ├── type_Bindlib.Map2.html │ └── type_Bindlib.html ├── 6.0.0 │ ├── bindlib │ │ ├── Bindlib │ │ │ ├── .dummy │ │ │ ├── Ctxt │ │ │ │ ├── argument-1-R │ │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ │ ├── Lift │ │ │ │ ├── argument-1-M │ │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ │ ├── Lift2 │ │ │ │ ├── argument-1-M │ │ │ │ │ └── index.html │ │ │ │ └── index.html │ │ │ ├── index.html │ │ │ ├── module-type-Map │ │ │ │ └── index.html │ │ │ ├── module-type-Map2 │ │ │ │ └── index.html │ │ │ └── module-type-Renaming │ │ │ │ └── index.html │ │ └── index.html │ ├── highlight.pack.js │ ├── index.html │ └── odoc.css └── index.html ├── dune-project ├── examples ├── basic.expected ├── basic.ml ├── dune ├── fchurch.expected ├── fchurch.ml ├── hashcons.expected ├── hashcons.ml ├── lambda.expected ├── lambda.ml ├── metavar │ ├── ast.ml │ ├── cmd.ml │ ├── dune │ ├── main.expected │ ├── main.ml │ ├── parser.ml │ ├── term.ml │ └── test.txt ├── more_lambda.ml ├── occur_count.ml ├── parsed.expected ├── parsed.ml ├── pred2.expected ├── pred2.ml ├── translate.expected ├── translate.ml ├── unif.expected └── unif.ml └── lib ├── bindlib.ml ├── bindlib.mli ├── dune └── pp.ml /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | branches: 4 | - master 5 | pull_request: 6 | branches: 7 | - master 8 | jobs: 9 | build: 10 | strategy: 11 | fail-fast: false 12 | matrix: 13 | ocaml-version: [ 14 | 4.07.0, 4.07.1, 4.08.0, 4.08.1, 4.09.0, 4.09.1, 4.10.0, 4.10.1, 15 | 4.10.2, 4.11.0, 4.11.1, 4.11.2, 4.12.0, 4.13.0, 4.13.1, 4.14.0, 16 | 4.14.1, 5.0.0, 5.1.0, 5.1.1 17 | ] 18 | runs-on: "ubuntu-latest" 19 | steps: 20 | - name: "Checking out the repo..." 21 | uses: actions/checkout@v2 22 | - name: "Recovering cached opam files..." 23 | uses: actions/cache@v2 24 | with: 25 | path: ~/.opam 26 | key: ${{ runner.os }}-ocaml-${{ matrix.ocaml-version }} 27 | - name: "Setting up opam..." 28 | uses: avsm/setup-ocaml@v1 29 | with: 30 | ocaml-version: ${{ matrix.ocaml-version }} 31 | - name: "Installing dependencies..." 32 | run: | 33 | eval $(opam env) 34 | opam update 35 | opam upgrade 36 | opam pin add -n -k path bindlib . 37 | opam install --deps-only -d -t bindlib 38 | - name: "Running tests..." 39 | run: | 40 | eval $(opam env) 41 | make tests 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .merlin 2 | *~ 3 | _build/ 4 | perf.log 5 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | ## https://github.com/craff 2 | Christophe Raffalli craff 3 | Christophe Raffalli raffalli 4 | Christophe Raffalli christophe.raffalli 5 | Christophe Raffalli craff 6 | Christophe Raffalli craff 7 | Christophe Raffalli Christophe Raffalli 8 | Christophe Raffalli Christophe Raffalli 9 | 10 | ## https://github.com/rlepigre 11 | Rodolphe Lepigre Rodolphe Lepigre 12 | Rodolphe Lepigre rodolphe.lepigre 13 | Rodolphe Lepigre Rodolphe Lepigre 14 | 15 | ## https://github.com/adelaett 16 | Alain alain <90894311+adelaett@users.noreply.github.com> 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | VERSION := 6.0.0 2 | 3 | all: 4 | @dune build 5 | .PHONY: all 6 | 7 | doc: 8 | @dune build @doc 9 | .PHONY: doc 10 | 11 | clean: 12 | @dune clean 13 | .PHONY: clean 14 | 15 | distclean: clean 16 | @find . -name "*~" -type f -exec rm {} \; 17 | .PHONY: distclean 18 | 19 | tests: 20 | @dune runtest 21 | .PHONY: tests 22 | 23 | bench: all 24 | @ulimit -s unlimited && perf stat _build/default/benchmark/church.exe > /dev/null 2> perf.log 25 | @ulimit -s unlimited && perf stat _build/default/benchmark/scott.exe > /dev/null 2>> perf.log 26 | @ulimit -s unlimited && perf stat _build/default/benchmark/lambdas.exe > /dev/null 2>> perf.log 27 | @cat perf.log 28 | @rm perf.log 29 | .PHONY: bench 30 | 31 | promote: 32 | @dune promote 33 | .PHONY: promote 34 | 35 | install: 36 | @dune install 37 | .PHONY: install 38 | 39 | uninstall: 40 | @dune uninstall 41 | .PHONY: uninstall 42 | 43 | ## Documentation webpage 44 | 45 | updatedoc: doc 46 | @rm -rf docs/$(VERSION) 47 | @cp -r _build/default/_doc/_html docs/$(VERSION) 48 | .PHONY: updatedoc 49 | 50 | ## Release 51 | 52 | release: distclean 53 | git push origin 54 | git tag -a $(VERSION) 55 | git push origin $(VERSION) 56 | opam publish 57 | .PHONY: release 58 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | The Bindlib library for OCaml 2 | ============================= 3 | 4 | Bindlib is a library allowing the manipulation of data structures 5 | with bound variables. It is particularly useful when writing ASTs 6 | for programming languages, but also for manipulating terms of the 7 | λ-calculus or quantified formulas. In the internals, binders are 8 | represented using a form of higher-order abstract syntax (HOAS). 9 | 10 | Ressources: 11 | - [Introductory paper](https://eptcs.web.cse.unsw.edu.au/paper.cgi?LFMTP2018.4) 12 | - [Generated documentation](https://rlepigre.github.io/ocaml-bindlib/ocamldoc/Bindlib.html) 13 | 14 | Projects using Bindlib: 15 | - [Lambdapi (implementation of Dedukti)](https://github.com/rlepigre/lambdapi) 16 | - [PML₂ language](https://github.com/rlepigre/pml) 17 | - [SubML language](https://rlepigre.github.io/subml/) 18 | - [PML](https://lama.univ-savoie.fr/tracpml) 19 | - [The Catala language](https://catala-lang.org/) 20 | - Many more small projects... 21 | 22 | Dependencies 23 | ------------ 24 | 25 | List of dependencies: 26 | - OCaml (at least version 4.07.0), 27 | - The Dune build system (at least version 2.7.0). 28 | 29 | Installation 30 | ------------ 31 | 32 | You can either pin the repository with opam or run the following. 33 | ```bash 34 | make 35 | make install 36 | ``` 37 | 38 | Contributors 39 | ------------ 40 | 41 | Main contributors: 42 | - Christophe Raffalli ([@craff](https://github.com/craff), author of the first version) 43 | - Rodolphe Lepigre ([@rlepigre](https://github.com/rlepigre)) 44 | 45 | The project received additional contributions from: 46 | - Alain ([@adelaett](https://github.com/adelaett)) 47 | - Rémi Nollet ([@rnollet](https://github.com/rnollet)) 48 | - Qiancheng Fu ([@qcfu-bu](https://github.com/qcfu-bu)) 49 | -------------------------------------------------------------------------------- /SEMANTICS.md: -------------------------------------------------------------------------------- 1 | Semantics of Bindlib (sketch / work in progress) 2 | ================================================ 3 | 4 | ### Variables 5 | 6 | A variable `x` is represented as a structure with the following fields: 7 | - `x.uid` containing a unique identifier, 8 | - `x.name` containing a prefered name, 9 | - `x.mkfree` a function injectiong the variable in the type of the variable. 10 | 11 | ### Unboxing and environment 12 | 13 | The `unbox` function is specified using an environment `e` (internal to the 14 | implementation), which is an association list from variable unique identifiers 15 | to values. We will write `unbox{e}(v)` to make the environment explicit. 16 | 17 | ### Equational semantics 18 | 19 | ``` 20 | unbox(v) = unbox{[]}(v) 21 | unbox{e}(box v) = v 22 | unbox{e}(apply_box f v) = (unbox{e}(f)) (unbox{e}(v)) 23 | unbox{e}(box_var x) = try List.assoc x.uid e with Not_found -> x.mkfree x 24 | subst (unbox{e}(bind_var x f)) v = unbox{(x.uid,v)::e}(f) 25 | unbox{e}(box_pair v1 v2) = (unbox{e}(v1), unbox{e}(v2)) 26 | unbox{e}(box_list vs) = List.map (fun v -> unbox{e}(v)) vs 27 | 28 | ``` 29 | -------------------------------------------------------------------------------- /benchmark/bench.ml: -------------------------------------------------------------------------------- 1 | type term = 2 | | Var of term Bindlib.var 3 | | Abs of (term, term) Bindlib.binder 4 | | App of term * term 5 | 6 | type tbinder = (term, term) Bindlib.binder 7 | type tvar = term Bindlib.var 8 | type tbox = term Bindlib.box 9 | 10 | let mkfree : tvar -> term = fun x -> Var(x) 11 | 12 | let var : tvar -> tbox = 13 | Bindlib.box_var 14 | 15 | let app : tbox -> tbox -> tbox = 16 | Bindlib.box_apply2 (fun t u -> App(t,u)) 17 | 18 | let abs : tbinder Bindlib.box -> tbox = 19 | Bindlib.box_apply (fun b -> Abs(b)) 20 | 21 | let rec box_term : term -> tbox = fun t -> 22 | match t with 23 | | Var(x) -> var x 24 | | Abs(b) -> abs (Bindlib.box_binder box_term b) 25 | | App(t,u) -> app (box_term t) (box_term u) 26 | 27 | type 'a pp = out_channel -> 'a -> unit 28 | 29 | let pp_term_in : Bindlib.ctxt -> term pp = fun ctxt oc t -> 30 | let pp fmt = Printf.fprintf oc fmt in 31 | let paren_if b = if b then ("(", ")") else ("", "") in 32 | let app_lvl = 2 in 33 | let abs_lvl = 1 in 34 | let ini_lvl = 0 in 35 | let rec print ctxt b _ t = 36 | match t with 37 | | Var(x) -> 38 | pp "%s" (Bindlib.name_of x) 39 | | App(t,u) -> 40 | let (l, r) = paren_if (b >= app_lvl) in 41 | pp "%s%a %a%s" l (print ctxt abs_lvl) t (print ctxt app_lvl) u r 42 | | Abs(_) -> 43 | let (l, r) = paren_if (b >= abs_lvl) in 44 | let rec pp_abs ctxt _ t = 45 | match t with 46 | | Abs(b) -> let (x,t,ctxt) = Bindlib.unbind_in ctxt b in 47 | pp " %s%a" (Bindlib.name_of x) (pp_abs ctxt) t 48 | | _ -> pp ".%a" (print ctxt ini_lvl) t 49 | in 50 | pp "%sλ%a%s" l (pp_abs ctxt) t r 51 | in 52 | print ctxt ini_lvl oc t 53 | 54 | let pp_term : term pp = fun oc t -> 55 | let ctxt = Bindlib.free_vars (box_term t) in 56 | pp_term_in ctxt oc t 57 | 58 | let norm : term -> term = fun t -> 59 | let rec norm t stack = 60 | match t with 61 | | App(t,u) -> norm t (u :: stack) 62 | | Abs(b) -> 63 | begin 64 | match stack with 65 | | u :: stack -> norm (Bindlib.subst b u) stack 66 | | [] -> 67 | if Bindlib.binder_closed b then Bindlib.box t else 68 | let (x,t) = Bindlib.unbind b in 69 | abs (Bindlib.bind_var x (norm t [])) 70 | end 71 | | Var(x) -> 72 | List.fold_left (fun t u -> app t (norm u [])) (var x) stack 73 | in 74 | Bindlib.unbox (norm t []) 75 | 76 | let lam x f = 77 | let x = Bindlib.new_var mkfree x in 78 | abs (Bindlib.bind_var x (f (var x))) 79 | 80 | let zero = 81 | lam "f" (fun _ -> lam "x" (fun x -> x)) 82 | let zero_ = Bindlib.unbox zero 83 | 84 | let succ = 85 | lam "n" (fun n -> lam "f" (fun f -> lam "x" (fun x -> 86 | app f (app (app n f) x) 87 | ))) 88 | let succ_ = Bindlib.unbox succ 89 | 90 | let plus = 91 | lam "n" (fun n -> lam "m" (fun m -> lam "f" (fun f -> lam "x" (fun x -> 92 | app (app n f) (app (app m f) x) 93 | )))) 94 | let plus_ = Bindlib.unbox plus 95 | 96 | let mult = 97 | lam "n" (fun n -> lam "m" (fun m -> lam "f" (fun f -> 98 | app n (app m f)))) 99 | let mult_ = Bindlib.unbox mult 100 | 101 | let pred = 102 | lam "n" (fun n -> 103 | app (app (app (app n ( 104 | lam "p" (fun p -> lam "x" (fun x -> lam "y" (fun _ -> 105 | app (app p (app succ x)) x 106 | ))))) (lam "x" (fun _ -> lam "y" (fun y -> y)))) zero) zero 107 | ) 108 | let pred_ = Bindlib.unbox pred 109 | 110 | let nat_2 = App(succ_, App(succ_, zero_)) 111 | let nat_4 = App(nat_2, nat_2) 112 | let nat_8 = App(App(plus_, nat_4), nat_4) 113 | let nat_10 = App(App(plus_, nat_2), nat_8) 114 | let nat_100 = App(App(mult_, nat_10), nat_10) 115 | let nat_400 = App(App(mult_, nat_4), nat_100) 116 | let nat_1000 = App(App(mult_, nat_100), nat_10) 117 | let nat_4000 = App(App(mult_, nat_4), nat_1000) 118 | 119 | let t0 = App(App(nat_4000, pred_), nat_4000) 120 | let t1 = App(App(mult_, nat_400), nat_1000) 121 | 122 | let _ = 123 | Printf.printf "Normalising: %a\n%!" pp_term t0; 124 | let t0_nf = norm t0 in 125 | Printf.printf "Result: %a\n%!" pp_term t0_nf; 126 | Printf.printf "Normalising \"%a\"\n%!" pp_term t1; 127 | let _ = norm t1 in 128 | Printf.printf "Result: ... (too big)\n%!"; 129 | (* let t1_nf = norm t1 in *) 130 | (* Printf.printf "%a\n%!" pp_term t1_nf; *) 131 | let max_words = Gc.((stat ()).top_heap_words) in 132 | Printf.eprintf "Max major heap size (in words): %i\n%!" max_words 133 | -------------------------------------------------------------------------------- /benchmark/church.ml: -------------------------------------------------------------------------------- 1 | (** Representation of pure λ-terms. *) 2 | type term = 3 | | Var of term Bindlib.var 4 | (** Free variables. *) 5 | | Abs of (term, term) Bindlib.binder 6 | (** Abstraction. *) 7 | | App of term * term 8 | (** Application. *) 9 | 10 | (** Synonym for the type of λ-variables. *) 11 | type tvar = term Bindlib.var 12 | 13 | (** Synonym for the type of boxed terms. *) 14 | type tbox = term Bindlib.box 15 | 16 | (** Injection of free variables into terms. *) 17 | let mkfree : tvar -> term = fun x -> Var(x) 18 | 19 | (** Smart constructor for free variables. *) 20 | let var : tvar -> tbox = Bindlib.box_var 21 | 22 | (** Smart constructor for abstractions. *) 23 | let abs : (term, term) Bindlib.binder Bindlib.box -> tbox = 24 | Bindlib.box_apply (fun b -> Abs(b)) 25 | 26 | (** Smart constructor for applications. *) 27 | let app : tbox -> tbox -> tbox = 28 | Bindlib.box_apply2 (fun t u -> App(t,u)) 29 | 30 | (** Printing function for terms. *) 31 | let print_term : out_channel -> term -> unit = 32 | let open Printf in 33 | let rec print ctx (p : [`Atm | `App | `Fun]) oc t = 34 | match (t, p) with 35 | | (Var(x) , _ ) -> output_string oc (Bindlib.name_of x) 36 | | (Abs(b) , `Fun) -> let (x, t,ctx) = Bindlib.unbind_in ctx b in 37 | fprintf oc "λ%s.%a" (Bindlib.name_of x) 38 | (print ctx p) t 39 | | (App(t,u), `Fun) 40 | | (App(t,u), `App) -> fprintf oc "%a %a" (print ctx `App) t 41 | (print ctx `Atm) u 42 | | (_ , _ ) -> fprintf oc "(%a)" (print ctx `Fun) t 43 | in 44 | print Bindlib.empty_ctxt `Fun 45 | 46 | (** Weak head normalization function. *) 47 | let wh_norm : term -> term = fun t -> 48 | let rec wh_norm t s = 49 | match (t, s) with 50 | | (App(t,u), _ ) -> wh_norm t (u::s) 51 | | (Abs(f) , a::s) -> wh_norm (Bindlib.subst f a) s 52 | | (_ , _ ) -> List.fold_left (fun t u -> App(t,u)) t s 53 | in 54 | wh_norm t [] 55 | 56 | (** Full normalization. *) 57 | let norm : term -> term = fun t -> 58 | let rec norm : term -> term list -> tbox = fun t s -> 59 | match t with 60 | | Var(x) -> List.fold_left (fun t u -> app t (norm u [])) (var x) s 61 | | App(t,u) -> norm t (u::s) 62 | | Abs(f) -> 63 | match s with 64 | | a::s -> norm (Bindlib.subst f a) s 65 | | [] -> let (x,t) = Bindlib.unbind f in 66 | abs (Bindlib.bind_var x (norm t [])) 67 | in 68 | Bindlib.unbox (norm t []) 69 | 70 | let top0 = Gc.(stat ()).minor_words 71 | 72 | (** Examples of terms. *) 73 | 74 | let (>>=) x t = abs (Bindlib.bind_var x t) 75 | let (!!) x = var x 76 | 77 | let x = Bindlib.new_var mkfree "x" 78 | let y = Bindlib.new_var mkfree "y" 79 | let t = Bindlib.new_var mkfree "t" 80 | let f = Bindlib.new_var mkfree "f" 81 | let n = Bindlib.new_var mkfree "n" 82 | let m = Bindlib.new_var mkfree "m" 83 | let p = Bindlib.new_var mkfree "p" 84 | 85 | let id = Bindlib.unbox (x >>= !!x) 86 | let delta = Bindlib.unbox (x >>= app !!x !!x) 87 | let zero = Bindlib.unbox (f >>= (x >>= !!x)) 88 | let tfls = Bindlib.unbox (t >>= (f >>= !!f)) 89 | let ttru = Bindlib.unbox (t >>= (f >>= !!t)) 90 | 91 | let succ = 92 | Bindlib.unbox (n >>= (f >>= (x >>= (app !!f (app (app !!n !!f) !!x))))) 93 | 94 | let succ' = 95 | Bindlib.unbox (n >>= (f >>= (x >>= (app (app !!n !!f) (app !!f !! x))))) 96 | 97 | let plus = Bindlib.unbox 98 | (n >>= (m >>= (f >>= (x >>= (app (app !!n !!f) (app (app !!m !!f) !!x)))))) 99 | 100 | let mult = Bindlib.unbox 101 | (n >>= (m >>= (f >>= (app !!n (app !!m !!f))))) 102 | 103 | let pred = Bindlib.unbox 104 | (n >>= app (app (app (app !!n (p >>= (x >>= (y >>= ( 105 | app (app !!p (app (Bindlib.box succ) !!x)) !!x))))) 106 | (x >>= (y >>= !!y))) (Bindlib.box zero)) (Bindlib.box zero)) 107 | 108 | let ch_2 = App(succ, App(succ, zero)) 109 | let ch_4 = App(ch_2, ch_2) 110 | let ch_8 = App(App(plus, ch_4), ch_4) 111 | let ch_10 = App(App(plus, ch_2), ch_8) 112 | let ch_100 = App(App(mult, ch_10), ch_10) 113 | let ch_1000= App(App(mult, ch_100), ch_10) 114 | 115 | let bench () = 116 | let fh = App(App(mult, ch_4), ch_100 ) in 117 | let ft = App(App(mult, ch_4), ch_1000) in 118 | let res = norm (App(App(ft, pred), ft)) in 119 | Printf.printf "Result: %a\n%!" print_term res; 120 | (*let res = norm (App(App(mult, fh), ch_1000)) in 121 | Printf.printf "Result: %a\n%!" print_term res;*) 122 | let _ = norm (App(App(mult, fh), ch_100)) in 123 | Printf.printf "Result: ...\n%!"; 124 | let _ = norm (App(App(mult, fh), ch_1000)) in 125 | let zz = norm (App(App(ch_1000,pred),ch_1000)) in 126 | Printf.printf "Result: %a\n%!" print_term zz; 127 | Printf.printf "Minor words: %f\n%!" Gc.((stat ()).minor_words -. top0) 128 | 129 | let _ = bench () 130 | -------------------------------------------------------------------------------- /benchmark/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name church) 3 | (modules Church) 4 | (libraries bindlib)) 5 | 6 | (executable 7 | (name scott) 8 | (modules Scott) 9 | (libraries bindlib)) 10 | 11 | (executable 12 | (name lambdas) 13 | (modules Lambdas) 14 | (libraries bindlib)) 15 | 16 | (executable 17 | (name bench_de_bruijn) 18 | (modules Bench_de_bruijn)) 19 | 20 | (executable 21 | (name bench) 22 | (modules Bench) 23 | (libraries bindlib)) 24 | -------------------------------------------------------------------------------- /benchmark/scott.ml: -------------------------------------------------------------------------------- 1 | (** Representation of pure λ-terms. *) 2 | type term = 3 | | Var of term Bindlib.var 4 | (** Free variables. *) 5 | | Abs of (term, term) Bindlib.binder 6 | (** Abstraction. *) 7 | | App of term * term 8 | (** Application. *) 9 | 10 | (** Synonym for the type of λ-variables. *) 11 | type tvar = term Bindlib.var 12 | 13 | (** Synonym for the type of boxed terms. *) 14 | type tbox = term Bindlib.box 15 | 16 | (** Injection of free variables into terms. *) 17 | let mkfree : tvar -> term = fun x -> Var(x) 18 | 19 | (** Smart constructor for free variables. *) 20 | let var : tvar -> tbox = Bindlib.box_var 21 | 22 | (** Smart constructor for abstractions. *) 23 | let abs : (term, term) Bindlib.binder Bindlib.box -> tbox = 24 | Bindlib.box_apply (fun b -> Abs(b)) 25 | 26 | (** Smart constructor for applications. *) 27 | let app : tbox -> tbox -> tbox = 28 | Bindlib.box_apply2 (fun t u -> App(t,u)) 29 | 30 | (** Printing function for terms. *) 31 | let print_term : out_channel -> term -> unit = 32 | let open Printf in 33 | let rec print ctx (p : [`Atm | `App | `Fun]) oc t = 34 | match (t, p) with 35 | | (Var(x) , _ ) -> output_string oc (Bindlib.name_of x) 36 | | (Abs(b) , `Fun) -> let (x, t,ctx) = Bindlib.unbind_in ctx b in 37 | fprintf oc "λ%s.%a" (Bindlib.name_of x) 38 | (print ctx p) t 39 | | (App(t,u), `Fun) 40 | | (App(t,u), `App) -> fprintf oc "%a %a" (print ctx `App) t 41 | (print ctx `Atm) u 42 | | (_ , _ ) -> fprintf oc "(%a)" (print ctx `Fun) t 43 | in 44 | print Bindlib.empty_ctxt `Fun 45 | 46 | (** Weak head normalization function. *) 47 | let wh_norm : term -> term = fun t -> 48 | let rec wh_norm t s = 49 | match (t, s) with 50 | | (App(t,u), _ ) -> wh_norm t (u::s) 51 | | (Abs(f) , a::s) -> wh_norm (Bindlib.subst f a) s 52 | | (_ , _ ) -> List.fold_left (fun t u -> App(t,u)) t s 53 | in 54 | wh_norm t [] 55 | 56 | (** Full normalization. *) 57 | let norm : term -> term = fun t -> 58 | let rec norm : term -> term list -> tbox = fun t s -> 59 | match t with 60 | | Var(x) -> List.fold_left (fun t u -> app t (norm u [])) (var x) s 61 | | App(t,u) -> norm t (u::s) 62 | | Abs(f) -> 63 | match s with 64 | | a::s -> norm (Bindlib.subst f a) s 65 | | [] -> let (x,t) = Bindlib.unbind f in 66 | abs (Bindlib.bind_var x (norm t [])) 67 | in 68 | Bindlib.unbox (norm t []) 69 | 70 | let top0 = Gc.(stat ()).minor_words 71 | 72 | (** Examples of terms. *) 73 | let (>>=) x t = abs (Bindlib.bind_var x t) 74 | let (!!) x = var x 75 | 76 | let x = Bindlib.new_var mkfree "x" 77 | let y = Bindlib.new_var mkfree "y" 78 | let t = Bindlib.new_var mkfree "t" 79 | let f = Bindlib.new_var mkfree "f" 80 | let n = Bindlib.new_var mkfree "n" 81 | let m = Bindlib.new_var mkfree "m" 82 | let p = Bindlib.new_var mkfree "p" 83 | let r = Bindlib.new_var mkfree "r" 84 | let app2 f x y = app(app f x) y 85 | let bb f = Bindlib.box f 86 | let bb1 f x = app (Bindlib.box f) x 87 | let bb2 f x y = app2 (Bindlib.box f) x y 88 | 89 | let id = Bindlib.unbox (x >>= !!x) 90 | let delta = Bindlib.unbox (x >>= app !!x !!x) 91 | let zero = Bindlib.unbox (f >>= (x >>= !!x)) 92 | let tfls = Bindlib.unbox (t >>= (f >>= !!f)) 93 | let ttru = Bindlib.unbox (t >>= (f >>= !!t)) 94 | let delta_fix 95 | = (x >>= (f >>= app !!f (app2 !!x !!x !!f))) 96 | let fix = Bindlib.unbox (app delta_fix delta_fix) 97 | 98 | let succ = 99 | Bindlib.unbox (n >>= (f >>= (x >>= (app !!f !!n)))) 100 | 101 | 102 | let plus = 103 | Bindlib.unbox 104 | (bb1 fix (r >>= (n >>= (m >>= ( 105 | app2 !!n (p >>= bb1 succ (app2 !!r !!m !!p)) !!m))))) 106 | 107 | let mult = 108 | Bindlib.unbox 109 | (bb1 fix (r >>= (n >>= (m >>= ( 110 | app2 !!n (p >>= bb2 plus (app2 !!r !!m !!p) !!m) (bb zero)))))) 111 | 112 | let pred = 113 | Bindlib.unbox 114 | (n >>= (app2 !!n (p >>= !!p) (bb zero))) 115 | 116 | let iter = 117 | Bindlib.unbox 118 | (bb1 fix (r >>= (n >>= (f >>= (x >>= ( 119 | app2 !!n (p >>= app !!f (app2 (app !!r !!p) !!f !!x)) !!x)))))) 120 | 121 | let sc_2 = App(succ, App(succ, zero)) 122 | let sc_4 = App(App(mult,sc_2), sc_2) 123 | let sc_8 = App(App(plus, sc_4), sc_4) 124 | let sc_10 = App(App(plus, sc_2), sc_8) 125 | let sc_100 = App(App(mult, sc_10), sc_10) 126 | let sc_1000= App(App(mult, sc_100), sc_10) 127 | let sc_10000= App(App(mult, sc_100), sc_100) 128 | let sc_1000000= App(App(mult, sc_1000), sc_1000) 129 | 130 | let bench () = 131 | let res = norm (App(pred,sc_4)) in 132 | Printf.printf "Result: %a\n%!" print_term res; 133 | let fh = App(App(mult, sc_4), sc_100 ) in 134 | let ft = App(App(mult, sc_4), sc_1000) in 135 | let res = norm (App(App(App(iter,ft), pred), ft)) in 136 | Printf.printf "Result: %a\n%!" print_term res; 137 | let _ = norm (App(App(mult, fh), sc_100)) in 138 | Printf.printf "Result: ...\n%!"; 139 | let _ = norm (App(App(mult, fh), fh)) in 140 | Printf.printf "Result: ...\n%!"; 141 | let res = norm (App(App(App(iter,sc_10000),pred),sc_10000)) in 142 | Printf.printf "Result: %a\n%!" print_term res; 143 | Printf.printf "Minor words: %f\n%!" Gc.((stat ()).minor_words -. top0) 144 | 145 | let _ = bench () 146 | -------------------------------------------------------------------------------- /bindlib.opam: -------------------------------------------------------------------------------- 1 | # This file is generated by dune, edit dune-project instead 2 | opam-version: "2.0" 3 | synopsis: "OCaml Bindlib library for bound variables" 4 | description: """ 5 | The Bindlib library provides support for free and bound variables in the 6 | OCaml language. The main application is the representation of types with 7 | a binding structure (e.g., abstract syntax trees).""" 8 | maintainer: [ 9 | "Rodolphe Lepigre " 10 | "Christophe Raffalli " 14 | "Christophe Raffalli = "4.07.0"} 21 | "dune" {>= "2.7" & build} 22 | "timed" {>= "1.0" & with-test} 23 | "pacomb" {>= "1.1" & with-test} 24 | "odoc" {with-doc} 25 | ] 26 | build: [ 27 | ["dune" "subst"] {dev} 28 | [ 29 | "dune" 30 | "build" 31 | "-p" 32 | name 33 | "-j" 34 | jobs 35 | "@install" 36 | "@runtest" {with-test} 37 | "@doc" {with-doc} 38 | ] 39 | ] 40 | dev-repo: "git+https://github.com/rlepigre/ocaml-bindlib.git" 41 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift 15 | 16 | 17 | 20 |

Functor Bindlib.Lift

21 | 22 |
module Lift (M : Map) : sig .. end
23 |
24 |

Functorial interface used to build lifting functions (i.e., functions that 25 | permute the 'a bindbox type with another type constructor) for any type 26 | equipped with a map function.

27 |
28 |
29 | 30 | 31 | 32 | 41 | 42 |
Parameters: 33 | 34 | 35 | 37 | 38 |
36 | M:Map 39 |
40 |
43 |
44 | 45 |
val lift_box : 'a Bindlib.bindbox M.t -> 'a M.t Bindlib.bindbox
46 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift2 15 | 16 | 17 | 20 |

Functor Bindlib.Lift2

21 | 22 |
module Lift2 (M : Map2) : sig .. end
23 |
24 |

Similar to the Lift functor, but handles "binary" map functions.

25 |
26 |
27 | 28 | 29 | 30 | 39 | 40 |
Parameters: 31 | 32 | 33 | 35 | 36 |
34 | M:Map2 37 |
38 |
41 |
42 | 43 |
val lift_box : ('a Bindlib.bindbox, 'b Bindlib.bindbox) M.t -> ('a, 'b) M.t Bindlib.bindbox
44 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map 15 | 16 | 17 | 20 |

Module type Bindlib.Map

21 | 22 |
module type Map = sig .. end
23 |
24 |

Type of a module equipped with a map function.

25 |
26 |
27 |
28 | 29 |
type 'a t 
30 | 31 | 32 |
val map : ('a -> 'b) -> 'a t -> 'b t
33 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map2 15 | 16 | 17 | 20 |

Module type Bindlib.Map2

21 | 22 |
module type Map2 = sig .. end
23 |
24 |

Type of a module equipped with a "binary" map function.

25 |
26 |
27 |
28 | 29 |
type ('a, 'b) t 
30 | 31 | 32 |
val map : ('a -> 'b) ->
('c -> 'd) -> ('a, 'c) t -> ('b, 'd) t
33 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/html.stamp: -------------------------------------------------------------------------------- 1 | 949fefa598e832d2d8853aab9b452642 -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 31 |
Bindlib
26 |

The Bindlib library provides support for free and bound variables in the 27 | OCaml language.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class attributes 12 | 13 | 14 | 16 |

Index of class attributes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_class_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class types 12 | 13 | 14 | 16 |

Index of class types

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of classes 12 | 13 | 14 | 16 |

Index of classes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_exceptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of exceptions 12 | 13 | 14 | 16 |

Index of exceptions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of extensions 12 | 13 | 14 | 16 |

Index of extensions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class methods 12 | 13 | 14 | 16 |

Index of class methods

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_module_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of module types 12 | 13 | 14 | 16 |

Index of module types

17 | 18 | 19 | 20 | 25 | 26 | 31 |
M
Map [Bindlib]
21 |

Type of a module equipped with a map function.

22 | 23 |
24 |
Map2 [Bindlib]
27 |

Type of a module equipped with a "binary" map function.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of modules 12 | 13 | 14 | 16 |

Index of modules

17 | 18 | 19 | 20 | 26 | 27 | 28 | 35 | 36 | 41 |
B
Bindlib
21 |

The Bindlib library provides support for free and bound variables in the 22 | OCaml language.

23 | 24 |
25 |
L
Lift [Bindlib]
29 |

Functorial interface used to build lifting functions (i.e., functions that 30 | permute the 'a bindbox type with another type constructor) for any type 31 | equipped with a map function.

32 | 33 |
34 |
Lift2 [Bindlib]
37 |

Similar to the Lift functor, but handles "binary" map functions.

38 | 39 |
40 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/index_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of types 12 | 13 | 14 | 16 |

Index of types

17 | 18 | 19 | 20 | 25 | 26 | 31 | 32 | 33 | 38 | 39 | 40 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 |
B
bindbox [Bindlib]
21 |

Type of a term of type 'a under construction.

22 | 23 |
24 |
binder [Bindlib]
27 |

Type of a binder for an element of type 'a into an element of type 'b.

28 | 29 |
30 |
C
ctxt [Bindlib]
34 |

Type of a context.

35 | 36 |
37 |
M
mbinder [Bindlib]
41 |

Type of a binder for an array of elements of type 'a into an element of 42 | type 'b.

43 | 44 |
45 |
mvar [Bindlib]
48 |

Type of an array of variables of type 'a.

49 | 50 |
51 |
T
t [Bindlib.Map2]
t [Bindlib.Map]
V
var [Bindlib]
60 |

Type of a free variable of type 'a.

61 | 62 |
63 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/style.css: -------------------------------------------------------------------------------- 1 | .keyword { font-weight : bold ; color : Red } 2 | .keywordsign { color : #C04600 } 3 | .comment { color : Green } 4 | .constructor { color : Blue } 5 | .type { color : #5C6585 } 6 | .string { color : Maroon } 7 | .warning { color : Red ; font-weight : bold } 8 | .info { margin-left : 3em; margin-right: 3em } 9 | .param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em } 10 | .code { color : #465F91 ; } 11 | .typetable { border-style : hidden } 12 | .paramstable { border-style : hidden ; padding: 5pt 5pt} 13 | tr { background-color : White } 14 | td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;} 15 | div.sig_block {margin-left: 2em} 16 | *:target { background: yellow; } 17 | body {font: 13px sans-serif; color: black; text-align: left; padding: 5px; margin: 0} 18 | h1 { font-size : 20pt ; text-align: center; } 19 | h2 { font-size : 20pt ; text-align: center; } 20 | h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; } 21 | h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; } 22 | h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; } 23 | h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; } 24 | div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ; padding: 2px; } 25 | div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; } 26 | div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; } 27 | div.h10 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; } 28 | a {color: #416DFF; text-decoration: none} 29 | a:hover {background-color: #ddd; text-decoration: underline} 30 | pre { margin-bottom: 4px; font-family: monospace; } 31 | pre.verbatim, pre.codepre { } 32 | .indextable {border: 1px #ddd solid; border-collapse: collapse} 33 | .indextable td, .indextable th {border: 1px #ddd solid; min-width: 80px} 34 | .indextable td.module {background-color: #eee ; padding-left: 2px; padding-right: 2px} 35 | .indextable td.module a {color: #4E6272; text-decoration: none; display: block; width: 100%} 36 | .indextable td.module a:hover {text-decoration: underline; background-color: transparent} 37 | .deprecated {color: #888; font-style: italic} 38 | .indextable tr td div.info { margin-left: 2px; margin-right: 2px } 39 | ul.indexlist { margin-left: 0; padding-left: 0;} 40 | ul.indexlist li { list-style-type: none ; margin-left: 0; padding-left: 0; } 41 | ul.info-attributes {list-style: none; margin: 0; padding: 0; } 42 | div.info > p:first-child { margin-top:0; } 43 | div.info-desc > p:first-child { margin-top:0; margin-bottom:0; } -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/type_Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift 11 | 12 | 13 | functor (M : Map->
14 |   sig val lift_box : 'Bindlib.bindbox M.t -> 'M.t Bindlib.bindbox end
15 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/type_Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift2 11 | 12 | 13 | functor (M : Map2->
14 |   sig
15 |     val lift_box :
16 |       ('Bindlib.bindbox, 'Bindlib.bindbox) M.t ->
17 |       ('a, 'b) M.t Bindlib.bindbox
18 |   end
19 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/type_Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map 11 | 12 | 13 | sig
14 |   type 'a t
15 |   val map : ('-> 'b) -> 'Bindlib.Map.t -> 'Bindlib.Map.t
16 | end
17 | -------------------------------------------------------------------------------- /docs/4.0.4-ocamldoc/type_Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map2 11 | 12 | 13 | sig
14 |   type ('a, 'b) t
15 |   val map :
16 |     ('-> 'b) ->
17 |     ('-> 'd) -> ('a, 'c) Bindlib.Map2.t -> ('b, 'd) Bindlib.Map2.t
18 | end
19 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift 15 | 16 | 17 | 20 |

Functor Bindlib.Lift

21 | 22 |
module Lift (M : Map) : sig .. end
23 |
24 |

Functorial interface used to build lifting functions (i.e., functions that 25 | permute the 'a bindbox type with another type constructor) for any type 26 | equipped with a map function.

27 |
28 |
29 | 30 | 31 | 32 | 41 | 42 |
Parameters: 33 | 34 | 35 | 37 | 38 |
36 | M:Map 39 |
40 |
43 |
44 | 45 |
val lift_box : 'a Bindlib.bindbox M.t -> 'a M.t Bindlib.bindbox
46 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift2 15 | 16 | 17 | 20 |

Functor Bindlib.Lift2

21 | 22 |
module Lift2 (M : Map2) : sig .. end
23 |
24 |

Similar to the Lift functor, but handles "binary" map functions.

25 |
26 |
27 | 28 | 29 | 30 | 39 | 40 |
Parameters: 31 | 32 | 33 | 35 | 36 |
34 | M:Map2 37 |
38 |
41 |
42 | 43 |
val lift_box : ('a Bindlib.bindbox, 'b Bindlib.bindbox) M.t -> ('a, 'b) M.t Bindlib.bindbox
44 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map 15 | 16 | 17 | 20 |

Module type Bindlib.Map

21 | 22 |
module type Map = sig .. end
23 |
24 |

Type of a module equipped with a map function.

25 |
26 |
27 |
28 | 29 |
type 'a t 
30 | 31 | 32 |
val map : ('a -> 'b) -> 'a t -> 'b t
33 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map2 15 | 16 | 17 | 20 |

Module type Bindlib.Map2

21 | 22 |
module type Map2 = sig .. end
23 |
24 |

Type of a module equipped with a "binary" map function.

25 |
26 |
27 |
28 | 29 |
type ('a, 'b) t 
30 | 31 | 32 |
val map : ('a -> 'b) ->
('c -> 'd) -> ('a, 'c) t -> ('b, 'd) t
33 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/html.stamp: -------------------------------------------------------------------------------- 1 | 41af1828f12bea1c22730a4eefb0e0da -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 31 |
Bindlib
26 |

The Bindlib library provides support for free and bound variables in the 27 | OCaml language.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class attributes 12 | 13 | 14 | 16 |

Index of class attributes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_class_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class types 12 | 13 | 14 | 16 |

Index of class types

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of classes 12 | 13 | 14 | 16 |

Index of classes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_exceptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of exceptions 12 | 13 | 14 | 16 |

Index of exceptions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of extensions 12 | 13 | 14 | 16 |

Index of extensions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class methods 12 | 13 | 14 | 16 |

Index of class methods

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_module_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of module types 12 | 13 | 14 | 16 |

Index of module types

17 | 18 | 19 | 20 | 25 | 26 | 31 |
M
Map [Bindlib]
21 |

Type of a module equipped with a map function.

22 | 23 |
24 |
Map2 [Bindlib]
27 |

Type of a module equipped with a "binary" map function.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of modules 12 | 13 | 14 | 16 |

Index of modules

17 | 18 | 19 | 20 | 26 | 27 | 28 | 35 | 36 | 41 |
B
Bindlib
21 |

The Bindlib library provides support for free and bound variables in the 22 | OCaml language.

23 | 24 |
25 |
L
Lift [Bindlib]
29 |

Functorial interface used to build lifting functions (i.e., functions that 30 | permute the 'a bindbox type with another type constructor) for any type 31 | equipped with a map function.

32 | 33 |
34 |
Lift2 [Bindlib]
37 |

Similar to the Lift functor, but handles "binary" map functions.

38 | 39 |
40 |
42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/index_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of types 12 | 13 | 14 | 16 |

Index of types

17 | 18 | 19 | 20 | 25 | 26 | 31 | 32 | 33 | 38 | 39 | 40 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 |
B
bindbox [Bindlib]
21 |

Type of a term of type 'a under construction.

22 | 23 |
24 |
binder [Bindlib]
27 |

Type of a binder for an element of type 'a into an element of type 'b.

28 | 29 |
30 |
C
ctxt [Bindlib]
34 |

Type of a context.

35 | 36 |
37 |
M
mbinder [Bindlib]
41 |

Type of a binder for an array of elements of type 'a into an element of 42 | type 'b.

43 | 44 |
45 |
mvar [Bindlib]
48 |

Type of an array of variables of type 'a.

49 | 50 |
51 |
T
t [Bindlib.Map2]
t [Bindlib.Map]
V
var [Bindlib]
60 |

Type of a free variable of type 'a.

61 | 62 |
63 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/style.css: -------------------------------------------------------------------------------- 1 | .keyword { font-weight : bold ; color : Red } 2 | .keywordsign { color : #C04600 } 3 | .comment { color : Green } 4 | .constructor { color : Blue } 5 | .type { color : #5C6585 } 6 | .string { color : Maroon } 7 | .warning { color : Red ; font-weight : bold } 8 | .info { margin-left : 3em; margin-right: 3em } 9 | .param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em } 10 | .code { color : #465F91 ; } 11 | .typetable { border-style : hidden } 12 | .paramstable { border-style : hidden ; padding: 5pt 5pt} 13 | tr { background-color : White } 14 | td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;} 15 | div.sig_block {margin-left: 2em} 16 | *:target { background: yellow; } 17 | body {font: 13px sans-serif; color: black; text-align: left; padding: 5px; margin: 0} 18 | h1 { font-size : 20pt ; text-align: center; } 19 | h2 { font-size : 20pt ; text-align: center; } 20 | h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; } 21 | h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; } 22 | h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; } 23 | h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; } 24 | div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ; padding: 2px; } 25 | div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; } 26 | div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; } 27 | div.h10 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; } 28 | a {color: #416DFF; text-decoration: none} 29 | a:hover {background-color: #ddd; text-decoration: underline} 30 | pre { margin-bottom: 4px; font-family: monospace; } 31 | pre.verbatim, pre.codepre { } 32 | .indextable {border: 1px #ddd solid; border-collapse: collapse} 33 | .indextable td, .indextable th {border: 1px #ddd solid; min-width: 80px} 34 | .indextable td.module {background-color: #eee ; padding-left: 2px; padding-right: 2px} 35 | .indextable td.module a {color: #4E6272; text-decoration: none; display: block; width: 100%} 36 | .indextable td.module a:hover {text-decoration: underline; background-color: transparent} 37 | .deprecated {color: #888; font-style: italic} 38 | .indextable tr td div.info { margin-left: 2px; margin-right: 2px } 39 | ul.indexlist { margin-left: 0; padding-left: 0;} 40 | ul.indexlist li { list-style-type: none ; margin-left: 0; padding-left: 0; } 41 | ul.info-attributes {list-style: none; margin: 0; padding: 0; } 42 | div.info > p:first-child { margin-top:0; } 43 | div.info-desc > p:first-child { margin-top:0; margin-bottom:0; } -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/type_Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift 11 | 12 | 13 | functor (M : Map->
14 |   sig val lift_box : 'Bindlib.bindbox M.t -> 'M.t Bindlib.bindbox end
15 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/type_Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift2 11 | 12 | 13 | functor (M : Map2->
14 |   sig
15 |     val lift_box :
16 |       ('Bindlib.bindbox, 'Bindlib.bindbox) M.t ->
17 |       ('a, 'b) M.t Bindlib.bindbox
18 |   end
19 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/type_Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map 11 | 12 | 13 | sig
14 |   type 'a t
15 |   val map : ('-> 'b) -> 'Bindlib.Map.t -> 'Bindlib.Map.t
16 | end
17 | -------------------------------------------------------------------------------- /docs/4.0.5-ocamldoc/type_Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map2 11 | 12 | 13 | sig
14 |   type ('a, 'b) t
15 |   val map :
16 |     ('-> 'b) ->
17 |     ('-> 'd) -> ('a, 'c) Bindlib.Map2.t -> ('b, 'd) Bindlib.Map2.t
18 | end
19 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift 15 | 16 | 17 | 20 |

Functor Bindlib.Lift

21 | 22 |
module Lift (M : Map) : sig .. end
23 |
24 |

Functorial interface used to build lifting functions for any type equipped 25 | with a map function. In other words, this function can be used to allow 26 | the permutation of the 'a box type with another type constructor.

27 |
28 |
29 | 30 | 31 | 32 | 41 | 42 |
Parameters: 33 | 34 | 35 | 37 | 38 |
36 | M:Map 39 |
40 |
43 |
44 | 45 |
val lift_box : 'a Bindlib.box M.t -> 'a M.t Bindlib.box
46 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift2 15 | 16 | 17 | 20 |

Functor Bindlib.Lift2

21 | 22 |
module Lift2 (M : Map2) : sig .. end
23 |
24 |

Similar to the Lift functor, but handles "binary" map functions.

25 |
26 |
27 | 28 | 29 | 30 | 39 | 40 |
Parameters: 31 | 32 | 33 | 35 | 36 |
34 | M:Map2 37 |
38 |
41 |
42 | 43 |
val lift_box : ('a Bindlib.box, 'b Bindlib.box) M.t -> ('a, 'b) M.t Bindlib.box
44 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map 15 | 16 | 17 | 20 |

Module type Bindlib.Map

21 | 22 |
module type Map = sig .. end
23 |
24 |

Type of a module equipped with a map function.

25 |
26 |
27 |
28 | 29 |
type 'a t 
30 | 31 | 32 |
val map : ('a -> 'b) -> 'a t -> 'b t
33 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map2 15 | 16 | 17 | 20 |

Module type Bindlib.Map2

21 | 22 |
module type Map2 = sig .. end
23 |
24 |

Type of a module equipped with a "binary" map function.

25 |
26 |
27 |
28 | 29 |
type ('a, 'b) t 
30 | 31 | 32 |
val map : ('a -> 'b) ->
('c -> 'd) -> ('a, 'c) t -> ('b, 'd) t
33 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/html.stamp: -------------------------------------------------------------------------------- 1 | e49ddf0f91e8ac3f2c62abb13a8d876e -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 31 |
Bindlib
26 |

The Bindlib library provides support for free and bound variables in the 27 | OCaml language.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class attributes 12 | 13 | 14 | 16 |

Index of class attributes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_class_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class types 12 | 13 | 14 | 16 |

Index of class types

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of classes 12 | 13 | 14 | 16 |

Index of classes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_exceptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of exceptions 12 | 13 | 14 | 16 |

Index of exceptions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of extensions 12 | 13 | 14 | 16 |

Index of extensions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class methods 12 | 13 | 14 | 16 |

Index of class methods

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_module_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of module types 12 | 13 | 14 | 16 |

Index of module types

17 | 18 | 19 | 20 | 25 | 26 | 31 |
M
Map [Bindlib]
21 |

Type of a module equipped with a map function.

22 | 23 |
24 |
Map2 [Bindlib]
27 |

Type of a module equipped with a "binary" map function.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of modules 12 | 13 | 14 | 16 |

Index of modules

17 | 18 | 19 | 20 | 26 | 27 | 28 | 34 | 35 | 40 |
B
Bindlib
21 |

The Bindlib library provides support for free and bound variables in the 22 | OCaml language.

23 | 24 |
25 |
L
Lift [Bindlib]
29 |

Functorial interface used to build lifting functions for any type equipped 30 | with a map function.

31 | 32 |
33 |
Lift2 [Bindlib]
36 |

Similar to the Lift functor, but handles "binary" map functions.

37 | 38 |
39 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/index_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of types 12 | 13 | 14 | 16 |

Index of types

17 | 18 | 19 | 20 | 25 | 26 | 31 | 32 | 33 | 38 | 39 | 40 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 |
B
binder [Bindlib]
21 |

Type of a binder for an element of type 'a into an element of type 'b.

22 | 23 |
24 |
box [Bindlib]
27 |

Type of a term of type 'a under construction.

28 | 29 |
30 |
C
ctxt [Bindlib]
34 |

Type of a context.

35 | 36 |
37 |
M
mbinder [Bindlib]
41 |

Type of a binder for an array of elements of type 'a into an element of 42 | type 'b.

43 | 44 |
45 |
mvar [Bindlib]
48 |

Type of an array of variables of type 'a.

49 | 50 |
51 |
T
t [Bindlib.Map2]
t [Bindlib.Map]
V
var [Bindlib]
60 |

Type of a free variable of type 'a.

61 | 62 |
63 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/style.css: -------------------------------------------------------------------------------- 1 | .keyword { font-weight : bold ; color : Red } 2 | .keywordsign { color : #C04600 } 3 | .comment { color : Green } 4 | .constructor { color : Blue } 5 | .type { color : #5C6585 } 6 | .string { color : Maroon } 7 | .warning { color : Red ; font-weight : bold } 8 | .info { margin-left : 3em; margin-right: 3em } 9 | .param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em } 10 | .code { color : #465F91 ; } 11 | .typetable { border-style : hidden } 12 | .paramstable { border-style : hidden ; padding: 5pt 5pt} 13 | tr { background-color : White } 14 | td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;} 15 | div.sig_block {margin-left: 2em} 16 | *:target { background: yellow; } 17 | body {font: 13px sans-serif; color: black; text-align: left; padding: 5px; margin: 0} 18 | h1 { font-size : 20pt ; text-align: center; } 19 | h2 { font-size : 20pt ; text-align: center; } 20 | h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; } 21 | h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; } 22 | h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; } 23 | h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; } 24 | div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ; padding: 2px; } 25 | div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; } 26 | div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; } 27 | div.h10 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; } 28 | a {color: #416DFF; text-decoration: none} 29 | a:hover {background-color: #ddd; text-decoration: underline} 30 | pre { margin-bottom: 4px; font-family: monospace; } 31 | pre.verbatim, pre.codepre { } 32 | .indextable {border: 1px #ddd solid; border-collapse: collapse} 33 | .indextable td, .indextable th {border: 1px #ddd solid; min-width: 80px} 34 | .indextable td.module {background-color: #eee ; padding-left: 2px; padding-right: 2px} 35 | .indextable td.module a {color: #4E6272; text-decoration: none; display: block; width: 100%} 36 | .indextable td.module a:hover {text-decoration: underline; background-color: transparent} 37 | .deprecated {color: #888; font-style: italic} 38 | .indextable tr td div.info { margin-left: 2px; margin-right: 2px } 39 | ul.indexlist { margin-left: 0; padding-left: 0;} 40 | ul.indexlist li { list-style-type: none ; margin-left: 0; padding-left: 0; } 41 | ul.info-attributes {list-style: none; margin: 0; padding: 0; } 42 | div.info > p:first-child { margin-top:0; } 43 | div.info-desc > p:first-child { margin-top:0; margin-bottom:0; } -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/type_Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift 11 | 12 | 13 | functor (M : Map->
14 |   sig val lift_box : 'Bindlib.box M.t -> 'M.t Bindlib.box end
15 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/type_Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift2 11 | 12 | 13 | functor (M : Map2->
14 |   sig
15 |     val lift_box :
16 |       ('Bindlib.box, 'Bindlib.box) M.t -> ('a, 'b) M.t Bindlib.box
17 |   end
18 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/type_Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map 11 | 12 | 13 | sig
14 |   type 'a t
15 |   val map : ('-> 'b) -> 'Bindlib.Map.t -> 'Bindlib.Map.t
16 | end
17 | -------------------------------------------------------------------------------- /docs/5.0.0-ocamldoc/type_Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map2 11 | 12 | 13 | sig
14 |   type ('a, 'b) t
15 |   val map :
16 |     ('-> 'b) ->
17 |     ('-> 'd) -> ('a, 'c) Bindlib.Map2.t -> ('b, 'd) Bindlib.Map2.t
18 | end
19 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift 15 | 16 | 17 | 20 |

Functor Bindlib.Lift

21 | 22 |
module Lift (M : Map) : sig .. end
23 |
24 |

Functorial interface used to build lifting functions for any type equipped 25 | with a map function. In other words, this function can be used to allow 26 | the permutation of the 'a box type with another type constructor.

27 |
28 |
29 | 30 | 31 | 32 | 41 | 42 |
Parameters: 33 | 34 | 35 | 37 | 38 |
36 | M:Map 39 |
40 |
43 |
44 | 45 |
val lift_box : 'a Bindlib.box M.t -> 'a M.t Bindlib.box
46 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Lift2 15 | 16 | 17 | 20 |

Functor Bindlib.Lift2

21 | 22 |
module Lift2 (M : Map2) : sig .. end
23 |
24 |

Similar to the Lift functor, but handles "binary" map functions.

25 |
26 |
27 | 28 | 29 | 30 | 39 | 40 |
Parameters: 31 | 32 | 33 | 35 | 36 |
34 | M:Map2 37 |
38 |
41 |
42 | 43 |
val lift_box : ('a Bindlib.box, 'b Bindlib.box) M.t -> ('a, 'b) M.t Bindlib.box
44 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map 15 | 16 | 17 | 20 |

Module type Bindlib.Map

21 | 22 |
module type Map = sig .. end
23 |
24 |

Type of a module equipped with a map function.

25 |
26 |
27 |
28 | 29 |
type 'a t 
30 | 31 | 32 |
val map : ('a -> 'b) -> 'a t -> 'b t
33 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Bindlib.Map2 15 | 16 | 17 | 20 |

Module type Bindlib.Map2

21 | 22 |
module type Map2 = sig .. end
23 |
24 |

Type of a module equipped with a "binary" map function.

25 |
26 |
27 |
28 | 29 |
type ('a, 'b) t 
30 | 31 | 32 |
val map : ('a -> 'b) ->
('c -> 'd) -> ('a, 'c) t -> ('b, 'd) t
33 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/html.stamp: -------------------------------------------------------------------------------- 1 | 979d670470d1d069bf3db2a5c0ad1643 -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 23 | 24 | 25 | 31 |
Bindlib
26 |

The Bindlib library provides support for free and bound variables in the 27 | OCaml language.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_attributes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class attributes 12 | 13 | 14 | 16 |

Index of class attributes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_class_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class types 12 | 13 | 14 | 16 |

Index of class types

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_classes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of classes 12 | 13 | 14 | 16 |

Index of classes

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_exceptions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of exceptions 12 | 13 | 14 | 16 |

Index of exceptions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_extensions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of extensions 12 | 13 | 14 | 16 |

Index of extensions

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_methods.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of class methods 12 | 13 | 14 | 16 |

Index of class methods

17 | 18 |
19 | 20 | 21 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_module_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of module types 12 | 13 | 14 | 16 |

Index of module types

17 | 18 | 19 | 20 | 25 | 26 | 31 |
M
Map [Bindlib]
21 |

Type of a module equipped with a map function.

22 | 23 |
24 |
Map2 [Bindlib]
27 |

Type of a module equipped with a "binary" map function.

28 | 29 |
30 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_modules.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of modules 12 | 13 | 14 | 16 |

Index of modules

17 | 18 | 19 | 20 | 26 | 27 | 28 | 34 | 35 | 40 |
B
Bindlib
21 |

The Bindlib library provides support for free and bound variables in the 22 | OCaml language.

23 | 24 |
25 |
L
Lift [Bindlib]
29 |

Functorial interface used to build lifting functions for any type equipped 30 | with a map function.

31 | 32 |
33 |
Lift2 [Bindlib]
36 |

Similar to the Lift functor, but handles "binary" map functions.

37 | 38 |
39 |
41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/index_types.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Index of types 12 | 13 | 14 | 16 |

Index of types

17 | 18 | 19 | 20 | 25 | 26 | 31 | 32 | 33 | 38 | 39 | 40 | 46 | 47 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 64 |
B
binder [Bindlib]
21 |

Type of a binder for an element of type 'a into an element of type 'b.

22 | 23 |
24 |
box [Bindlib]
27 |

Type of a term of type 'a under construction.

28 | 29 |
30 |
C
ctxt [Bindlib]
34 |

Type of a context.

35 | 36 |
37 |
M
mbinder [Bindlib]
41 |

Type of a binder for an array of elements of type 'a into an element of 42 | type 'b.

43 | 44 |
45 |
mvar [Bindlib]
48 |

Type of an array of variables of type 'a.

49 | 50 |
51 |
T
t [Bindlib.Map2]
t [Bindlib.Map]
V
var [Bindlib]
60 |

Type of a free variable of type 'a.

61 | 62 |
63 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/style.css: -------------------------------------------------------------------------------- 1 | .keyword { font-weight : bold ; color : Red } 2 | .keywordsign { color : #C04600 } 3 | .comment { color : Green } 4 | .constructor { color : Blue } 5 | .type { color : #5C6585 } 6 | .string { color : Maroon } 7 | .warning { color : Red ; font-weight : bold } 8 | .info { margin-left : 3em; margin-right: 3em } 9 | .param_info { margin-top: 4px; margin-left : 3em; margin-right : 3em } 10 | .code { color : #465F91 ; } 11 | .typetable { border-style : hidden } 12 | .paramstable { border-style : hidden ; padding: 5pt 5pt} 13 | tr { background-color : White } 14 | td.typefieldcomment { background-color : #FFFFFF ; font-size: smaller ;} 15 | div.sig_block {margin-left: 2em} 16 | *:target { background: yellow; } 17 | body {font: 13px sans-serif; color: black; text-align: left; padding: 5px; margin: 0} 18 | h1 { font-size : 20pt ; text-align: center; } 19 | h2 { font-size : 20pt ; text-align: center; } 20 | h3 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ;padding: 2px; } 21 | h4 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90DDFF ;padding: 2px; } 22 | h5 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90EDFF ;padding: 2px; } 23 | h6 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90FDFF ;padding: 2px; } 24 | div.h7 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #90BDFF ; padding: 2px; } 25 | div.h8 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #E0FFFF ; padding: 2px; } 26 | div.h9 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #F0FFFF ; padding: 2px; } 27 | div.h10 { font-size : 20pt ; border: 1px solid #000000; margin-top: 5px; margin-bottom: 2px;text-align: center; background-color: #FFFFFF ; padding: 2px; } 28 | a {color: #416DFF; text-decoration: none} 29 | a:hover {background-color: #ddd; text-decoration: underline} 30 | pre { margin-bottom: 4px; font-family: monospace; } 31 | pre.verbatim, pre.codepre { } 32 | .indextable {border: 1px #ddd solid; border-collapse: collapse} 33 | .indextable td, .indextable th {border: 1px #ddd solid; min-width: 80px} 34 | .indextable td.module {background-color: #eee ; padding-left: 2px; padding-right: 2px} 35 | .indextable td.module a {color: #4E6272; text-decoration: none; display: block; width: 100%} 36 | .indextable td.module a:hover {text-decoration: underline; background-color: transparent} 37 | .deprecated {color: #888; font-style: italic} 38 | .indextable tr td div.info { margin-left: 2px; margin-right: 2px } 39 | ul.indexlist { margin-left: 0; padding-left: 0;} 40 | ul.indexlist li { list-style-type: none ; margin-left: 0; padding-left: 0; } 41 | ul.info-attributes {list-style: none; margin: 0; padding: 0; } 42 | div.info > p:first-child { margin-top:0; } 43 | div.info-desc > p:first-child { margin-top:0; margin-bottom:0; } -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/type_Bindlib.Lift.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift 11 | 12 | 13 | functor (M : Map->
14 |   sig val lift_box : 'Bindlib.box M.t -> 'M.t Bindlib.box end
15 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/type_Bindlib.Lift2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Lift2 11 | 12 | 13 | functor (M : Map2->
14 |   sig
15 |     val lift_box :
16 |       ('Bindlib.box, 'Bindlib.box) M.t -> ('a, 'b) M.t Bindlib.box
17 |   end
18 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/type_Bindlib.Map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map 11 | 12 | 13 | sig
14 |   type 'a t
15 |   val map : ('-> 'b) -> 'Bindlib.Map.t -> 'Bindlib.Map.t
16 | end
17 | -------------------------------------------------------------------------------- /docs/5.0.1-ocamldoc/type_Bindlib.Map2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Bindlib.Map2 11 | 12 | 13 | sig
14 |   type ('a, 'b) t
15 |   val map :
16 |     ('-> 'b) ->
17 |     ('-> 'd) -> ('a, 'c) Bindlib.Map2.t -> ('b, 'd) Bindlib.Map2.t
18 | end
19 | -------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/.dummy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlepigre/ocaml-bindlib/0a3fed2902e0222dc6450af0ddf1c2a60beff1c0/docs/6.0.0/bindlib/Bindlib/.dummy -------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Ctxt/argument-1-R/index.html: -------------------------------------------------------------------------------- 1 | 2 | R (bindlib.Bindlib.Ctxt.1-R)

Parameter Ctxt.1-R

type ctxt

Type representing a set of variable names.

val empty_ctxt : ctxt

empty_ctxt represents an empty context.

val reset_context_for_closed_terms : bool

reset_context_for_closed_terms indicates whether the context should be reset to the empty context when calling unbind_in or munbind_in on a closed binder (which cannot capture names). If set to true, printing a λ-term will produce “λx.λx.x” rather than “λx.λx0.x0”, or “λx.x (λx.x)” rather than “λx.x (λx0.x0)”.

val skip_constant_binders : bool

skip_constant_binders indicates whether binders that are constant must be skipped (i.e., not recorded in the context). This permits reusing the name in a lower binder like in “λx.λx.x”, but not in “λx.x (λx.x)”.

val constant_binder_name : string option

constant_binder_name optionally provides a representation for a binder that is constant, to highlight the absence of a name. When this value is defined to be Some(s), then s is used as name for all such binders. For example, if s is "_" then we would get “λ_.λx.x”. Note that if the value of constant_binder_name is not None, skip_constant_binder is ignored.

val new_name : string -> ctxt -> string * ctxt

new_name name ctxt creates a name that is fresh in context ctxt. The given name indicates a prefered name (or base for the name). Note that the returned context extends ctxt with the new name.

val reserve_name : string -> ctxt -> ctxt

reserve_name name ctxt extends context ctxt by reserving name as a free variable name.

-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Ctxt/index.html: -------------------------------------------------------------------------------- 1 | 2 | Ctxt (bindlib.Bindlib.Ctxt)

Module Bindlib.Ctxt

A functor that can be used to obtain context-manipulating functions, given the specification of a renaming policy. The defined ctxt type as well as the obtained functions can then be used as a drop-in replacement for their default counterparts (found at the top level of the Bindlib module).

Parameters

module R : Renaming

Signature

type ctxt = R.ctxt
val empty_ctxt : ctxt
val free_vars : 'a box -> ctxt
val new_var_in : ctxt -> ( 'a var -> 'a ) -> string -> 'a var * ctxt
val new_mvar_in : ctxt -> ( 'a var -> 'a ) -> string array -> 'a mvar * ctxt
val unbind_in : ctxt -> ( 'a, 'b ) binder -> 'a var * 'b * ctxt
val unbind2_in : 3 | ctxt -> 4 | ( 'a, 'b ) binder -> 5 | ( 'a, 'c ) binder -> 6 | 'a var * 'b * 'c * ctxt
val unmbind_in : ctxt -> ( 'a, 'b ) mbinder -> 'a mvar * 'b * ctxt
val unmbind2_in : 7 | ctxt -> 8 | ( 'a, 'b ) mbinder -> 9 | ( 'a, 'c ) mbinder -> 10 | 'a mvar * 'b * 'c * ctxt
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Lift/argument-1-M/index.html: -------------------------------------------------------------------------------- 1 | 2 | M (bindlib.Bindlib.Lift.1-M)

Parameter Lift.1-M

type 'a t
val map : ( 'a -> 'b ) -> 'a t -> 'b t
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Lift/index.html: -------------------------------------------------------------------------------- 1 | 2 | Lift (bindlib.Bindlib.Lift)

Module Bindlib.Lift

Functorial interface used to build lifting functions for any type equipped with a map function. In other words, this function can be used to allow the permutation of the 'a box type with another type constructor.

Parameters

module M : Map

Signature

val lift_box : 'a box M.t -> 'a M.t box
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Lift2/argument-1-M/index.html: -------------------------------------------------------------------------------- 1 | 2 | M (bindlib.Bindlib.Lift2.1-M)

Parameter Lift2.1-M

type ('a, 'b) t
val map : ( 'a -> 'b ) -> ( 'c -> 'd ) -> ( 'a, 'c ) t -> ( 'b, 'd ) t
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/Lift2/index.html: -------------------------------------------------------------------------------- 1 | 2 | Lift2 (bindlib.Bindlib.Lift2)

Module Bindlib.Lift2

Similar to the Lift functor, but handles "binary" map functions.

Parameters

module M : Map2

Signature

val lift_box : ( 'a box, 'b box ) M.t -> ( 'a, 'b ) M.t box
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/module-type-Map/index.html: -------------------------------------------------------------------------------- 1 | 2 | Map (bindlib.Bindlib.Map)

Module type Bindlib.Map

Type of a module equipped with a map function.

type 'a t
val map : ( 'a -> 'b ) -> 'a t -> 'b t
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/module-type-Map2/index.html: -------------------------------------------------------------------------------- 1 | 2 | Map2 (bindlib.Bindlib.Map2)

Module type Bindlib.Map2

Type of a module equipped with a "binary" map function.

type ('a, 'b) t
val map : ( 'a -> 'b ) -> ( 'c -> 'd ) -> ( 'a, 'c ) t -> ( 'b, 'd ) t
-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/Bindlib/module-type-Renaming/index.html: -------------------------------------------------------------------------------- 1 | 2 | Renaming (bindlib.Bindlib.Renaming)

Module type Bindlib.Renaming

Module type giving the specification of a renaming policy, to be used with the Ctxt functor.

type ctxt

Type representing a set of variable names.

val empty_ctxt : ctxt

empty_ctxt represents an empty context.

val reset_context_for_closed_terms : bool

reset_context_for_closed_terms indicates whether the context should be reset to the empty context when calling unbind_in or munbind_in on a closed binder (which cannot capture names). If set to true, printing a λ-term will produce “λx.λx.x” rather than “λx.λx0.x0”, or “λx.x (λx.x)” rather than “λx.x (λx0.x0)”.

val skip_constant_binders : bool

skip_constant_binders indicates whether binders that are constant must be skipped (i.e., not recorded in the context). This permits reusing the name in a lower binder like in “λx.λx.x”, but not in “λx.x (λx.x)”.

val constant_binder_name : string option

constant_binder_name optionally provides a representation for a binder that is constant, to highlight the absence of a name. When this value is defined to be Some(s), then s is used as name for all such binders. For example, if s is "_" then we would get “λ_.λx.x”. Note that if the value of constant_binder_name is not None, skip_constant_binder is ignored.

val new_name : string -> ctxt -> string * ctxt

new_name name ctxt creates a name that is fresh in context ctxt. The given name indicates a prefered name (or base for the name). Note that the returned context extends ctxt with the new name.

val reserve_name : string -> ctxt -> ctxt

reserve_name name ctxt extends context ctxt by reserving name as a free variable name.

-------------------------------------------------------------------------------- /docs/6.0.0/bindlib/index.html: -------------------------------------------------------------------------------- 1 | 2 | index (bindlib.index)

bindlib index

Library bindlib

The entry point of this library is the module: Bindlib.

-------------------------------------------------------------------------------- /docs/6.0.0/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | index 5 | 6 | 7 | 8 | 9 | 10 |
11 |
12 |

OCaml package documentation

13 |
    14 |
  1. bindlib
  2. 15 |
16 |
17 |
18 | 19 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | The Bindlib Library 6 | 16 | 17 | 18 | 19 |

The OCaml Bindlib library

20 |

Christophe Raffalli and Rodolphe Lepigre 21 | 22 |

Description:

23 |

24 | The Bindlib library provides support for free and bound variables in the 25 | OCaml language. The main application in the representation of types with 26 | a binding structure (e.g., abstract syntax trees). 27 |

28 | 29 |

Resources:

30 | 44 | 45 | Fork me on GitHub 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 2.7) 2 | 3 | (name "bindlib") 4 | (authors 5 | "Rodolphe Lepigre " 6 | "Christophe Raffalli " 9 | "Christophe Raffalli = 4.07.0)) 24 | (dune :build) 25 | (timed (and (>= 1.0) :with-test)) 26 | (pacomb (and (>= 1.1) :with-test)) 27 | (odoc :with-doc))) 28 | -------------------------------------------------------------------------------- /examples/basic.expected: -------------------------------------------------------------------------------- 1 | id (size = 1): λx.x 2 | fst (size = 2): λx.λy.x 3 | delta (size = 2): λx.(x) x 4 | omega (size = 5): (λx.(x) x) λx.(x) x 5 | t (size = 15): ((λx.λy.x) (λx.x) (λx.(x) x) λx.x) (λx.(x) x) λx.(x) x 6 | eval t (size = 1): λx.x 7 | t (size = 3): (λx.λy1.x) y 8 | eval t (size = 1): λy1.y 9 | -------------------------------------------------------------------------------- /examples/basic.ml: -------------------------------------------------------------------------------- 1 | (* This file contains the code quoted in "bindlib.mli" as a trailing example. 2 | It illustrates a very basic usage of [Bindlib] to represent and manipulate 3 | the simple abstract syntax tree of the pure λ-calculus. *) 4 | 5 | open Bindlib 6 | 7 | (* Type of the terms of the λ-calculus. *) 8 | type term = 9 | | Var of term var 10 | | Abs of (term, term) binder 11 | | App of term * term 12 | 13 | (* Call-by-name evaluation function. *) 14 | let rec eval : term -> term = fun t -> 15 | match t with 16 | | App(f,a) -> 17 | begin 18 | match eval f with 19 | | Abs(b) -> eval (subst b a) 20 | | _ -> t 21 | end 22 | | _ -> t 23 | 24 | (* The common syntactic wrapper for variables. *) 25 | let mkfree : term var -> term = fun x -> Var(x) 26 | 27 | (* Size function computing the number of λ-abstractions and applications. *) 28 | let rec size : term -> int = fun t -> 29 | match t with 30 | | Var(_) -> 0 31 | | Abs(b) -> let (_,t) = unbind b in 32 | 1 + size t 33 | | App(t,u) -> 1 + size t + size u 34 | 35 | (* Smart constructors. *) 36 | 37 | let var : term var -> term box = 38 | fun x -> box_var x 39 | 40 | let abs_raw : (term, term) binder box -> term box = 41 | fun b -> box_apply (fun b -> Abs(b)) b 42 | 43 | let abs : term var -> term box -> term box = 44 | fun x t -> abs_raw (bind_var x t) 45 | 46 | let app : term box -> term box -> term box = 47 | fun t u -> box_apply2 (fun t u -> App(t,u)) t u 48 | 49 | let rec box_term : term -> term box = fun t -> 50 | match t with 51 | | Var(x) -> var x 52 | | Abs(b) -> abs_raw (box_binder box_term b) 53 | | App(t,u) -> app (box_term t) (box_term u) 54 | 55 | (* Conversion of a λ-term into a [string] using Krivine's notation (this means 56 | that the application of term [t] to term [u] is written [(t) u]). *) 57 | let rec to_string : ctxt -> term -> string = fun ctxt t -> 58 | match t with 59 | | Var(x) -> name_of x 60 | | Abs(b) -> let (x,t,ctxt) = unbind_in ctxt b in 61 | "λ" ^ name_of x ^ "." ^ to_string ctxt t 62 | | App(t,u) -> "(" ^ to_string ctxt t ^ ") " ^ to_string ctxt u 63 | 64 | let to_string : term -> string = fun t -> 65 | to_string (free_vars (box_term t)) t 66 | 67 | (* Examples of terms. *) 68 | 69 | (* λx.x *) 70 | let id : term = 71 | let x = new_var mkfree "x" in 72 | unbox (abs x (var x)) 73 | 74 | (* λx.λy.x *) 75 | let fst : term = 76 | let x = new_var mkfree "x" in 77 | let y = new_var mkfree "y" in 78 | unbox (abs x (abs y (var x))) 79 | 80 | (* λx.(x) x (boxed) *) 81 | let delta : term box = 82 | let x = new_var mkfree "x" in 83 | abs x (app (var x) (var x)) 84 | 85 | (* (λx.(x) x) (λx.(x) x) *) 86 | let omega : term = 87 | unbox (app delta delta) 88 | 89 | (* λx.(x) x *) 90 | let delta : term = 91 | unbox delta 92 | 93 | (* Tests. *) 94 | let _ = 95 | Printf.printf "id (size = %2i): %s\n%!" (size id) (to_string id); 96 | Printf.printf "fst (size = %2i): %s\n%!" (size fst) (to_string fst); 97 | Printf.printf "delta (size = %2i): %s\n%!" (size delta) (to_string delta); 98 | Printf.printf "omega (size = %2i): %s\n%!" (size omega) (to_string omega) 99 | 100 | (* Define a bigger term and test evaluation. *) 101 | let _ = 102 | let x = new_var mkfree "x" in 103 | let y = new_var mkfree "y" in 104 | let delta = abs x (app (var x) (var x)) in 105 | let omega = app delta delta in 106 | let fst = abs x (abs y (var x)) in 107 | let id = abs x (var x) in 108 | let t = unbox (app (app fst (app id (app delta id))) omega) in 109 | let v = eval t in 110 | Printf.printf "t (size = %2i): %s\n%!" (size t) (to_string t); 111 | Printf.printf "eval t (size = %2i): %s\n%!" (size v) (to_string v) 112 | 113 | (* Test with an open term. *) 114 | let _ = 115 | let x = new_var mkfree "x" in 116 | let y = new_var mkfree "y" in 117 | let fst = abs x (abs y (var x)) in 118 | let t = unbox (app fst (var y)) in 119 | let v = eval t in 120 | Printf.printf "t (size = %2i): %s\n%!" (size t) (to_string t); 121 | Printf.printf "eval t (size = %2i): %s\n%!" (size v) (to_string v) 122 | -------------------------------------------------------------------------------- /examples/dune: -------------------------------------------------------------------------------- 1 | (tests 2 | (names basic fchurch lambda parsed translate unif pred2 3 | more_lambda hashcons occur_count) 4 | (libraries bindlib)) 5 | -------------------------------------------------------------------------------- /examples/fchurch.expected: -------------------------------------------------------------------------------- 1 | ⊢ ΛX.ΛY.λx:X.λy:Y.x : ∀X.∀Y.(X) ⇒ ((Y) ⇒ (X)) 2 | ⊢ ΛX.ΛY.λx:X.λy:Y.x : ∀X.∀Y.(X) ⇒ ((Y) ⇒ (X)) 3 | ⊢ ΛX.ΛY.λf:(X) ⇒ (Y).λx:X.(f) x : ∀X.∀Y.((X) ⇒ (Y)) ⇒ ((X) ⇒ (Y)) 4 | OK 5 | -------------------------------------------------------------------------------- /examples/hashcons.expected: -------------------------------------------------------------------------------- 1 | λx.x 2 | λx.x 3 | λx.(x x) 4 | λx.(x x) 5 | λx.x 6 | λf.λx.(f (f x)) 7 | λf.λx.((λf1.λx1.((λf2.λx2.((λf3.λx3.((λf4.λx4.x4 f3) (f3 x3)) f2) (f2 x2)) f1) (f1 x1)) f) (f x)) 8 | λf.λx.((λf1.λx1.((λf2.λx2.((λf3.λx3.((λf4.λx4.x4 f3) (f3 x3)) f2) (f2 x2)) f1) (f1 x1)) f) (f x)) 9 | -------------------------------------------------------------------------------- /examples/hashcons.ml: -------------------------------------------------------------------------------- 1 | (** Experiment with hashconsing. *) 2 | 3 | open Bindlib 4 | 5 | type term = {mutable address : int; mutable key : int; data : term_aux} 6 | 7 | and term_aux = 8 | | TVar of term var 9 | | TApp of term * term 10 | | TLam of (term, term) binder 11 | | HVar of int 12 | 13 | type t = term 14 | 15 | let canonical_var f = 16 | let n = if binder_occur f then binder_rank f + 1 else 0 in 17 | {address = -n; key = Hashtbl.hash (`HVar, n); data = HVar(n)} 18 | 19 | let hash_binder f = 20 | Hashtbl.hash (binder_occur f, (subst f (canonical_var f)).key) 21 | 22 | let hash_aux t = 23 | match t with 24 | | HVar(n) -> Hashtbl.hash (`HVar, n) 25 | | TVar(x) -> hash_var x 26 | | TApp(t,u) -> Hashtbl.hash (`TApp, t.key, u.key) 27 | | TLam(b) -> Hashtbl.hash (`TLam, hash_binder b) 28 | 29 | let hash r = r.key 30 | 31 | let equal_binders b1 b2 = 32 | binder_rank b1 = binder_rank b2 && 33 | binder_occur b1 = binder_occur b2 && 34 | (subst b1 (canonical_var b1)).address = 35 | (subst b2 (canonical_var b2)).address 36 | 37 | let equal_aux t1 t2 = t1 == t2 || 38 | match (t1, t2) with 39 | | (HVar(n1) , HVar(n2) ) -> n1 = n2 40 | | (TVar(x1) , TVar(x2) ) -> eq_vars x1 x2 41 | | (TApp(t1,u1), TApp(t2,u2)) -> 42 | t1.address = t2.address && u1.address = u2.address 43 | | (TLam(b1) , TLam(b2) ) -> equal_binders b1 b2 44 | | (_ , _ ) -> false 45 | 46 | let equal t1 t2 = equal_aux t1.data t2.data 47 | 48 | module WLambda = Weak.Make( 49 | struct 50 | type t = term 51 | let hash = hash 52 | let equal = equal 53 | end) 54 | 55 | let hashtbl = WLambda.create 1001 56 | 57 | let get_addr = 58 | let counter = ref 1 in 59 | fun () -> let addr = !counter in incr counter; addr 60 | 61 | let hash_cons data = 62 | let t = {address = get_addr (); key = hash_aux data; data} in 63 | try WLambda.find hashtbl t with Not_found -> WLambda.add hashtbl t; t 64 | 65 | let re_hash_cons old = 66 | old.key <- hash_aux old.data; 67 | old.address <- get_addr (); 68 | try 69 | let res = WLambda.find hashtbl old in 70 | old.address <- get_addr (); res 71 | with Not_found -> WLambda.add hashtbl old; old 72 | 73 | let rec print_in ctxt oc t = 74 | match t.data with 75 | | TVar(x) -> 76 | Printf.fprintf oc "%s" (name_of x) 77 | | TLam(b) -> 78 | let (x,t,ctxt) = Bindlib.unbind_in ctxt b in 79 | Printf.fprintf oc "λ%s.%a" (name_of x) (print_in ctxt) t 80 | | TApp(t,u) -> 81 | Printf.fprintf oc "(%a %a)" (print_in ctxt) t (print_in ctxt) u 82 | | HVar(n) -> 83 | Printf.fprintf oc "{%i}" n 84 | 85 | let print_closed = print_in empty_ctxt 86 | 87 | let mkfree : term var -> term = fun x -> 88 | hash_cons (TVar(x)) 89 | 90 | let var : term var -> term box = 91 | box_var 92 | 93 | let lam : string -> (term box -> term box) -> term box = fun x f -> 94 | let x = Bindlib.new_var mkfree x in 95 | box_apply hash_cons (box_apply (fun x -> TLam x) (bind_var x (f (var x)))) 96 | 97 | let app : term box -> term box -> term box = fun t u -> 98 | box_apply hash_cons (box_apply2 (fun t u -> TApp(t,u)) t u) 99 | 100 | let _App(t1,t2) = hash_cons(TApp(t1,t2)) 101 | 102 | let rec eval t = 103 | match t.data with 104 | | TVar(_) -> failwith "open term" 105 | | HVar(_) -> failwith "invalid term" 106 | | TLam(_) -> t 107 | | TApp(t1,t2) -> 108 | let t1 = eval t1 in 109 | let t2 = eval t2 in 110 | let b = match t1.data with TLam(b) -> b | _ -> failwith "ill-typed" in 111 | eval (subst b t2) 112 | 113 | (* Tests. *) 114 | 115 | let idt = unbox (lam "x" (fun x -> x)) 116 | let delta = unbox (lam "x" (fun x -> app x x)) 117 | let idt' = unbox (lam "y" (fun x -> x)) 118 | let delta' = unbox (lam "y" (fun x -> app x x)) 119 | let zero = unbox (lam "f" (fun _ -> lam "x" (fun x -> x))) 120 | let succ = unbox (lam "n" (fun n -> lam "f" (fun f -> lam "x" (fun x -> 121 | app (app n f) (app f x))))) 122 | let two = unbox (lam "f" (fun f -> lam "x" (fun x -> app f (app f x)))) 123 | let add = unbox (lam "n" (fun n -> lam "m" (fun m -> lam "f" (fun f -> 124 | lam "x" (fun x -> app (app n f) (app (app m f) x)))))) 125 | 126 | let dog = eval (_App(_App(_App(two,two),succ),zero)) 127 | let four = eval (_App(_App(_App(_App(add,two),two),succ),zero)) 128 | 129 | let _ = assert (idt.address = idt'.address) 130 | let _ = assert (idt.data == idt'.data) 131 | 132 | let _ = assert (delta.address = delta'.address && 133 | delta.data == delta'.data) 134 | 135 | let idt'' = eval (_App(delta, _App(delta', idt))) 136 | 137 | let _ = 138 | Printf.printf "%a\n%!" print_closed idt; 139 | Printf.printf "%a\n%!" print_closed idt'; 140 | Printf.printf "%a\n%!" print_closed delta; 141 | Printf.printf "%a\n%!" print_closed delta'; 142 | Printf.printf "%a\n%!" print_closed idt''; 143 | Printf.printf "%a\n%!" print_closed two; 144 | Printf.printf "%a\n%!" print_closed four; 145 | Printf.printf "%a\n%!" print_closed dog 146 | 147 | let _ = assert (idt.address = idt''.address) 148 | let _ = assert (idt.data == idt''.data) 149 | 150 | let _ = assert (four.address = dog.address) 151 | let _ = assert (four.data == dog.data) 152 | -------------------------------------------------------------------------------- /examples/lambda.expected: -------------------------------------------------------------------------------- 1 | Here are some terms: 2 | x 3 | y 4 | λx.x 5 | λx.λy.x 6 | λx.(x) x 7 | (λx.(x) x) λx.(x) x 8 | λx.λy.(y) x 9 | (λx.λy.x) y 10 | ((λx.λy.x) y) x 11 | (λx.λy.(y) x) y 12 | λy.λx.(y) (y) x 13 | (λy.λx.(y) (y) x) λy.λx.(y) (y) x 14 | Here are some sevaluation... Bindlib is fast. 15 | Renaming of variables is delayed until printing. 16 | It uses context and policies to allow fine control. 17 | (λx.λy.x) y 18 | → λy.y 19 | ((λx.λy.x) y) x 20 | → y 21 | (λx.λy.(y) x) y 22 | → λy.(y) y 23 | (λy.λx.(y) (y) x) λy.λx.(y) (y) x 24 | → λx.λx1.(x) (x) (x) (x) x1 25 | Same as above with the custom renaming: 26 | x 27 | y 28 | λx.x 29 | λx.λ_.x 30 | λx.(x) x 31 | (λx.(x) x) λx.(x) x 32 | λx.λy.(y) x 33 | (λx.λ_.x) y 34 | ((λx.λ_.x) y) x 35 | (λx.λy.(y) x) y 36 | λy.λx.(y) (y) x 37 | (λy.λx.(y) (y) x) λy.λx.(y) (y) x 38 | (λx.λ_.x) y 39 | → λ_.y 40 | ((λx.λ_.x) y) x 41 | → y 42 | (λx.λy.(y) x) y 43 | → λy.(y) y 44 | (λy.λx.(y) (y) x) λy.λx.(y) (y) x 45 | → λx.λx'.(x) (x) (x) (x) x' 46 | -------------------------------------------------------------------------------- /examples/metavar/ast.ml: -------------------------------------------------------------------------------- 1 | (** Ast constructed by the parser. *) 2 | 3 | (** Parsed term. *) 4 | type pterm = 5 | | PApp of pterm * pterm 6 | (** Application. *) 7 | | PLam of string * pterm 8 | (** Abstraction. *) 9 | | PVar of string 10 | (** Variable. *) 11 | | PNrm of pterm 12 | (** Normalisation of a term. *) 13 | 14 | let many_PLam : string list -> pterm -> pterm = 15 | List.fold_right (fun x t -> PLam(x,t)) 16 | 17 | (** Parsed command. *) 18 | type cmd = 19 | | Decl of string * pterm 20 | (** Declare a meta-variable. *) 21 | | Prnt of pterm 22 | (** Print the normal form of the given term. *) 23 | | Undo 24 | (** Undo the previous command (excluding [Undo]). *) 25 | | Goal 26 | (** Print all the goals (unset meta-variables). *) 27 | -------------------------------------------------------------------------------- /examples/metavar/cmd.ml: -------------------------------------------------------------------------------- 1 | open Term 2 | open Bindlib 3 | open Timed 4 | open Ast 5 | 6 | type env = 7 | { glob : meta list ref (* assoc list of all meta var *) 8 | ; ctxt : ctxt ref (* bindlib context to use bindlib renaming *) 9 | ; locl : (string * term box) list 10 | (* local environment *) 11 | ; mutable undo : Time.t list 12 | (* do not manage undo list via Timed *) 13 | } 14 | 15 | (* printing of meta var *) 16 | let print_mta ch m = 17 | let parray ch a = 18 | Array.iteri (fun i s -> 19 | Printf.fprintf ch "%s%s" (if i > 0 then "," else "") s) a 20 | in 21 | Printf.fprintf ch "%s[%a]" m.mname parray m.ctxte 22 | 23 | (* creation of a fresh meta variable. Its context is 24 | computed from the local environment *) 25 | let create_mta name env = 26 | let names, args = List.split env.locl in 27 | let names = Array.of_list names in 28 | (* let bindlib rename the metavar if needed *) 29 | let v, ctxt = new_var_in !(env.ctxt) var name in 30 | let name' = name_of v in 31 | if name' <> name then 32 | Printf.printf "Warning: meta variable %s created as %s.\n%!" name name'; 33 | let m = { mname = name'; ctxte = names; value = ref None } in 34 | Printf.printf "New meta %a\n%!" print_mta m; 35 | (* update the environment *) 36 | env.ctxt := ctxt; 37 | env.glob := m :: ! (env. glob); 38 | (m, Array.of_list args) 39 | 40 | (* search a name in the environment *) 41 | let search name env = 42 | try (* a local variable ? *) 43 | List.assoc name env.locl 44 | with Not_found -> try (* a meta variable with an empty context *) 45 | let m = List.find (fun m -> m.mname = name) !(env.glob) in 46 | if m.ctxte <> [||] then raise Not_found; 47 | mta m [||] 48 | with Not_found -> (* creation of a fresh meta variable *) 49 | let m, args = create_mta name env in 50 | mta m args 51 | 52 | (* translation from parsed term to real term *) 53 | let pterm_to_term env t = 54 | let rec fn env = function 55 | | PApp(t,u) -> app (fn env t) (fn env u) 56 | | PLam(name, t) -> 57 | let v = new_var var name in 58 | let env = { env with locl = (name, box_var v) :: env.locl } in 59 | lam v (fn env t) 60 | | PVar name -> search name env 61 | | PNrm t -> norm (unbox (fn env t)) (* local normalisation of a subterm 62 | useless but fun ? *) 63 | in fn env t 64 | 65 | (* undo provided by Timed *) 66 | let undo env = match env.undo with 67 | | [] -> Printf.printf "Warning: nothing to undo.\n%!" 68 | | time::undo -> 69 | Time.restore time; env.undo <- undo 70 | 71 | let declare env name t = 72 | let mta = (* search the mta *) 73 | try List.find (fun m -> m.mname = name) !(env.glob) 74 | with Not_found -> (* or create a new one with an empty context *) 75 | let m, args = create_mta name env in 76 | assert (args = [||]); (* check for emptyness of the context *) 77 | m 78 | in 79 | if !(mta.value) <> None then (* can not reset a meta ... use undo *) 80 | Printf.printf "Warning: meta variable %s already set.\n%!" name 81 | else 82 | let vars = new_mvar var mta.ctxte in 83 | let env = (* prepare the initial local env with the context of the meta *) 84 | { env with 85 | locl = Array.to_list 86 | (Array.mapi (fun i name -> (name, box_var vars.(i))) 87 | mta.ctxte) 88 | @ env.locl 89 | } 90 | in 91 | (* conversion *) 92 | let t = pterm_to_term env t in 93 | (* binding the context and unboxing *) 94 | let f = unbox (bind_mvar vars t) in 95 | Printf.printf "Set meta %a\n%!" print_mta mta; 96 | mta.value := Some f 97 | 98 | (* run command *) 99 | let run env = function 100 | | Decl(name,t) -> 101 | let save = Time.save () in 102 | declare env name t; 103 | env.undo <- save::env.undo 104 | | Undo -> 105 | undo env 106 | | Prnt t -> 107 | let save = Time.save () in 108 | Printf.printf "%a\n%!" (print_term !(env.ctxt)) 109 | (unbox (pterm_to_term env (PNrm t))); 110 | Time.restore save (* do not keep meta var created just for printing *) 111 | | Goal -> 112 | List.iter (fun m -> if !(m.value) = None then 113 | Printf.printf "Goal: %a\n%!" print_mta m) 114 | !(env.glob) 115 | 116 | let run = 117 | let env = 118 | { glob = Timed.ref [] 119 | ; ctxt = Timed.ref Bindlib.empty_ctxt 120 | ; locl = [] 121 | ; undo = [] } 122 | in 123 | fun cmd -> run env cmd 124 | 125 | 126 | -------------------------------------------------------------------------------- /examples/metavar/dune: -------------------------------------------------------------------------------- 1 | (test 2 | (name main) 3 | (preprocess (per_module ((pps pacomb.ppx) parser))) 4 | (libraries bindlib unix pacomb timed) 5 | (action (with-stdin-from test.txt (run %{test})))) 6 | -------------------------------------------------------------------------------- /examples/metavar/main.expected: -------------------------------------------------------------------------------- 1 | New meta id[] 2 | Set meta id[] 3 | New meta 0[] 4 | Set meta 0[] 5 | New meta s[] 6 | New meta s_in1[x,f,n] 7 | Set meta s[] 8 | New meta 10[] 9 | Warning: meta variable 9 created as 11. 10 | New meta 11[] 11 | Set meta 10[] 12 | Warning: meta variable 9 created as 12. 13 | New meta 12[] 14 | Warning: meta variable 8 created as 13. 15 | New meta 13[] 16 | Set meta 12[] 17 | Warning: meta variable 8 created as 14. 18 | New meta 14[] 19 | Warning: meta variable 7 created as 15. 20 | New meta 15[] 21 | Set meta 14[] 22 | Warning: meta variable 7 created as 16. 23 | New meta 16[] 24 | Warning: meta variable 6 created as 17. 25 | New meta 17[] 26 | Set meta 16[] 27 | Warning: meta variable 6 created as 18. 28 | New meta 18[] 29 | Warning: meta variable 5 created as 19. 30 | New meta 19[] 31 | Set meta 18[] 32 | Warning: meta variable 5 created as 20. 33 | New meta 20[] 34 | Warning: meta variable 4 created as 21. 35 | New meta 21[] 36 | Set meta 20[] 37 | Warning: meta variable 4 created as 22. 38 | New meta 22[] 39 | Warning: meta variable 3 created as 23. 40 | New meta 23[] 41 | Set meta 22[] 42 | Warning: meta variable 3 created as 24. 43 | New meta 24[] 44 | Warning: meta variable 2 created as 25. 45 | New meta 25[] 46 | Set meta 24[] 47 | Warning: meta variable 2 created as 26. 48 | New meta 26[] 49 | Warning: meta variable 1 created as 27. 50 | New meta 27[] 51 | Set meta 26[] 52 | Warning: meta variable 1 created as 28. 53 | New meta 28[] 54 | Set meta 28[] 55 | New meta big[] 56 | Warning: meta variable 4 created as 29. 57 | New meta 29[] 58 | Warning: meta variable 4 created as 30. 59 | New meta 30[] 60 | Set meta big[] 61 | 30[] 29[] 62 | Goal: 30[] 63 | Goal: 29[] 64 | Goal: 27[] 65 | Goal: 25[] 66 | Goal: 23[] 67 | Goal: 21[] 68 | Goal: 19[] 69 | Goal: 17[] 70 | Goal: 15[] 71 | Goal: 13[] 72 | Goal: 11[] 73 | Goal: s_in1[x,f,n] 74 | New meta s_in2[x,f,n] 75 | Set meta s_in1[x,f,n] 76 | λn.λf.λx.f s_in2[x,f,n] 77 | Set meta s_in2[x,f,n] 78 | λn.λf.λx.f n f x 79 | 30[] 29[] 80 | Set meta s_in1[x,f,n] 81 | 30[] 29[] 82 | New meta r[] 83 | New meta s_in2[] 84 | Set meta r[] 85 | New meta q[] 86 | Warning: meta variable s_in1 created as s_in3. 87 | New meta s_in3[] 88 | Set meta q[] 89 | -------------------------------------------------------------------------------- /examples/metavar/main.ml: -------------------------------------------------------------------------------- 1 | (** Entry point. *) 2 | 3 | let _ = 4 | try 5 | let cmds = Parser.parse_channel stdin in 6 | List.iter Cmd.run cmds 7 | with e -> 8 | Printf.eprintf "Uncaught exception: %s\n%!" (Printexc.to_string e); 9 | exit 1 10 | -------------------------------------------------------------------------------- /examples/metavar/parser.ml: -------------------------------------------------------------------------------- 1 | open Pacomb 2 | open Ast 3 | 4 | let%parser ident = (id::RE"[a-z0-9][_a-zA-Z0-9]*[']*") => id 5 | 6 | let%parser rec term_atom = 7 | (id::ident) => PVar id 8 | ; '(' (t::term_full) ')' => t 9 | ; '[' (t::term_full) ']' => PNrm t 10 | 11 | and term_appl = 12 | (t::term_atom) => t 13 | ; (t::term_appl) (u::term_atom) => PApp(t,u) 14 | 15 | and term_full = 16 | (t::term_appl) => t 17 | ; ("λ" => () ; "%" => ()) (ids:: ~* ident) '.' (t::term_full) 18 | => many_PLam ids t 19 | 20 | let%parser command = 21 | "$u" => Undo 22 | ; "$g" => Goal 23 | ; "$s" (x::ident) "=" (t::term_full) => Decl(x,t) 24 | ; "$p" (t::term_full) => Prnt(t) 25 | 26 | let%parser commands = cs :: ~* ((c::command) ";" => c) => cs 27 | 28 | let blank = Blank.line_comments "//" 29 | 30 | let parse_channel : in_channel -> cmd list = fun ic -> 31 | let parse = Grammar.parse_channel commands blank in 32 | Pos.handle_exception parse ic 33 | -------------------------------------------------------------------------------- /examples/metavar/term.ml: -------------------------------------------------------------------------------- 1 | open Bindlib 2 | open Timed (* We use timed references for backtracking. *) 3 | 4 | (** Term of the λ-calculus with meta-variables. *) 5 | type term = 6 | | Var of term var 7 | (* Variable. *) 8 | | Lam of (term, term) binder 9 | (** Abstraction. *) 10 | | App of term * term 11 | (** Application. *) 12 | | Mta of meta * term array 13 | (** Meta-variable with its environment. *) 14 | 15 | (** Meta-variable. *) 16 | and meta = 17 | { mname : string 18 | (** Name of the meta-variable. *) 19 | ; ctxte : string array 20 | (** Context of the meta-variable. *) 21 | ; value : (term, term) mbinder option Timed.ref 22 | (** Value of the meta-variable if it is set. *) } 23 | 24 | type tbox = term box 25 | 26 | (* Smart constructors *) 27 | let var : term var -> term 28 | = fun v -> Var v 29 | let app : tbox -> tbox -> tbox 30 | = box_apply2 (fun u v -> App(u,v)) 31 | (* choose bindings from an existing var (not using bind or vbind *) 32 | let lam : term var -> tbox -> tbox 33 | = fun v t -> box_apply (fun b -> Lam b) (bind_var v t) 34 | let mta : meta -> tbox array -> tbox 35 | = fun m a -> box_apply (fun a -> Mta(m,a)) (box_array a) 36 | 37 | (* Printing function. *) 38 | let rec print_term wrap ctxt ch = 39 | let pterm = print_term false ctxt in 40 | let wterm = print_term true ctxt in 41 | let parray ch = 42 | let pelt i = 43 | Printf.fprintf ch "%s%a" (if i > 0 then "," else "") pterm 44 | in 45 | Array.iteri pelt 46 | in 47 | function 48 | | Var x -> 49 | Printf.fprintf ch "%s" (name_of x) 50 | | Lam b -> 51 | let (x, t, ctxt) = unbind_in ctxt b in 52 | if wrap then Printf.fprintf ch "("; 53 | Printf.fprintf ch "λ%s.%a" (name_of x) (print_term false ctxt) t; 54 | if wrap then Printf.fprintf ch ")"; 55 | | App(t,u) -> 56 | Printf.fprintf ch "%a %a" pterm t wterm u 57 | | Mta(mta,a) -> 58 | Printf.fprintf ch "%s[%a]" mta.mname parray a 59 | 60 | let print_term = print_term false 61 | 62 | (* normalisation function *) 63 | let rec whnf : term -> term = fun t -> 64 | match t with 65 | | App(t1,t2) as t0 -> ( 66 | match (whnf t1) with 67 | | Lam f -> whnf (subst f t2) 68 | | t1' -> 69 | (* a small optimization here when the term is in whnf *) 70 | if t1' == t1 then t0 else App(t1', t2)) 71 | | Mta({ value = r; _}, a) -> 72 | begin 73 | match !r with 74 | | Some f -> whnf (msubst f a) 75 | | None -> t 76 | end 77 | | _ -> t 78 | 79 | let rec norm : term -> tbox = fun t -> 80 | match whnf t with 81 | | Lam(f) -> 82 | let (x,t) = unbind f in 83 | lam x (norm t) 84 | | t -> 85 | let rec unwind t = 86 | match t with 87 | | Var(x) -> box_var x 88 | | App(t,u) -> app (unwind t) (norm u) 89 | | Mta(m,a) -> mta m (Array.map norm a) 90 | | Lam(_) -> assert false 91 | in 92 | unwind t 93 | -------------------------------------------------------------------------------- /examples/metavar/test.txt: -------------------------------------------------------------------------------- 1 | // Term syntax: 2 | // 3 | // - lident (lowercase ident) for variable. 4 | // If the variable is not bound and is not an existing meta variable 5 | // in an empty context, a new variable is created using the current 6 | // context. 7 | // 8 | // When a meta variable already exists with the same name, the 9 | // name is changed and a warning is printed. 10 | // 11 | // - u v: application 12 | // 13 | // - λx y.t or %x y.t: abstraction 14 | // 15 | // Command syntax: 16 | // 17 | // - $s id = term; 18 | // Set a meta variable (can use its context variables) 19 | // 20 | // If id does not exists, a fresh meta variable with an 21 | // empty context is created and set immediately 22 | // 23 | // - $p t; Print a term 24 | // 25 | // - $u; Undo the last $s command 26 | // 27 | // - $g; Print the unset meta variable (the goals) 28 | // 29 | // - feature : a meta variable can use itself creating recursive terms 30 | 31 | $s id = λx.x; 32 | $s 0 = λf x.x; 33 | // successor with a hole 34 | $s s = λn f x.s_in1; 35 | $s 10 = s 9; 36 | $s 9 = s 8; 37 | $s 8 = s 7; 38 | $s 7 = s 6; 39 | $s 6 = s 5; 40 | $s 5 = s 4; 41 | $s 4 = s 3; 42 | $s 3 = s 2; 43 | $s 2 = s 1; 44 | $s 1 = s 0; 45 | $s big = 4 4; 46 | $p big; 47 | // the goal 48 | $g; 49 | 50 | // fill the hole in two steps 51 | $s s_in1 = f s_in2; 52 | $p s; 53 | $s s_in2 = n f x; 54 | $p s; 55 | $p big; 56 | 57 | // undo and try another successor 58 | $u; 59 | $u; 60 | $s s_in1 = n f (f x); 61 | $p big; 62 | 63 | // check renaming of meta var 64 | // s_in2 was erased by undo, this is ok 65 | $s r = s_in2; 66 | // renamed because s_in1 already exists 67 | $s q = s_in1; 68 | -------------------------------------------------------------------------------- /examples/more_lambda.ml: -------------------------------------------------------------------------------- 1 | open Bindlib 2 | 3 | (* Type of the terms of the λ-calculus. *) 4 | type term = 5 | | Var of term var 6 | | Abs of (term, term) binder 7 | | App of term * term 8 | 9 | (* The common syntactic wrapper for variables. *) 10 | let mkfree : term var -> term = fun x -> Var(x) 11 | 12 | (* Size function computing the number of λ-abstractions and applications. *) 13 | let rec size : term -> int = fun t -> 14 | match t with 15 | | Var(_) -> 0 16 | | Abs(b) -> let (_,t) = unbind b in 17 | 1 + size t 18 | | App(t,u) -> 1 + size t + size u 19 | 20 | (* Smart constructors. *) 21 | 22 | let var : term var -> term box = 23 | fun x -> box_var x 24 | 25 | let abs_raw : (term, term) binder box -> term box = 26 | fun b -> box_apply (fun b -> Abs(b)) b 27 | 28 | let abs : term var -> term box -> term box = 29 | fun x t -> abs_raw (bind_var x t) 30 | 31 | let app : term box -> term box -> term box = 32 | fun t u -> box_apply2 (fun t u -> App(t,u)) t u 33 | 34 | let rec box_term : term -> term box = fun t -> 35 | match t with 36 | | Var(x) -> var x 37 | | Abs(b) -> abs_raw (box_binder box_term b) 38 | | App(t,u) -> app (box_term t) (box_term u) 39 | 40 | (* Weak head normalisation. *) 41 | 42 | let rec whnf : term -> term = fun t -> 43 | match t with 44 | | App(t1,t2) -> 45 | begin 46 | match whnf t1 with 47 | | Abs(b) -> whnf (Bindlib.subst b t2) 48 | | u -> if u == t1 then t (* optimisation *) else App(u, t2) 49 | end 50 | | t -> t 51 | 52 | (* Call-by-name normalisation. *) 53 | 54 | let norm : term -> term = fun t -> 55 | let rec norm t = 56 | match whnf t with 57 | | Abs(b) -> let (x, t) = Bindlib.unbind b in abs x (norm t) 58 | | t -> 59 | let rec unwind t = 60 | match t with 61 | | Var(x) -> var x 62 | | App(t1,t2) -> app (unwind t1) (norm t2) 63 | | _ -> assert false (* unreachable *) 64 | in 65 | unwind t 66 | in 67 | Bindlib.unbox (norm t) 68 | 69 | (* Example of complex variable manipulation: application marking. Here, [mark] 70 | is a function that can be described as follows using mathematical notations 71 | (with implicit variable renaming, i.e., assuming x does not occur in t): 72 | - mark(t) = λx.Φ(x,t) 73 | - Φ(x,y ) = y 74 | - Φ(x,λy.t) = λy.Φ(x,t) 75 | - Φ(x,t u ) = Φ(x,t) Φ(x,u) *) 76 | 77 | let mark t = 78 | let rec phi x t = 79 | match t with 80 | | Var(y) -> var y 81 | | App(t,u) -> app (app (var x) (phi x t)) (phi x u) 82 | | Abs(b) -> let (y, t) = Bindlib.unbind b in abs y (phi x t) 83 | in 84 | let x = Bindlib.new_var mkfree "x" in 85 | unbox (abs x (phi x t)) 86 | -------------------------------------------------------------------------------- /examples/occur_count.ml: -------------------------------------------------------------------------------- 1 | (* This example shows how to keep information about the free variables of a 2 | term in a custom "box" type. *) 3 | 4 | open Bindlib 5 | 6 | (* AST of the pure λ-calculus using free variables and binders. *) 7 | type term = 8 | | Var of term var 9 | | Abs of (term, term) binder 10 | | App of term * term 11 | 12 | module VarMap = Map.Make(struct 13 | type t = term var 14 | let compare = compare_vars 15 | end) 16 | 17 | type tvar = term var 18 | 19 | type tbox = { 20 | (* Boxed term. *) 21 | t : term box; 22 | (* Mapping variables to number of occurences. *) 23 | m : int VarMap.t 24 | } 25 | 26 | let free_vars : tbox -> int VarMap.t = fun t -> t.m 27 | 28 | let unbox t = unbox t.t 29 | 30 | (* The often required [mkfree] function. *) 31 | let mkfree : tvar -> term = 32 | fun x -> Var(x) 33 | 34 | (* Smart constructors to build terms in the [box]. *) 35 | let var : tvar -> tbox = fun v -> 36 | {t = box_var v; m = VarMap.singleton v 1} 37 | 38 | let box : term -> tbox = fun t -> 39 | {t = box t; m = VarMap.empty} 40 | 41 | let abs : tvar -> tbox -> tbox = fun x t -> 42 | let m = VarMap.remove x t.m in 43 | let t = box_apply (fun b -> Abs(b)) (bind_var x t.t) in 44 | {t; m} 45 | 46 | let app : tbox -> tbox -> tbox = fun t u -> 47 | let merge _ n1 n2 = Some(n1 + n2) in 48 | let m = VarMap.union merge t.m u.m in 49 | let t = box_apply2 (fun t u -> App(t,u)) t.t u.t in 50 | {t; m} 51 | 52 | let fresh_var : string -> tvar = 53 | fun x -> new_var mkfree x 54 | 55 | let x : tvar = fresh_var "x" 56 | let y : tvar = fresh_var "y" 57 | let t : tbox = app (var x) (app (app (var y) (var x)) (var x)) 58 | 59 | let _ = 60 | let pp_mapping v n = 61 | Printf.printf "There are %i occurrences of variable %s.\n%!" n (name_of v) 62 | in 63 | VarMap.iter pp_mapping (free_vars t) 64 | -------------------------------------------------------------------------------- /examples/parsed.expected: -------------------------------------------------------------------------------- 1 | Translated to [λx.λy.x]! 2 | -------------------------------------------------------------------------------- /examples/parsed.ml: -------------------------------------------------------------------------------- 1 | (* This example illustrates the way one can convert an AST without binders (or 2 | the output of a parser) into an AST built using [Bindlib]. *) 3 | 4 | open Bindlib 5 | 6 | (* AST of the pure λ-calculus. *) 7 | type term = 8 | | Var of term var 9 | | Abs of (term, term) binder 10 | | App of term * term 11 | 12 | (* Utilities and smart constructors. *) 13 | let mkfree : term var -> term = 14 | fun x -> Var(x) 15 | 16 | let var : term var -> term box = 17 | fun x -> box_var x 18 | 19 | let abs : term var -> term box -> term box = 20 | fun x t -> box_apply (fun b -> Abs(b)) (bind_var x t) 21 | 22 | let app : term box -> term box -> term box = 23 | fun t u -> box_apply2 (fun t u -> App(t,u)) t u 24 | 25 | (* Printing function. *) 26 | let print : out_channel -> term -> unit = fun ch t -> 27 | let rec fn ctxt ch t = 28 | match t with 29 | | Var(x) -> Printf.fprintf ch "%s" (name_of x) 30 | | Abs(b) -> let (x,t,ctxt) = unbind_in ctxt b in 31 | Printf.fprintf ch "λ%s.%a" (name_of x) (fn ctxt) t 32 | | App(t,u) -> Printf.fprintf ch "(%a) %a" (fn ctxt) t (fn ctxt) u 33 | in 34 | fn empty_ctxt ch t 35 | 36 | (* Example of parsing time AST for our language. *) 37 | type pterm = 38 | | PVar of string 39 | | PLam of string * pterm 40 | | PApp of pterm * pterm 41 | 42 | (* Translation function to our AST using bindlib. *) 43 | let trans : pterm -> term = 44 | let rec trans : (string * term var) list -> pterm -> term box = 45 | fun env t -> 46 | match t with 47 | | PVar(x) -> var (List.assoc x env) (* unbound if not found *) 48 | | PLam(x,t) -> let v = new_var mkfree x in 49 | abs v (trans ((x,v)::env) t) 50 | | PApp(t,u) -> app (trans env t) (trans env u) 51 | in 52 | fun t -> unbox (trans [] t) 53 | 54 | (* Translation test. *) 55 | let _ = 56 | let fst = PLam("x",PLam("y",PVar("x"))) in 57 | Printf.printf "Translated to [%a]!\n%!" print (trans fst) 58 | -------------------------------------------------------------------------------- /examples/pred2.expected: -------------------------------------------------------------------------------- 1 | INFERING 2 | 3 | h3 : X(x) 4 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 5 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 6 | ------------------------------ 7 | X(x) 8 | 9 | h3 : X(x) 10 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 11 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 12 | ------------------------------ 13 | ∀₂ X.((X(x)) ⇒ (X(y))) 14 | 15 | h3 : X(x) 16 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 17 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 18 | ------------------------------ 19 | (X(x)) ⇒ (X(y)) 20 | 21 | h3 : X(x) 22 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 23 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 24 | ------------------------------ 25 | X(y) 26 | 27 | h3 : X(x) 28 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 29 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 30 | ------------------------------ 31 | ∀₂ X.((X(y)) ⇒ (X(z))) 32 | 33 | h3 : X(x) 34 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 35 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 36 | ------------------------------ 37 | (X(y)) ⇒ (X(z)) 38 | 39 | h3 : X(x) 40 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 41 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 42 | ------------------------------ 43 | X(z) 44 | 45 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 46 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 47 | ------------------------------ 48 | (X(x)) ⇒ (X(z)) 49 | 50 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 51 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 52 | ------------------------------ 53 | ∀₂ X.((X(x)) ⇒ (X(z))) 54 | 55 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 56 | ------------------------------ 57 | (∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))) 58 | 59 | ------------------------------ 60 | (∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z))))) 61 | 62 | ------------------------------ 63 | ∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))))) 64 | 65 | ------------------------------ 66 | ∀₁ y.(∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z))))))) 67 | 68 | ------------------------------ 69 | ∀₁ x.(∀₁ y.(∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))))))) 70 | 71 | TYPE: ∀₁ x.(∀₁ y.(∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))))))) 72 | 73 | CHECKING 74 | 75 | h3 : X(x) 76 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 77 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 78 | ------------------------------ 79 | X(x) 80 | 81 | h3 : X(x) 82 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 83 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 84 | ------------------------------ 85 | ∀₂ X.((X(x)) ⇒ (X(y))) 86 | 87 | h3 : X(x) 88 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 89 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 90 | ------------------------------ 91 | (X(x)) ⇒ (X(y)) 92 | 93 | h3 : X(x) 94 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 95 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 96 | ------------------------------ 97 | X(y) 98 | 99 | h3 : X(x) 100 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 101 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 102 | ------------------------------ 103 | ∀₂ X.((X(y)) ⇒ (X(z))) 104 | 105 | h3 : X(x) 106 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 107 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 108 | ------------------------------ 109 | (X(y)) ⇒ (X(z)) 110 | 111 | h3 : X(x) 112 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 113 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 114 | ------------------------------ 115 | X(z) 116 | 117 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 118 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 119 | ------------------------------ 120 | (X(x)) ⇒ (X(z)) 121 | 122 | h2 : ∀₂ X.((X(y)) ⇒ (X(z))) 123 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 124 | ------------------------------ 125 | ∀₂ X.((X(x)) ⇒ (X(z))) 126 | 127 | h1 : ∀₂ X.((X(x)) ⇒ (X(y))) 128 | ------------------------------ 129 | (∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))) 130 | 131 | ------------------------------ 132 | (∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z))))) 133 | 134 | ------------------------------ 135 | ∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))))) 136 | 137 | ------------------------------ 138 | ∀₁ y.(∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z))))))) 139 | 140 | ------------------------------ 141 | ∀₁ x.(∀₁ y.(∀₁ z.((∀₂ X.((X(x)) ⇒ (X(y)))) ⇒ ((∀₂ X.((X(y)) ⇒ (X(z)))) ⇒ (∀₂ X.((X(x)) ⇒ (X(z)))))))) 142 | 143 | OK 144 | -------------------------------------------------------------------------------- /examples/translate.expected: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rlepigre/ocaml-bindlib/0a3fed2902e0222dc6450af0ddf1c2a60beff1c0/examples/translate.expected -------------------------------------------------------------------------------- /examples/translate.ml: -------------------------------------------------------------------------------- 1 | (* This example illustrates the use of [copy_var] to translate from one AST to 2 | another, without relying on an environment for variables. It also shows the 3 | difference between [vbind] and [bind_var]. *) 4 | 5 | open Bindlib 6 | 7 | (* Language A with its AST and smart constructors. *) 8 | module A = 9 | struct 10 | type term = 11 | | A_Var of term var 12 | | A_Abs of (term, term) binder 13 | | A_App of term * term 14 | 15 | let mkfree x = A_Var(x) 16 | 17 | let var x = box_var x 18 | let abs x t = box_apply (fun b -> A_Abs(b)) (bind_var x t) 19 | let app = box_apply2 (fun t u -> A_App(t,u)) 20 | end 21 | 22 | (* Language B with its AST and smart constructors. *) 23 | module B = 24 | struct 25 | type term = 26 | | B_Var of term var 27 | | B_Abs of (term, term) binder 28 | | B_App of term * term 29 | 30 | let mkfree x = B_Var(x) 31 | 32 | let var x = box_var x 33 | let abs x t = box_apply (fun b -> B_Abs(b)) (bind_var x t) 34 | let app = box_apply2 (fun t u -> B_App(t,u)) 35 | end 36 | 37 | (* Conversion functions between variables. *) 38 | let a_to_b_var : A.term var -> B.term var = 39 | fun x -> copy_var x B.mkfree (name_of x) 40 | 41 | let b_to_a_var : B.term var -> A.term var = 42 | fun x -> copy_var x A.mkfree (name_of x) 43 | 44 | (* Translation function. *) 45 | let translate : A.term -> B.term = 46 | let rec tr : A.term -> B.term box = fun t -> 47 | match t with 48 | | A.A_Var(x) -> B.var (a_to_b_var x) 49 | | A.A_Abs(b) -> let (x,t) = unbind b in 50 | B.abs (a_to_b_var x) (tr t) 51 | | A.A_App(t,u) -> B.app (tr t) (tr u) 52 | in 53 | fun t -> unbox (tr t) 54 | 55 | (* Tests. *) 56 | let id_a = 57 | let x = new_var A.mkfree "x" in 58 | unbox (A.abs x (A.var x)) 59 | 60 | let id_b = translate id_a 61 | -------------------------------------------------------------------------------- /examples/unif.expected: -------------------------------------------------------------------------------- 1 | try c1 = c1 2 | give c1 = c1 3 | 4 | try c1 = c2 5 | Clash 6 | 7 | try (\x0 -> x0) c1 = (\x0 -> x0) c1 8 | give (\x0 -> x0) c1 = (\x0 -> x0) c1 9 | 10 | try (\x0 -> x0) c1 = (\x0 -> x0) c2 11 | Clash 12 | 13 | try (\x0 -> x0) c1 = ? c1 14 | give (\x0 -> x0) c1 = (\x0 -> x0) c1 15 | 16 | try (\x0 -> x0) c1 = ? c2 17 | give (\x0 -> x0) c1 = (\x0 -> c1) c2 18 | 19 | try (\x0 -> x0) c1 = ? c1 (\x0 -> x0) 20 | give (\x0 -> x0) c1 = (\x0 x1 -> x0) c1 (\x0 -> x0) 21 | 22 | try ? c1 = f (? c1) 23 | Too_Deep 24 | 25 | try ? (? c1) = f (? (? c1)) 26 | Too_Deep 27 | 28 | try c1 = ? c1 c2 29 | give c1 = (\x0 x1 -> x0) c1 c2 30 | 31 | try c2 = ? c1 c2 32 | give c2 = (\x0 x1 -> x1) c1 c2 33 | 34 | -------------------------------------------------------------------------------- /lib/dune: -------------------------------------------------------------------------------- 1 | (library 2 | (name bindlib) 3 | (public_name bindlib) 4 | (synopsis "An efficient representation of binders") 5 | (preprocess 6 | (action 7 | (run ocaml %{project_root}/lib/pp.ml %{ocaml_version} %{input-file}))) 8 | (preprocessor_deps pp.ml) 9 | (modules bindlib) 10 | (wrapped false)) 11 | -------------------------------------------------------------------------------- /lib/pp.ml: -------------------------------------------------------------------------------- 1 | (** Preprocessor for removing the "[@@unboxed]" attribute on [Bindlib.any_var] 2 | if the OCaml version is lower that 4.11. *) 3 | 4 | let iter_lines : (string -> unit) -> string -> unit = fun f file -> 5 | let ic = open_in file in 6 | try while true do f (input_line ic) done with End_of_file -> close_in ic 7 | 8 | (** OCaml version given as first command line argument. *) 9 | let version = 10 | match String.split_on_char '.' Sys.argv.(1) with 11 | | major :: minor :: _ -> (int_of_string major, int_of_string minor) 12 | | _ -> assert false 13 | 14 | (** File to process given as second command line argument. *) 15 | let input_file = Sys.argv.(2) 16 | 17 | let print_line : string -> unit = fun line -> 18 | print_string line; print_char '\n' 19 | 20 | let print_line_if_not_unbox : string -> unit = fun line -> 21 | if String.trim line <> "[@@unboxed]" then print_line line 22 | 23 | let _ = 24 | let handle_line = 25 | if version < (4, 11) then print_line_if_not_unbox else print_line 26 | in 27 | iter_lines handle_line input_file 28 | --------------------------------------------------------------------------------