File: autoMulti.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (135 lines) | stat: -rw-r--r-- 4,067 bytes parent folder | download
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
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2010-present Institut National de Recherche en Informatique et *)
(* en Automatique and the authors. All rights reserved.                     *)
(*                                                                          *)
(* This software is governed by the CeCILL-B license under French law and   *)
(* abiding by the rules of distribution of free software. You can use,      *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL        *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt.            *)
(****************************************************************************)


(* Test interpretation as all cycles of relaxations *)

module Make(A:AutoArch.S) = struct
  module R = A.R
  module L = A.L

  type t = R.SetSet.t
  type outcome = L.outcome
  type relax = R.relax
  type relax_set = R.Set.t
  type count = int R.Map.t

  let pp = R.pp_set_set

  let interpret all o = R.relaxs_of all (A.E.parse_edges o.L.cycle)

  let intest i = R.Set.unions (R.SetSet.elements i)

  let expand_cumul i =
    let xs =
      R.SetSet.fold
        (fun rs k -> R.expand_cumul rs::k)
        i [] in
    R.SetSet.of_list xs


  let get_relaxed_assuming safe i =
    R.SetSet.fold
      (fun rs k ->
        match R.Set.as_singleton (R.Set.diff rs safe) with
        | None -> k
        | Some r -> r::k)
      i

  let shows_relax safe r i =
    R.SetSet.exists
      (fun rs ->
        match R.Set.as_singleton (R.Set.diff rs safe) with
        | None -> false
        | Some s -> R.compare r s = 0)
      i

  let simplify_for_safes relaxed testing i =
    try
      let i =
        R.SetSet.of_list
          (R.SetSet.fold
             (fun rs k ->
               (* Irrelevant interpretation,
                  corresponding cycle is non-global *)
               if R.Set.is_empty (R.Set.inter relaxed rs) then rs::k
               else k)
             i []) in
    let i =
      R.SetSet.of_list
        (R.SetSet.fold
           (fun rs k ->
             let rs = R.Set.inter testing rs in
             (* No explained *)
             if R.Set.is_empty rs then raise Exit
             else rs::k)
           i []) in
    if R.SetSet.is_empty i then None
    else Some i
    with Exit -> None


(* Safe heuristics *)
  let safe_by_inter i =
    let xss = R.SetSet.elements i in
    match xss with
    | []|[_] -> R.Set.empty
    | xs::(_::_ as xss) -> List.fold_left R.Set.inter xs xss

  let get_mins le ps =
    let rec select_rec r = function
        [] -> r
      | p::ps ->
          if List.exists (fun p0 -> le p0 p) ps
          then select_rec r ps
          else select_rec (p::r) ps in
    select_rec [] (select_rec [] ps)

  let safe_by_cardinal i k =
    let i =
      R.SetSet.of_list
        (get_mins
           (fun s1 s2 -> R.Set.cardinal s1 < R.Set.cardinal s2)
           (R.SetSet.elements i)) in
    let c = R.SetSet.cardinal i in
    if c > 0 then
      R.SetSet.fold
        (fun rs k -> (rs,c)::k)
        i k
    else k


(* Relaxation connt for false safe heuristic *)
  let unexplained safe i =
    let x =
      R.SetSet.filter
        (fun rs -> R.Set.subset rs safe)
        i in
    if R.SetSet.is_empty x then None
    else Some x

 let count _name safe i m =
    R.SetSet.fold
      (fun rs m ->
        if R.Set.subset rs safe then
          R.Set.fold
            (fun r m ->
              let v = try  R.Map.find r m with Not_found -> 0 in
              R.Map.add r (v+1) m)
            rs m
        else m)
      i m
end