From e5ef5b916a587c28cc09d3fc7a6250e050378e90 Mon Sep 17 00:00:00 2001 From: Frank Hillard Date: Fri, 21 Jun 2024 11:52:33 +0200 Subject: [PATCH] Add get_entrypoint_name function in core + bump to ligo 1.6.0 --- Makefile | 9 +- README.md | 9 +- core/test/test_math.mligo | 30 ++--- core/test/test_utils.mligo | 36 ++--- core/test/test_utils_getentrypointname.mligo | 38 ++++++ core/utils.mligo | 35 ++++- float/test/test_float.mligo | 26 ++-- float/test/test_trigo_float.mligo | 90 ++++++------- float/trigo_float.mligo | 15 ++- ligo.json | 4 +- rational/test/test_rational.mligo | 24 ++-- rational/test/test_trigo_rational.mligo | 130 +++++++++---------- rational/trigo_rational.mligo | 12 +- 13 files changed, 267 insertions(+), 191 deletions(-) create mode 100644 core/test/test_utils_getentrypointname.mligo diff --git a/Makefile b/Makefile index 8979fcc..7a38e69 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -ligo_compiler?=docker run --rm -v "$$PWD":"$$PWD" -w "$$PWD" ligolang/ligo:1.0.0 +ligo_compiler?=docker run --rm -v "$$PWD":"$$PWD" -w "$$PWD" ligolang/ligo:1.6.0 PROTOCOL_OPT?= @@ -9,7 +9,7 @@ help: .PHONY: test -test: test_ligo_utils test_ligo_math test_ligo_float test_ligo_trigo_float test_ligo_trigo_rational test_ligo_trigo_rational +test: test_ligo_utils test_ligo_utils_getentrypointname test_ligo_math test_ligo_float test_ligo_trigo_float test_ligo_trigo_rational test_ligo_trigo_rational test_ligo_trigo_rational: rational/test/test_trigo_rational.mligo @echo "Running integration tests (trigo rational)" @@ -31,6 +31,11 @@ test_ligo_utils: core/test/test_utils.mligo @echo "Running integration tests (is_implicit, bytes_to_nat)" @$(ligo_compiler) run test $^ $(PROTOCOL_OPT) +test_ligo_utils_getentrypointname: core/test/test_utils_getentrypointname.mligo + @echo "Running integration tests (get_entrypoint_name)" + @$(ligo_compiler) run test $^ $(PROTOCOL_OPT) + + test_ligo_math: core/test/test_math.mligo @echo "Running integration tests (Math)" @$(ligo_compiler) run test $^ $(PROTOCOL_OPT) diff --git a/README.md b/README.md index 53a19b8..00e6621 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,15 @@ # math-lib-cameligo This repository contains a math library for [LIGO](https://ligolang.org/). It is -provided in two flavors (`Float` & `Rational`), and the project is structured as -follows +provided in two flavors (`Float` & `Rational`), and the project is structured as +follows 1. [core](./core/README.md): This contains basic math functions - like `isqrt`, `power`, `factorial`, `min`, `max`, `log_10`. + like `isqrt`, `power`, `factorial`, `min`, `max`, `log_10`. It also provides some + useful hack functions like `get_entrypoint_name`, `is_implicit` ("tz1.." ? "KT1.."). 2. [float](./float/README.md): This provides floating point arithmetic for LIGO (which is not supported natively by Michelson). It also provides some useful trigonometric functions. 3. [rational](./rational/README.md): This provides rational arithmetic for LIGO (which is not supported natively by Michelson). It also provides some - useful trigonometric functions. \ No newline at end of file + useful trigonometric functions. diff --git a/core/test/test_math.mligo b/core/test/test_math.mligo index b1b8d2e..922028d 100644 --- a/core/test/test_math.mligo +++ b/core/test/test_math.mligo @@ -1,20 +1,20 @@ #import "../math.mligo" "Math" let test = let _test_isqrt = - let () = assert (Math.isqrt (4n) = 2n) in - let () = assert (Math.isqrt (8n) = 2n) in - let () = assert (Math.isqrt (9n) = 3n) in - let () = assert (Math.isqrt (15n) = 3n) in - let () = assert (Math.isqrt (16n) = 4n) in - let () = assert (Math.isqrt (17n) = 4n) in - Test.log ("Test 'isqrt' finished") in + let () = Assert.assert (Math.isqrt (4n) = 2n) in + let () = Assert.assert (Math.isqrt (8n) = 2n) in + let () = Assert.assert (Math.isqrt (9n) = 3n) in + let () = Assert.assert (Math.isqrt (15n) = 3n) in + let () = Assert.assert (Math.isqrt (16n) = 4n) in + let () = Assert.assert (Math.isqrt (17n) = 4n) in + Test.Next.IO.log ("Test 'isqrt' finished") in let _test_factorial = - let () = assert (Math.factorial (0n) = 1n) in - let () = assert (Math.factorial (1n) = 1n) in - let () = assert (Math.factorial (2n) = 2n) in - let () = assert (Math.factorial (3n) = 6n) in - let () = assert (Math.factorial (4n) = 24n) in - let () = assert (Math.factorial (5n) = 120n) in - let () = assert (Math.factorial (6n) = 720n) in - Test.log ("Test 'factorial' finished") in + let () = Assert.assert (Math.factorial (0n) = 1n) in + let () = Assert.assert (Math.factorial (1n) = 1n) in + let () = Assert.assert (Math.factorial (2n) = 2n) in + let () = Assert.assert (Math.factorial (3n) = 6n) in + let () = Assert.assert (Math.factorial (4n) = 24n) in + let () = Assert.assert (Math.factorial (5n) = 120n) in + let () = Assert.assert (Math.factorial (6n) = 720n) in + Test.Next.IO.log ("Test 'factorial' finished") in () diff --git a/core/test/test_utils.mligo b/core/test/test_utils.mligo index a851bfa..38b3e0f 100644 --- a/core/test/test_utils.mligo +++ b/core/test/test_utils.mligo @@ -4,12 +4,12 @@ let test = //0x050a00000016 00 00430d6ec166d9c623104776aaad3bb50615c6791f // let is_implicit(elt: address) : bool = // let pack_elt : bytes = Bytes.pack elt in - // let () = Test.log((elt, pack_elt)) in + // let () = Test.Next.IO.log((elt, pack_elt)) in // let size : nat = Bytes.length pack_elt in // let is_imp : bytes = Bytes.sub 6n 1n pack_elt in // let addr_bin : bytes = Bytes.sub 7n (abs(size - 7n)) pack_elt in // let value : nat = Utils.Bytes.bytes_to_nat(addr_bin) in - // let () = Test.log(value) in + // let () = Test.Next.IO.log(value) in // ( is_imp = 0x00 ) // in // TEST @@ -68,7 +68,7 @@ let test = let run_test (elt : (address * bool)) : unit = let calculated : bool = f (elt.0) in let expected : bool = elt.1 in - assert (calculated = expected) in + Assert.assert (calculated = expected) in List.iter run_test all_tests in // for KT1... is_implicit() should answer false @@ -80,7 +80,7 @@ let test = // Run tests let () = run_tests all_tests Utils.Address.is_implicit in - Test.log ("Test finished") in + Test.Next.IO.log ("Test finished") in let _test_bytes_is_adddress = (* chest key/payload and time matches -> OK *) @@ -91,7 +91,7 @@ let test = let () = match value with None -> failwith ("a boolean true was expected") - | Some b -> assert (b = true) in + | Some b -> Assert.assert (b = true) in let payload : bytes = 0x050a0000001601f4186c23ee65145a1038193686882c29a1f2009e00 in let value : bool option = @@ -99,45 +99,45 @@ let test = let () = match value with None -> failwith ("a boolean false was expected") - | Some b -> assert (b = false) in + | Some b -> Assert.assert (b = false) in let payload : bytes = 0x07020000001601f4186c23ee65145a1038193686882c29a1f2009e00 in let value : bool option = Utils.Bytes.Packed.is_internal_address_implicit (payload) in let () = match value with - None -> assert (true) + None -> Assert.assert (true) | Some _ -> failwith ("a None was expected") in - Test.log ("Test finished") in + Test.Next.IO.log ("Test finished") in let _test_convert_bytes_to_nat = (* chest key/payload and time matches -> OK *) let payload : bytes = 0x00 in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 0n) in + let () = Assert.assert (value = 0n) in let payload : bytes = 0x0a in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 10n) in + let () = Assert.assert (value = 10n) in let payload : bytes = 0x0A in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 10n) in + let () = Assert.assert (value = 10n) in let payload : bytes = 0x2c in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 44n) in + let () = Assert.assert (value = 44n) in let payload : bytes = 0x2C in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 44n) in + let () = Assert.assert (value = 44n) in let payload : bytes = 0xFF in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 255n) in + let () = Assert.assert (value = 255n) in let payload : bytes = 0x1234 in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 4660n) in + let () = Assert.assert (value = 4660n) in let payload : bytes = 0x001234 in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 4660n) in + let () = Assert.assert (value = 4660n) in let payload : bytes = 0x123400 in let value : nat = Utils.Bytes.Conversion.bytes_to_nat (payload) in - let () = assert (value = 4660n * 256n) in - Test.log ("Test 'rational' finished") in + let () = Assert.assert (value = 4660n * 256n) in + Test.Next.IO.log ("Test 'rational' finished") in () diff --git a/core/test/test_utils_getentrypointname.mligo b/core/test/test_utils_getentrypointname.mligo new file mode 100644 index 0000000..04109b6 --- /dev/null +++ b/core/test/test_utils_getentrypointname.mligo @@ -0,0 +1,38 @@ +#import "../utils.mligo" "Utils" + +module Counter = struct + type storage = int + + type ret = operation list * storage + + [@entry] + let increment (delta : int) (store : storage) : ret = [], store + delta + + [@entry] + let decrement (delta : int) (store : storage) : ret = [], store - delta + + [@entry] + let reset (() : unit) (_ : storage) : ret = [], 0 +end + + +let test = + let _test_get_entrypoint_name = + // let user = Test.nth_bootstrap_account 1 in + let orig = Test.Next.Originate.contract (contract_of Counter) 42 0tez in + let contract = Test.Next.Typed_address.to_contract orig.taddr in + let contract_address : address = Tezos.address contract in + + let verify_entrypoint_name (type a) (name: string) (ep: a contract option) : unit = + match ep with + | None -> failwith "[Test get_entrypoint_name] Unknown entrypoint" + | Some ep -> Assert.assert (Utils.Entrypoint.get_entrypoint_name(ep) = name) + in + let ep_inc = (Tezos.get_entrypoint_opt "%increment" contract_address : int contract option) in + let ep_dec = (Tezos.get_entrypoint_opt "%decrement" contract_address : int contract option) in + let ep_res = (Tezos.get_entrypoint_opt "%reset" contract_address : unit contract option) in + let () = verify_entrypoint_name "%increment" ep_inc in + let () = verify_entrypoint_name "%decrement" ep_dec in + let () = verify_entrypoint_name "%reset" ep_res in + Test.Next.IO.log ("Test 'get_entrypoint_name' finished") in + () diff --git a/core/utils.mligo b/core/utils.mligo index 8e4a43e..ff71b8f 100644 --- a/core/utils.mligo +++ b/core/utils.mligo @@ -8,12 +8,43 @@ module Address = struct //let size : nat = Bytes.length pack_elt in //let addr_bin : bytes = Bytes.sub 7n (abs(size - 7n)) pack_elt in //let value : nat = bytes_to_nat(addr_bin) in - //let () = Test.log(value) in + //let () = Test.Next.IO.log(value) in (is_imp = 0x00) end +module Entrypoint = struct + (** Retrieves the entrypoint name from a given entrypoint ('a contract). The returned entrypoint name is prefixed with "%" *) + let get_entrypoint_name (type a) (ep : a contract) : string = + let pad4 (seq: bytes) : bytes = + let rec padding (bts: bytes) (current_size: nat) (expected_size: nat) : bytes = + if current_size = expected_size then + bts + else + padding (Bytes.concat 0x00 bts) (current_size + 1n) expected_size + in + let current_size = Bytes.length seq in + let () = Assert.Error.assert(current_size <= 4n) "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name (name too long)" in + padding seq current_size 4n + in + let pack_ep : bytes = Bytes.pack ep in + let size = Bytes.length pack_ep in + let () = Assert.Error.assert(size > 28n) "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name (bytes representation too short)" in + let nb_to_read = abs(size - 28n) in + let name_bytes : bytes = Bytes.sub 28n nb_to_read pack_ep in + let nb_to_read_bytes = bytes nb_to_read in + let nb_to_read_4bytes = pad4 nb_to_read_bytes in + // Add prefix for string + let full_name_bytes = Bytes.concat 0x0501 (Bytes.concat nb_to_read_4bytes name_bytes) in + let name : string = match Bytes.unpack full_name_bytes with + | None -> failwith "[@ligo/math-lib/core/utils] Error in Entrypoint.get_entrypoint_name" + | Some n -> n + in + String.concat "%" name + +end + module Bytes = struct module Packed = struct let is_internal_address (pack_elt : bytes) : bool = @@ -59,7 +90,7 @@ module Bytes = struct [@private] let byte_to_nat (hexa : bytes) : nat = let _check_size : unit = - assert_with_error (Bytes.length hexa = 1n) "Can only convert 1 byte" in + Assert.Error.assert (Bytes.length hexa = 1n) "Can only convert 1 byte" in if hexa = 0x00 then 0n else diff --git a/float/test/test_float.mligo b/float/test/test_float.mligo index 9ada0f2..95571d3 100644 --- a/float/test/test_float.mligo +++ b/float/test/test_float.mligo @@ -3,47 +3,47 @@ let test = let _test_scientific = let a : Float.t = Float.inverse (Float.new 6 0) in let value_resolved : int = Float.resolve a 3n in - let () = assert (value_resolved = 166) in + let () = Assert.assert (value_resolved = 166) in let a : Float.t = Float.inverse (Float.new (6) 0) in let a : Float.t = Float.mul (Float.new (-1) 0) a in let value_resolved : int = Float.resolve a 3n in - let () = assert (value_resolved = -166) in + let () = Assert.assert (value_resolved = -166) in let a : Float.t = Float.inverse (Float.new 3 0) in let b : Float.t = Float.inverse (Float.new 2 0) in let value : Float.t = Float.add a b in - //let () = assert(value = { p=5; q=6 }) in + //let () = Assert.assert(value = { p=5; q=6 }) in let value_resolved : int = Float.resolve value 3n in - let () = assert (value_resolved = 833) in + let () = Assert.assert (value_resolved = 833) in let a : Float.t = Float.inverse (Float.new 3 0) in let b : Float.t = Float.inverse (Float.new 2 0) in let value : Float.t = Float.sub a b in - //let () = assert(value = { p=-1; q=6 }) in + //let () = Assert.assert(value = { p=-1; q=6 }) in let value_resolved : int = Float.resolve value 3n in - let () = assert (value_resolved = -166) in + let () = Assert.assert (value_resolved = -166) in let a : Float.t = Float.inverse (Float.new 3 0) in let b : Float.t = Float.inverse (Float.new 2 0) in let value : Float.t = Float.mul a b in - //let () = assert(value = { p=1; q=6 }) in + //let () = Assert.assert(value = { p=1; q=6 }) in let value_resolved : int = Float.resolve value 3n in - let () = assert (value_resolved = 166) in + let () = Assert.assert (value_resolved = 166) in let a : Float.t = Float.inverse (Float.new 3 0) in let b : Float.t = Float.inverse (Float.new 2 0) in let value : Float.t = Float.div a b in - //let () = assert(value = { p=2; q=3 }) in + //let () = Assert.assert(value = { p=2; q=3 }) in let value_resolved : int = Float.resolve value 3n in - let () = assert (value_resolved = 666) in + let () = Assert.assert (value_resolved = 666) in // 1/2 % 1/3 let a : Float.t = Float.inverse (Float.new 2 0) in let b : Float.t = Float.inverse (Float.new 3 0) in let value : Float.t = Float.modulo a b in - //let () = assert(value = { p=2; q=3 }) in + //let () = Assert.assert(value = { p=2; q=3 }) in let value_resolved : int = Float.resolve value 3n in - let () = assert (value_resolved = 166) in - Test.log ("Test finished") in + let () = Assert.assert (value_resolved = 166) in + Test.Next.IO.log ("Test finished") in () diff --git a/float/test/test_trigo_float.mligo b/float/test/test_trigo_float.mligo index bc5c7ec..e2b72ba 100644 --- a/float/test/test_trigo_float.mligo +++ b/float/test/test_trigo_float.mligo @@ -12,32 +12,32 @@ let test = Float.lt diff error_threshold in // ASSERT - let () = Test.log ("sin(0)") in - let () = assert (test_sinus (Trigo.zero, Trigo.zero)) in - let () = Test.log ("sin(Pi/2)") in - let () = assert (test_sinus (Trigo.pi_half, Trigo.one)) in - let () = Test.log ("sin(Pi)") in - let () = assert (test_sinus (Trigo.pi, Trigo.zero)) in - let () = Test.log ("sin(3*Pi/2)") in - let () = assert (test_sinus (Trigo.three_pi_half, Trigo.minus_one)) in - let () = Test.log ("sin(2*Pi)") in - let () = assert (test_sinus (Trigo.two_pi, Trigo.zero)) in - let () = Test.log ("sin(Pi/4)") in + let () = Test.Next.IO.log ("sin(0)") in + let () = Assert.assert (test_sinus (Trigo.zero, Trigo.zero)) in + let () = Test.Next.IO.log ("sin(Pi/2)") in + let () = Assert.assert (test_sinus (Trigo.pi_half, Trigo.one)) in + let () = Test.Next.IO.log ("sin(Pi)") in + let () = Assert.assert (test_sinus (Trigo.pi, Trigo.zero)) in + let () = Test.Next.IO.log ("sin(3*Pi/2)") in + let () = Assert.assert (test_sinus (Trigo.three_pi_half, Trigo.minus_one)) in + let () = Test.Next.IO.log ("sin(2*Pi)") in + let () = Assert.assert (test_sinus (Trigo.two_pi, Trigo.zero)) in + let () = Test.Next.IO.log ("sin(Pi/4)") in let expected = (Float.div Trigo.sqrt_2 Trigo.two) in - let () = assert (test_sinus (Trigo.pi_quarter, expected)) in - let () = Test.log ("sin(Pi/6)") in + let () = Assert.assert (test_sinus (Trigo.pi_quarter, expected)) in + let () = Test.Next.IO.log ("sin(Pi/6)") in let expected = (Float.inverse Trigo.two) in - let () = assert (test_sinus (Trigo.pi_sixth, expected)) in - let () = Test.log ("sin(Pi/3)") in + let () = Assert.assert (test_sinus (Trigo.pi_sixth, expected)) in + let () = Test.Next.IO.log ("sin(Pi/3)") in let expected = (Float.div Trigo.sqrt_3 Trigo.two) in - let () = assert (test_sinus (Trigo.pi_third, expected)) in - let () = Test.log ("sin(-Pi/2)") in + let () = Assert.assert (test_sinus (Trigo.pi_third, expected)) in + let () = Test.Next.IO.log ("sin(-Pi/2)") in let angle = Float.sub Trigo.zero Trigo.pi_half in - let () = assert (test_sinus (angle, Trigo.minus_one)) in - let () = Test.log ("sin(-3*Pi/2)") in + let () = Assert.assert (test_sinus (angle, Trigo.minus_one)) in + let () = Test.Next.IO.log ("sin(-3*Pi/2)") in let angle = Float.sub Trigo.pi_half Trigo.two_pi in - let () = assert (test_sinus (angle, Trigo.one)) in - Test.log ("Test 'trigo sinus (with float)' finished") in + let () = Assert.assert (test_sinus (angle, Trigo.one)) in + Test.Next.IO.log ("Test 'trigo sinus (with float)' finished") in let _test_trigo_cosinus = // GIVEN @@ -48,38 +48,38 @@ let test = Float.lt diff error_threshold in // ASSERT - let () = Test.log ("cos(0)") in - let () = assert (test_cosinus (Trigo.zero, Trigo.one)) in - let () = Test.log ("cos(Pi/2)") in - let () = assert (test_cosinus (Trigo.pi_half, Trigo.zero)) in - let () = Test.log ("cos(Pi)") in - let () = assert (test_cosinus (Trigo.pi, Trigo.minus_one)) in - let () = Test.log ("cos(3*Pi/2)") in - let () = assert (test_cosinus (Trigo.three_pi_half, Trigo.zero)) in - let () = Test.log ("cos(2*Pi)") in - let () = assert (test_cosinus (Trigo.two_pi, Trigo.one)) in - let () = Test.log ("cos(Pi/4)") in + let () = Test.Next.IO.log ("cos(0)") in + let () = Assert.assert (test_cosinus (Trigo.zero, Trigo.one)) in + let () = Test.Next.IO.log ("cos(Pi/2)") in + let () = Assert.assert (test_cosinus (Trigo.pi_half, Trigo.zero)) in + let () = Test.Next.IO.log ("cos(Pi)") in + let () = Assert.assert (test_cosinus (Trigo.pi, Trigo.minus_one)) in + let () = Test.Next.IO.log ("cos(3*Pi/2)") in + let () = Assert.assert (test_cosinus (Trigo.three_pi_half, Trigo.zero)) in + let () = Test.Next.IO.log ("cos(2*Pi)") in + let () = Assert.assert (test_cosinus (Trigo.two_pi, Trigo.one)) in + let () = Test.Next.IO.log ("cos(Pi/4)") in let expected = (Float.div Trigo.sqrt_2 Trigo.two) in - let () = assert (test_cosinus (Trigo.pi_quarter, expected)) in - let () = Test.log ("cos(Pi/6)") in + let () = Assert.assert (test_cosinus (Trigo.pi_quarter, expected)) in + let () = Test.Next.IO.log ("cos(Pi/6)") in let expected = (Float.div Trigo.sqrt_3 Trigo.two) in - let () = assert (test_cosinus (Trigo.pi_sixth, expected)) in - let () = Test.log ("cos(Pi/3)") in + let () = Assert.assert (test_cosinus (Trigo.pi_sixth, expected)) in + let () = Test.Next.IO.log ("cos(Pi/3)") in let expected = (Float.inverse (Float.new 2 0)) in - let () = assert (test_cosinus (Trigo.pi_third, expected)) in - let () = Test.log ("cos(-Pi/2)") in + let () = Assert.assert (test_cosinus (Trigo.pi_third, expected)) in + let () = Test.Next.IO.log ("cos(-Pi/2)") in let angle = Float.sub (Float.new 0 0) Trigo.pi_half in - let () = assert (test_cosinus (angle, Trigo.zero)) in - let () = Test.log ("cos(-3*Pi/2)") in + let () = Assert.assert (test_cosinus (angle, Trigo.zero)) in + let () = Test.Next.IO.log ("cos(-3*Pi/2)") in let angle = Float.sub Trigo.pi_half Trigo.two_pi in - let () = assert (test_cosinus (angle, Trigo.zero)) in - Test.log ("Test 'trigo cosinus (with float)' finished") in + let () = Assert.assert (test_cosinus (angle, Trigo.zero)) in + Test.Next.IO.log ("Test 'trigo cosinus (with float)' finished") in let _test_trigo = let error_threshold = (Float.inverse (Float.new 1 12)) in let precision : nat = 11n in // cos²(a) + sin²(a) = 1 - let () = Test.log ("cos^2(a) + sin^2(a) = 1") in + let () = Test.Next.IO.log ("cos^2(a) + sin^2(a) = 1") in let angle = Trigo.pi_half in let expected = (Float.new 1 0) in let cos_a = Trigo.cosinus (angle, precision) in @@ -88,6 +88,6 @@ let test = let diff = Float.sub (res) expected in // let error = Float.resolve diff 12n in - let () = assert (Float.lt diff error_threshold) in - Test.log ("Test 'trigo (with float)' finished") in + let () = Assert.assert (Float.lt diff error_threshold) in + Test.Next.IO.log ("Test 'trigo (with float)' finished") in () diff --git a/float/trigo_float.mligo b/float/trigo_float.mligo index 0933d26..7590eed 100644 --- a/float/trigo_float.mligo +++ b/float/trigo_float.mligo @@ -23,8 +23,8 @@ let sqrt_3 : Float.t = {value=17320508075688772935; pow=-19} (* computes sinus for an ange between zero and half_pi *) let sin(a, n : Float.t * nat) : Float.t = - let _check_angle_positive = assert_with_error (Float.gte a zero) "[Trigo_float.sinus] given angle is out of bound" in - let _check_angle_pi_half = assert_with_error (Float.lte a pi_half) "[Trigo_float.sinus] given angle is out of bound" in + let _check_angle_positive = Assert.Error.assert (Float.gte a zero) "[Trigo_float.sinus] given angle is out of bound" in + let _check_angle_pi_half = Assert.Error.assert (Float.lte a pi_half) "[Trigo_float.sinus] given angle is out of bound" in let one = Float.new 1 0 in let two = Float.new 2 0 in //let u = (x - (a+b)/2.0 )/ (b-a)/2.0 @@ -49,17 +49,18 @@ let sin(a, n : Float.t * nat) : Float.t = ] in - let coef_0 = Option.unopt (List.head_opt coef) in - let coef_1 = Option.unopt (List.head_opt (Option.unopt (List.tail_opt coef))) in + let coef_0 = Option.value_with_error "Missing chebychev coef 0" (List.head coef) in + let coef_from_1 = Option.value_with_error "Missing chebychev coef 1" (List.tail coef) in + let coef_1 = Option.value_with_error "Missing chebychev coef 1" (List.head coef_from_1) in let y0 = Float.add coef_0 (Float.mul coef_1 u) in let t0 : Float.t = one in let t1 : Float.t = u in - let coef_from_2 = Option.unopt (List.tail_opt (Option.unopt (List.tail_opt coef))) in + let coef_from_2 = Option.value_with_error "Missing chebychev coef 2" (List.tail coef_from_1) in let rec compute (i, acc, t_prev, t_prev_prev, n, coef : nat * Float.t * Float.t * Float.t * nat * chebychev_coef) : Float.t = if (i <= n) then let t_next_u = Float.sub (Float.mul (Float.mul two u) t_prev) t_prev_prev in - let current_coef = Option.unopt (List.head_opt coef) in - let rest_coef = Option.unopt (List.tail_opt coef) in + let current_coef = Option.value_with_error "Missing chebychev coef" (List.head coef) in + let rest_coef = Option.value_with_error "Missing chebychev coef" (List.tail coef) in let new_acc = Float.add acc (Float.mul t_next_u current_coef) in compute(i + 1n, new_acc, t_next_u, t_prev, n, rest_coef) else diff --git a/ligo.json b/ligo.json index d679912..5b903eb 100644 --- a/ligo.json +++ b/ligo.json @@ -1,7 +1,7 @@ { "name": "@ligo/math-lib", - "version": "1.1.1", - "description": "A math library for LIGO with support for Float & Rational numbers", + "version": "1.1.2", + "description": "A math library for LIGO with support for Float & Rational numbers & extra functions", "directories": { "test": "test" }, diff --git a/rational/test/test_rational.mligo b/rational/test/test_rational.mligo index 37f8fbb..96698c8 100644 --- a/rational/test/test_rational.mligo +++ b/rational/test/test_rational.mligo @@ -4,21 +4,21 @@ let test = let a = Rational.new 6 in let a = Rational.inverse a in let value_resolved : int = Rational.resolve a 3n in - let () = assert (value_resolved = 166) in + let () = Assert.assert (value_resolved = 166) in let a : Rational.t = { p = 1; q = 6 } in let value_resolved : int = Rational.resolve a 3n in - let () = assert (value_resolved = 166) in + let () = Assert.assert (value_resolved = 166) in let a : Rational.t = { p = -1; q = 6 } in let value_resolved : int = Rational.resolve a 3n in - let () = assert (value_resolved = -166) in + let () = Assert.assert (value_resolved = -166) in let a : Rational.t = { p = 1; @@ -31,14 +31,14 @@ let test = } in let value : Rational.t = Rational.add a b in let () = - assert + Assert.assert (value = { p = 5; q = 6 }) in let value_resolved : int = Rational.resolve value 3n in - let () = assert (value_resolved = 833) in + let () = Assert.assert (value_resolved = 833) in let a : Rational.t = { p = 1; @@ -51,14 +51,14 @@ let test = } in let value : Rational.t = Rational.sub a b in let () = - assert + Assert.assert (value = { p = -1; q = 6 }) in let value_resolved : int = Rational.resolve value 3n in - let () = assert (value_resolved = -166) in + let () = Assert.assert (value_resolved = -166) in let a : Rational.t = { p = 1; @@ -71,14 +71,14 @@ let test = } in let value : Rational.t = Rational.mul a b in let () = - assert + Assert.assert (value = { p = 1; q = 6 }) in let value_resolved : int = Rational.resolve value 3n in - let () = assert (value_resolved = 166) in + let () = Assert.assert (value_resolved = 166) in let a : Rational.t = { p = 1; @@ -91,13 +91,13 @@ let test = } in let value : Rational.t = Rational.div a b in let () = - assert + Assert.assert (value = { p = 2; q = 3 }) in let value_resolved : int = Rational.resolve value 3n in - let () = assert (value_resolved = 666) in - Test.log ("Test finished") in + let () = Assert.assert (value_resolved = 666) in + Test.Next.IO.log ("Test finished") in () diff --git a/rational/test/test_trigo_rational.mligo b/rational/test/test_trigo_rational.mligo index a2dfe4f..3a83cba 100644 --- a/rational/test/test_trigo_rational.mligo +++ b/rational/test/test_trigo_rational.mligo @@ -8,211 +8,211 @@ let test = let precision : nat = 11n in // sin(0) - let () = Test.log ("sin(0)") in + let () = Test.Next.IO.log ("sin(0)") in let angle = Trigo.zero in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(PI/2) - let () = Test.log ("sin(Pi/2)") in + let () = Test.Next.IO.log ("sin(Pi/2)") in let angle = Trigo.pi_half in let expected = (Rational.new 1) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(PI) - let () = Test.log ("sin(Pi)") in + let () = Test.Next.IO.log ("sin(Pi)") in let angle = Trigo.pi in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(3*PI/2) - let () = Test.log ("sin(3*Pi/2)") in + let () = Test.Next.IO.log ("sin(3*Pi/2)") in let angle = Trigo.three_pi_half in let expected = (Rational.new (-1)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(2*PI) - let () = Test.log ("sin(2*Pi)") in + let () = Test.Next.IO.log ("sin(2*Pi)") in let angle = Trigo.two_pi in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(PI/4) - let () = Test.log ("sin(Pi/4)") in + let () = Test.Next.IO.log ("sin(Pi/4)") in let angle = Trigo.pi_quarter in let expected = (Rational.div Trigo.sqrt_2 (Rational.new 2)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(PI/6) - let () = Test.log ("sin(Pi/6)") in + let () = Test.Next.IO.log ("sin(Pi/6)") in let angle = Trigo.pi_sixth in let expected = (Rational.inverse (Rational.new 2)) in //let expected = (Rational.div Trigo.sqrt_3 (Rational.new 2)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(PI/3) - let () = Test.log ("sin(Pi/3)") in + let () = Test.Next.IO.log ("sin(Pi/3)") in let angle = Trigo.pi_third in let expected = (Rational.div Trigo.sqrt_3 (Rational.new 2)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(-PI/2) - let () = Test.log ("sin(-Pi/2)") in + let () = Test.Next.IO.log ("sin(-Pi/2)") in let angle = Rational.sub (Rational.new 0) Trigo.pi_half in let expected = (Rational.new (-1)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // sin(-3*PI/2) - let () = Test.log ("sin(-3*Pi/2)") in + let () = Test.Next.IO.log ("sin(-3*Pi/2)") in //let angle = Rational.sub Trigo.zero Trigo.three_pi_half in let angle = Rational.sub Trigo.pi_half Trigo.two_pi in let expected = (Rational.new (1)) in let diff = Rational.sub (Trigo.sinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in - Test.log ("Test 'trigo sinus (with rational)' finished") in + let () = Assert.assert (Rational.lt diff error_threshold) in + Test.Next.IO.log ("Test 'trigo sinus (with rational)' finished") in let _test_trigo_cosinus = let error_threshold = (Rational.inverse (Rational.new (int (Math.power (10n, 12n))))) in let precision : nat = 11n in // cos(0) - let () = Test.log ("cos(0)") in + let () = Test.Next.IO.log ("cos(0)") in let angle = Trigo.zero in let expected = (Rational.new 1) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(PI/2) - let () = Test.log ("cos(Pi/2)") in + let () = Test.Next.IO.log ("cos(Pi/2)") in let angle = Trigo.pi_half in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(PI) - let () = Test.log ("cos(Pi)") in + let () = Test.Next.IO.log ("cos(Pi)") in let angle = Trigo.pi in let expected = (Rational.new (-1)) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(3*PI/2) - let () = Test.log ("cos(3*Pi/2)") in + let () = Test.Next.IO.log ("cos(3*Pi/2)") in let angle = Trigo.three_pi_half in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(2*PI) - let () = Test.log ("cos(2*Pi)") in + let () = Test.Next.IO.log ("cos(2*Pi)") in let angle = Trigo.two_pi in let expected = (Rational.new 1) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(PI/4) - let () = Test.log ("cos(Pi/4)") in + let () = Test.Next.IO.log ("cos(Pi/4)") in let angle = Trigo.pi_quarter in let expected = (Rational.div Trigo.sqrt_2 (Rational.new 2)) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(PI/6) - let () = Test.log ("cos(Pi/6)") in + let () = Test.Next.IO.log ("cos(Pi/6)") in let angle = Trigo.pi_sixth in let expected = (Rational.div Trigo.sqrt_3 (Rational.new 2)) in //let expected = (Rational.div Trigo.sqrt_3 (Rational.new 2)) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(PI/3) - let () = Test.log ("cos(Pi/3)") in + let () = Test.Next.IO.log ("cos(Pi/3)") in let angle = Trigo.pi_third in let expected = (Rational.inverse (Rational.new 2)) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(-PI/2) - let () = Test.log ("cos(-Pi/2)") in + let () = Test.Next.IO.log ("cos(-Pi/2)") in let angle = Rational.sub (Rational.new 0) Trigo.pi_half in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in + let () = Assert.assert (Rational.lt diff error_threshold) in // cos(-3*PI/2) - let () = Test.log ("cos(-3*Pi/2)") in + let () = Test.Next.IO.log ("cos(-3*Pi/2)") in //let angle = Rational.sub Trigo.zero Trigo.three_pi_half in let angle = Rational.sub Trigo.pi_half Trigo.two_pi in let expected = (Rational.new 0) in let diff = Rational.sub (Trigo.cosinus (angle, precision)) expected in - //let () = Test.log(error) in + //let () = Test.Next.IO.log(error) in - let () = assert (Rational.lt diff error_threshold) in - Test.log ("Test 'trigo cosinus (with rational)' finished") in + let () = Assert.assert (Rational.lt diff error_threshold) in + Test.Next.IO.log ("Test 'trigo cosinus (with rational)' finished") in let _test_trigo = let error_threshold = (Rational.inverse (Rational.new (int (Math.power (10n, 12n))))) in let precision : nat = 11n in // cos²(a) + sin²(a) = 1 - let () = Test.log ("cos^2(a) + sin^2(a) = 1") in + let () = Test.Next.IO.log ("cos^2(a) + sin^2(a) = 1") in let angle = Trigo.pi_half in let expected = (Rational.new 1) in let cos_a = Trigo.cosinus (angle, precision) in let sin_a = Trigo.sinus (angle, precision) in let res = Rational.add (Rational.mul cos_a cos_a) (Rational.mul sin_a sin_a) in let diff = Rational.sub (res) expected in - let () = assert (Rational.lt diff error_threshold) in - Test.log ("Test 'trigo (with rational)' finished") in + let () = Assert.assert (Rational.lt diff error_threshold) in + Test.Next.IO.log ("Test 'trigo (with rational)' finished") in () diff --git a/rational/trigo_rational.mligo b/rational/trigo_rational.mligo index 4b3c318..301eb77 100644 --- a/rational/trigo_rational.mligo +++ b/rational/trigo_rational.mligo @@ -178,15 +178,15 @@ let sin (a, n : Rational.t * nat) : Rational.t = failwith ("chebychev_lookup_intervals does not match chebychev_lookup_table") | Some coef -> coef in - let coef_0 = Option.unopt (List.head_opt coef) in - let coef_1 = Option.unopt (List.head_opt (Option.unopt (List.tail_opt coef))) in + let coef_0 = Option.value_with_error "Missing chebychev coef 0" (List.head coef) in + let coef_from_1 = Option.value_with_error "Missing chebychev coef 1" (List.tail coef) in + let coef_1 = Option.value_with_error "Missing chebychev coef 1" (List.head coef_from_1) in let y0 = Rational.add coef_0 (Rational.mul coef_1 u) in let one = Rational.new 1 in let two = Rational.new 2 in let t0 : Rational.t = one in let t1 : Rational.t = u in - let coef_from_2 = - Option.unopt (List.tail_opt (Option.unopt (List.tail_opt coef))) in + let coef_from_2 = Option.value_with_error "Missing chebychev coef 2" (List.tail coef_from_1) in let rec compute (i, acc, t_prev, t_prev_prev, n, coef : nat * Rational.t * Rational.t * Rational.t * nat * chebychev_coef) @@ -195,8 +195,8 @@ let sin (a, n : Rational.t * nat) : Rational.t = then let t_next_u = Rational.sub (Rational.mul (Rational.mul two u) t_prev) t_prev_prev in - let current_coef = Option.unopt (List.head_opt coef) in - let rest_coef = Option.unopt (List.tail_opt coef) in + let current_coef = Option.value_with_error "Missing chebychev coef" (List.head coef) in + let rest_coef = Option.value_with_error "Missing chebychev coef" (List.tail coef) in let new_acc = Rational.add acc (Rational.mul t_next_u current_coef) in compute (i + 1n, new_acc, t_next_u, t_prev, n, rest_coef) else acc in