123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206(*****************************************************************************)(* *)(* MIT License *)(* Copyright (c) 2022 Nomadic Labs <contact@nomadic-labs.com> *)(* *)(* Permission is hereby granted, free of charge, to any person obtaining a *)(* copy of this software and associated documentation files (the "Software"),*)(* to deal in the Software without restriction, including without limitation *)(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *)(* and/or sell copies of the Software, and to permit persons to whom the *)(* Software is furnished to do so, subject to the following conditions: *)(* *)(* The above copyright notice and this permission notice shall be included *)(* in all copies or substantial portions of the Software. *)(* *)(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*)(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *)(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *)(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*)(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *)(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *)(* DEALINGS IN THE SOFTWARE. *)(* *)(*****************************************************************************)openLang_stdlibmoduleEncodings(L:LIB)=structopenL(**
Encoding type for encapsulating encoding/decoding/input functions.
This type enables us to use more structured types for data
in circuits.
For that, encoding is parameterized by 3 types:
- 'oh is the type of the high-level OCaml representation
- 'u is the unpacked type, i.e. a collection of atomic reprs.
- `p is the packed type, i.e the inner type of Plompiler's repr.
For example, for the representation of a point (pair of scalars),
one might have:
( {x:int; y:int},
scalar repr * scalar repr,
scalar * scalar
) encoding
The first type, the record [{x:int; y:int}], represents an OCaml point,
which becomes the argument taken by the [input] function.
The second type, [scalar repr * scalar repr], is an unpacking of the
encoding. This is used for the result of [decode]. We can use any type
isomorphic to [scalar repr * scalar repr] here.
The last type must be [scalar * scalar], as an encoding of a point will be
of the type [(scalar * scalar) repr].
*)type('oh,'u,'p)encoding={encode:'u->'prepr;decode:'prepr->'u;input:'oh->'pInput.t;of_input:'pInput.t->'oh;}(**
The function [conv] defines conversions for [encoding]s, by changing
the higher-level ['u] and and ['oh] types.
*)letconv:('u1->'u0)->('u0->'u1)->('o1->'o0)->('o0->'o1)->('o0,'u0,'p)encoding->('o1,'u1,'p)encoding=funfgfigie->letencodea=e.encode@@fainletdecodeb=g@@e.decodebinletinputx=e.input@@fixinletof_inputx=gi@@e.of_inputxin{encode;decode;input;of_input}letwith_implicit_bool_check:('prepr->boolreprt)->('o,'u,'p)encoding->('o,'u,'p)encoding=funbce->{ewithinput=(funx->Input.with_implicit_bool_checkbc@@e.inputx)}letwith_assertion:('prepr->unitreprt)->('o,'u,'p)encoding->('o,'u,'p)encoding=funassertione->{ewithinput=(funx->Input.with_assertionassertion@@e.inputx)}(** Encoding combinators *)letscalar_encoding=letencodex=xinletdecodex=xinletinput=Input.scalarinletof_input=Input.to_scalarin{encode;decode;input;of_input}letbool_encoding=letencodex=xinletdecodex=xinletinput=Input.boolinletof_input=Input.to_boolin{encode;decode;input;of_input}letlist_encoding(e:_encoding)=letencodea=to_list@@List.mape.encodeainletdecodex=List.mape.decode(of_listx)inletinputa=Input.list@@List.mape.inputainletof_inputx=List.mape.of_input(Input.to_listx)in{encode;decode;input;of_input}(* Encoding for lists, where we keep the repr of the list itself, not a list
of repr *)letatomic_list_encoding:('a,'brepr,'c)encoding->('alist,'blistrepr,'clist)encoding=fune->letencodea=to_list@@List.mape.encode(of_lista)inletdecodex=to_list@@List.mape.decode(of_listx)inletinputa=Input.list@@List.mape.inputainletof_inputx=List.mape.of_input(Input.to_listx)in{encode;decode;input;of_input}letobj2_encoding(el:_encoding)(er:_encoding)=letencode(a,b)=pair(el.encodea)(er.encodeb)inletdecodep=leta,b=of_pairpin(el.decodea,er.decodeb)inletinput(a,f)=Input.pair(el.inputa)(er.inputf)inletof_inputp=leta,b=Input.to_pairpin(el.of_inputa,er.of_inputb)in{encode;decode;input;of_input}letatomic_obj2_encoding:('a,'brepr,'c)encoding->('d,'erepr,'f)encoding->('a*'d,('b*'e)repr,'c*'f)encoding=funeler->letencodep=leta,b=of_pairpinpair(el.encodea)(er.encodeb)inletdecodep=leta,b=of_pairpinpair(el.decodea)(er.decodeb)inletinput(a,f)=Input.pair(el.inputa)(er.inputf)inletof_inputp=leta,b=Input.to_pairpin(el.of_inputa,er.of_inputb)in{encode;decode;input;of_input}letobj3_encodinge0e1e2=obj2_encodinge0(obj2_encodinge1e2)letatomic_obj3_encodinge0e1e2=atomic_obj2_encodinge0(atomic_obj2_encodinge1e2)letobj4_encodinge0e1e2e3=obj2_encodinge0(obj3_encodinge1e2e3)letatomic_obj4_encodinge0e1e2e3=atomic_obj2_encodinge0(atomic_obj3_encodinge1e2e3)letobj5_encodinge0e1e2e3e4=obj2_encodinge0(obj4_encodinge1e2e3e4)letatomic_obj5_encodinge0e1e2e3e4=atomic_obj2_encodinge0(atomic_obj4_encodinge1e2e3e4)letobj6_encodinge0e1e2e3e4e5=obj2_encodinge0(obj5_encodinge1e2e3e4e5)letatomic_obj6_encodinge0e1e2e3e4e5=atomic_obj2_encodinge0(atomic_obj5_encodinge1e2e3e4e5)letobj7_encodinge0e1e2e3e4e5e6=obj2_encodinge0(obj6_encodinge1e2e3e4e5e6)letatomic_obj7_encodinge0e1e2e3e4e5e6=atomic_obj2_encodinge0(atomic_obj6_encodinge1e2e3e4e5e6)letobj8_encodinge0e1e2e3e4e5e6e7=obj2_encodinge0(obj7_encodinge1e2e3e4e5e6e7)letatomic_obj8_encodinge0e1e2e3e4e5e6e7=atomic_obj2_encodinge0(atomic_obj7_encodinge1e2e3e4e5e6e7)letobj9_encodinge0e1e2e3e4e5e6e7e8=obj2_encodinge0(obj8_encodinge1e2e3e4e5e6e7e8)letatomic_obj9_encodinge0e1e2e3e4e5e6e7e8=atomic_obj2_encodinge0(atomic_obj8_encodinge1e2e3e4e5e6e7e8)letobj10_encodinge0e1e2e3e4e5e6e7e8e9=obj2_encodinge0(obj9_encodinge1e2e3e4e5e6e7e8e9)letatomic_obj10_encodinge0e1e2e3e4e5e6e7e8e9=atomic_obj2_encodinge0(atomic_obj9_encodinge1e2e3e4e5e6e7e8e9)end