123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150open!CoremoduleDependencies=Fix_id.Settyperesolved=privateResolved[@@derivingsexp_of]typeunresolved=privateUnresolved[@@derivingsexp_of]moduleSingle=structtype'resolutiont=|Yes_or_maybe:'at|No:'at|Depends_on_recursion:unresolvedt[@@derivingsexp_of]letmerge_resolved(a:resolvedt)(b:resolvedt):resolvedt=matcha,bwith|Yes_or_maybe,Yes_or_maybe->Yes_or_maybe|Yes_or_maybe,No|No,Yes_or_maybe->Yes_or_maybe|No,No->No;;letmerge_unresolved(a:unresolvedt)(b:unresolvedt):unresolvedt=matcha,bwith|Yes_or_maybe,Yes_or_maybe->Yes_or_maybe|Yes_or_maybe,Depends_on_recursion|Depends_on_recursion,Yes_or_maybe->Yes_or_maybe|Yes_or_maybe,No|No,Yes_or_maybe->Yes_or_maybe|Depends_on_recursion,Depends_on_recursion->Depends_on_recursion|Depends_on_recursion,No|No,Depends_on_recursion->Depends_on_recursion|No,No->No;;letunresolve(a:resolvedt):unresolvedt=matchawith|Yes_or_maybe->Yes_or_maybe|No->No;;(* [resolved_equivalent] is only used during resolution of recursive dependencies. We
map [Depends_on_recursion] to [No] because [No] is the identity for [resolved t] and
as part of resolution, we'll merge in all of the recursive dependencies. *)letresolved_equivalent(a:unresolvedt):resolvedt=matchawith|Yes_or_maybe->Yes_or_maybe|No->No|Depends_on_recursion->No;;endtype'resolutiont={path:'resolutionSingle.t;lifecycle:'resolutionSingle.t;input:'resolutionSingle.t}[@@derivingsexp_of]moduleResolved=structtypenonrect=resolvedtletcreate~path~lifecycle~input={path;lifecycle;input}letmerge(a:t)(b:t)={path=Single.merge_resolveda.pathb.path;lifecycle=Single.merge_resolveda.lifecycleb.lifecycle;input=Single.merge_resolveda.inputb.input};;letboth_use_path(a:t)(b:t):bool=matcha.path,b.pathwith|Yes_or_maybe,Yes_or_maybe->true|Yes_or_maybe,No|No,Yes_or_maybe|No,No->false;;letpathcontains=contains.pathletlifecyclecontains=contains.lifecycleletinputcontains=contains.inputendmoduleUnresolved=structtypenonrect={contains:unresolvedt;recursive_dependencies:Dependencies.t}letmerge{contains=ca;recursive_dependencies=ra}{contains=cb;recursive_dependencies=rb}={contains={path=Single.merge_unresolvedca.pathcb.path;lifecycle=Single.merge_unresolvedca.lifecyclecb.lifecycle;input=Single.merge_unresolvedca.inputcb.input};recursive_dependencies=Dependencies.unionrarb};;letof_resolved(resolved:Resolved.t)={contains={path=Single.unresolveresolved.path;lifecycle=Single.unresolveresolved.lifecycle;input=Single.unresolveresolved.input};recursive_dependencies=Dependencies.empty};;letresolved_equivalent{contains;recursive_dependencies=_}={path=Single.resolved_equivalentcontains.path;lifecycle=Single.resolved_equivalentcontains.lifecycle;input=Single.resolved_equivalentcontains.input};;letlazy_={contains={path=Yes_or_maybe;lifecycle=Yes_or_maybe;input=Yes_or_maybe};recursive_dependencies=Dependencies.empty};;letrecursivefix_id={contains={path=Depends_on_recursion;lifecycle=Depends_on_recursion;input=Depends_on_recursion};recursive_dependencies=Dependencies.singletonfix_id};;letnon_recursive~(path:resolvedSingle.t)~(lifecycle:resolvedSingle.t)~(input:resolvedSingle.t)={contains={path=Single.unresolvepath;lifecycle=Single.unresolvelifecycle;input=Single.unresolveinput};recursive_dependencies=Dependencies.empty};;letremove_dependency(t:t)~on:fix_id={twithrecursive_dependencies=Dependencies.removet.recursive_dependenciesfix_id};;end