package dose3
Dose library (part of Mancoosi tools)
Install
Dune Dependency
Authors
Maintainers
Sources
dose3-7.0.0.tar.gz
md5=bc99cbcea8fca29dca3ebbee54be45e1
sha512=98dc4bd28e9f4aa8384be71b31783ae1afac577ea587118b8457b554ffe302c98e83d0098971e6b81803ee5c4f2befe3a98ef196d6b0da8feb4121e982ad5c2f
doc/src/dose3.algo/strongconflicts_int.ml.html
Source file strongconflicts_int.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
(**************************************************************************************) (* Copyright (C) 2009 Pietro Abate <pietro.abate@pps.jussieu.fr> *) (* Copyright (C) 2009 Mancoosi Project *) (* *) (* This library is free software: you can redistribute it and/or modify *) (* it under the terms of the GNU Lesser General Public License as *) (* published by the Free Software Foundation, either version 3 of the *) (* License, or (at your option) any later version. A special linking *) (* exception to the GNU Lesser General Public License applies to this *) (* library, see the COPYING file for more information. *) (**************************************************************************************) (** Strong Conflicts *) open ExtLib open Dose_common include Util.Logging (struct let label = "dose_algo.strongconflicts_int" end) module SG = Defaultgraphs.IntPkgGraph.G module PkgV = Defaultgraphs.IntPkgGraph.PkgV type cfl_type = Explicit | Conjunctive | Other of Diagnostic.reason_int list module CflE = struct type t = int * int * cfl_type let compare = Stdlib.compare let default = (0, 0, Other []) end (* unlabelled indirected graph, for the cache *) module IG = Graph.Imperative.Matrix.Graph module CG = Graph.Imperative.Graph.ConcreteLabeled (PkgV) (CflE) (** progress bar *) let seedingbar = Util.Progress.create "Strongconflicts_int.seeding" let localbar = Util.Progress.create "Strongconflicts_int.local" (** timer *) let sctimer = Util.Timer.create "Strongconflicts_int.main" (* open Depsolver_int *) module S = Set.Make (struct type t = int let compare = Stdlib.compare end) let swap (p, q) = (min p q, max p q) let to_set l = List.fold_right S.add l S.empty let explicit univ = let conflict_pairs = Hashtbl.create 1023 in Cudf.iteri_packages (fun i p -> List.iter (fun j -> let pair = swap (i, j) in if i <> j && not (Hashtbl.mem conflict_pairs pair) then Hashtbl.add conflict_pairs pair ()) (CudfAdd.resolve_vpkgs_int univ p.Cudf.conflicts)) univ ; conflict_pairs let triangle reverse xpred ypred common = if not (S.is_empty common) then let xrest = S.diff xpred ypred in let yrest = S.diff ypred xpred in let pred_pred = S.fold (fun z acc -> S.union (to_set reverse.(z)) acc) common S.empty in S.subset xrest pred_pred && S.subset yrest pred_pred else false (* [strongconflicts mdf] return the list of strong conflicts *) let strongconflicts univ = let solver = Depsolver_int.init_solver_univ ~global_constraints:[] univ in let reverse = Depsolver_int.reverse_dependencies univ in let size = Cudf.universe_size univ in let cache = IG.make size in Util.Timer.start sctimer ; debug "Pre-seeding ..." ; Util.Progress.set_total seedingbar size ; let cg = SG.create ~size () in for i = 0 to size - 1 do Util.Progress.progress seedingbar ; Defaultgraphs.IntPkgGraph.conjdepgraph_int cg univ i ; IG.add_vertex cache i done ; (* we already add the transitive closure on the fly *) (* let cg = Strongdeps_int.SO.O.add_transitive_closure cg in *) debug "dependency graph : nodes %d , edges %d" (SG.nb_vertex cg) (SG.nb_edges cg) ; (* add all edges to the cache *) SG.iter_edges (IG.add_edge cache) cg ; debug " done" ; let i = ref 0 in let total = ref 0 in let ex = explicit univ in let conflict_size = Hashtbl.length ex in let try_add_edge stronglist p q x y = if not (IG.mem_edge cache p q) then ( IG.add_edge cache p q ; match Depsolver_int.solve solver ~explain:true [p; q] with | Diagnostic.SuccessInt _ -> () | Diagnostic.FailureInt f -> CG.add_edge_e stronglist (p, (x, y, Other (f ())), q)) in let strongraph = CG.create () in Util.Progress.set_total localbar conflict_size ; (* The simplest algorithm. We iterate over all explicit conflicts, * filtering out all couples that cannot possiby be in conflict * because either of strong dependencies or because already considered. * Then we iter over the reverse dependency closures of the selected * conflict and we check all pairs that have not been considered before. * *) Hashtbl.iter (fun (x, y) _ -> incr i ; Util.Progress.progress localbar ; if not (IG.mem_edge cache x y) then ( let donei = ref 0 in let pkg_x = CudfAdd.inttopkg univ x in let pkg_y = CudfAdd.inttopkg univ y in let (a, b) = ( to_set (Depsolver_int.reverse_dependency_closure reverse [x]), to_set (Depsolver_int.reverse_dependency_closure reverse [y]) ) in IG.add_edge cache x y ; CG.add_edge_e strongraph (x, (x, y, Explicit), y) ; debug "(%d of %d) %s # %s ; Strong conflicts %d Tuples %d" !i conflict_size pkg_x.Cudf.package pkg_y.Cudf.package (CG.nb_edges strongraph) (S.cardinal a * S.cardinal b) ; List.iter (fun p -> List.iter (fun q -> if p <> q && not (IG.mem_edge cache p q) then ( IG.add_edge cache p q ; CG.add_edge_e strongraph (p, (x, y, Conjunctive), q))) (y :: SG.pred cg y)) (x :: SG.pred cg x) ; (* unless : * 1- x and y are in triangle, that is: there is ONE reverse dependency * of both x and y that has a disjunction "x | y". *) let xpred = to_set reverse.(x) in let ypred = to_set reverse.(y) in let common = S.inter xpred ypred in if S.cardinal xpred = 1 && S.cardinal ypred = 1 && S.choose xpred = S.choose ypred then ( let p = S.choose xpred in debug "triangle %s - %s (%s)" (CudfAdd.string_of_package pkg_x) (CudfAdd.string_of_package pkg_y) (CudfAdd.string_of_package (CudfAdd.inttopkg univ p)) ; try_add_edge strongraph p x x y ; incr donei ; try_add_edge strongraph p y x y ; incr donei) else if triangle reverse xpred ypred common then debug "debconf triangle %s - %s" (CudfAdd.string_of_package pkg_x) (CudfAdd.string_of_package pkg_y) else S.iter (fun p -> S.iter (fun q -> try_add_edge strongraph p q x y ; incr donei ; if !donei mod 10000 = 0 then debug "%d" !donei) (S.diff b (to_set (IG.succ cache p)))) a ; debug "\n | tuple examined %d" !donei ; total := !total + !donei)) ex ; Util.Progress.reset localbar ; debug " total tuple examined %d" !total ; ignore (Util.Timer.stop sctimer ()) ; strongraph
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>