12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394open!Coreopen!ImportmoduleElem=structmoduleKeyed=structtypet=|T:{key:'k;id:'kType_equal.Id.t;compare:'k->'k->int}->tletcompare(T{key=key1;id=id1;compare=compare1})(T{key=key2;id=id2;compare=_})=matchType_equal.Id.same_witnessid1id2with|SomeT->compare1key1key2|None->(* Use the Uid comparison function so that the comparator is stable.
This function will never return 0 because we've already established
that these type-ids are not equal*)Type_equal.Id.Uid.compare(Type_equal.Id.uidid1)(Type_equal.Id.uidid2);;letsexp_of_t(T{key;id;compare=_})=Type_equal.Id.to_sexpidkeyletcreate~key~id~compare=T{key;id;compare}endletkeyed~compareid=stage(funkey->Keyed.create~key~id~compare)typet=|Subst_from|Subst_into|AssocofKeyed.t|Switchofint[@@derivingsexp_of,compare]letto_string=letoffset=Char.to_int'a'inletlower_nibble_to_alphac=Int.bit_andc0b1111+offset|>Char.of_int_exninletchar_to_alphabufc=letc=Char.to_intcinletlower=lower_nibble_to_alphacinletupper=lower_nibble_to_alpha(Int.shift_rightc4)inBuffer.add_charbufupper;Buffer.add_charbuflowerinletkeyed_to_stringk=letbuf=Buffer.create10inSexp.to_buffer_gen(Keyed.sexp_of_tk)~buf~add_char:char_to_alpha~add_string:(funbufstring->String.iterstring~f:(char_to_alphabuf));Buffer.contentsbufinletint_to_stringi=letbuf=Buffer.create4inString.iter(Int.to_stringi)~f:(char_to_alphabuf);Buffer.contentsbufinfunction|Subst_from->"x"|Subst_into->"y"|Assock->keyed_to_stringk|Switchi->int_to_stringi;;endtypet={items:Elem.tlist;string_repr:stringLazy.t}letsexp_of_tt=[%sexp_of:Elem.tlist]t.itemsletcompareab=[%compare:Elem.tlist]a.itemsb.itemsletempty={items=[];string_repr=Lazy.return"bonsai_path"}letappendtele={items=t.items@[ele];string_repr=lazy(let(lazyparent)=t.string_reprinparent^"_"^Elem.to_stringele)};;includeComparable.Make_plain(structtypenonrect=t[@@derivingcompare,sexp_of]end)letto_unique_identifier_stringt=Lazy.forcet.string_repr