12345678910111213141516171819202122232425262728293031323334353637383940openUtil.Source(* Cache entry using values *)moduleValueEntry=structtypet=Value.tletdefault:t=Value.Make.booltrueletequal=Value.eqlethash(value:Value.t)=value.note.vhashendmoduleValueCache=Cache.Make.Make(ValueEntry)(* Cache entry using id and values *)moduleCallEntry=structtypet=string*Value.tlistletdefault:t=("",[])letrecequal_values(values_a:Value.tlist)(values_b:Value.tlist):bool=match(values_a,values_b)with|[],[]->true|v_a::rest_a,v_b::rest_b->Value.eqv_av_b&&equal_valuesrest_arest_b|_->falseletequal((id_a,values_a):t)((id_b,values_b):t):bool=ifnot(String.equalid_aid_b)thenfalseelseequal_valuesvalues_avalues_blethash((id,values):t):int=leth=ref((Hashtbl.hashid*31)+17)inList.iter(fun(v:Value.t)->h:=(!h*31)+v.note.vhash)values;!hland0x7FFFFFFFendmoduleCallCache=Cache.Make.Make(CallEntry)