123456789101112131415161718192021222324252627282930313233343536373839(* Claude Code
*
* Copyright (C) 2026 Yoann Padioleau
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License
* (LGPL) as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*)(* See Vlc.mli *)type'at=Leafof'a|Nodeof'atoption*'atoptionletbits_of(code:string):intlist=List.filter_map(function'0'->Some0|'1'->Some1|_->None)(List.init(String.lengthcode)(String.getcode))letof_list(codes:(string*'a)list):'at=letrecinsert(node:'atoption)(bits:intlist)(v:'a):'at=match(node,bits)with|None,[]->Leafv|Some_,[]|Some(Leaf_),_->invalid_arg"Vlc.of_list: a code is a prefix of another"|None,b::rest->ifb=0thenNode(Some(insertNonerestv),None)elseNode(None,Some(insertNonerestv))|Some(Node(l,r)),b::rest->ifb=0thenNode(Some(insertlrestv),r)elseNode(l,Some(insertrrestv))inmatchList.fold_left(funtree(code,v)->Some(inserttree(bits_ofcode)v))Nonecodeswith|Somet->t|None->invalid_arg"Vlc.of_list: no codes"letread(b:Bits.t)(table:'at):'a=letrecgo=function|Leafv->v|Node(l,r)->(matchifBits.readb1=0thenlelserwithSomen->gon|None->failwith"Vlc: not a code of the table")ingotableletkraft(codes:(string*'a)list):float=List.fold_left(funacc(code,_)->acc+.(2.**-.float_of_int(List.length(bits_ofcode))))0.codes