Source file nats.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
open Lang
open Xl
open Il
module Value = Runtime.Value
open Util.Source
open Error

(* Conversion between meta-numerics and OCaml numerics *)

let bigint_of_value (value : value) : Bigint.t =
  value |> Value.Get.num |> Num.to_int

let value_of_bigint (add : value -> unit) (n : Bigint.t) : value =
  let value = Value.Make.nat n in
  add value;
  value

(* dec $sum_nat(nat* ) : nat *)

let sum_nat (add : value -> unit) (at : region) (targs : targ list)
    (values_input : value list) : value =
  Extract.zero at targs;
  let values =
    Extract.one at values_input |> Value.Get.list |> List.map bigint_of_value
  in
  let sum = List.fold_left Bigint.( + ) Bigint.zero values in
  value_of_bigint add sum

(* dec $max_nat(nat* ) : nat *)

let max_nat (add : value -> unit) (at : region) (targs : targ list)
    (values_input : value list) : value =
  Extract.zero at targs;
  let values =
    Extract.one at values_input |> Value.Get.list |> List.map bigint_of_value
  in
  let max =
    match values with
    | [] -> error at "max of empty list"
    | hd :: tl -> List.fold_left Bigint.max hd tl
  in
  value_of_bigint add max

(* dec $min_nat(nat* ) : nat *)

let min_nat (add : value -> unit) (at : region) (targs : targ list)
    (values_input : value list) : value =
  Extract.zero at targs;
  let values =
    Extract.one at values_input |> Value.Get.list |> List.map bigint_of_value
  in
  let min =
    match values with
    | [] -> error at "min of empty list"
    | hd :: tl -> List.fold_left Bigint.min hd tl
  in
  value_of_bigint add min