|
| 1 | +(** Tool for converting YAML witness 0.1 ([location_invariant] and [loop_invariant] entries) to YAML witness 2.0 ([invariant_set] entry). *) |
| 2 | + |
| 3 | +open Goblint_lib |
| 4 | +open YamlWitnessType |
| 5 | + |
| 6 | +let invariant2invariant_set_invariant ~location (invariant: Invariant.t): InvariantSet.LoopInvariant.t = |
| 7 | + assert (invariant.type_ = "assertion"); |
| 8 | + assert (invariant.format = "C"); |
| 9 | + { |
| 10 | + location; |
| 11 | + value = invariant.string; |
| 12 | + format = "c_expression" |
| 13 | + } |
| 14 | + |
| 15 | +let strip_location (location: Location.t): Location.t = |
| 16 | + {location with file_hash = None} |
| 17 | + |
| 18 | +let main () = |
| 19 | + let yaml_str = Batteries.input_all stdin in |
| 20 | + let yaml = Yaml.of_string_exn yaml_str in |
| 21 | + let yaml_entries = yaml |> GobYaml.list |> BatResult.get_ok in |
| 22 | + |
| 23 | + let metadata': Metadata.t option ref = ref None in |
| 24 | + let invariants = List.map (fun yaml_entry -> |
| 25 | + let entry = Entry.of_yaml yaml_entry |> Result.get_ok in |
| 26 | + begin match !metadata' with |
| 27 | + | None -> |
| 28 | + metadata' := Some {entry.metadata with format_version = "2.0"} |
| 29 | + | Some metadata -> |
| 30 | + (* all existing metadata should be the same *) |
| 31 | + (* they (should) have different UUIDs, so change UUID to match to compare the rest *) |
| 32 | + assert (Metadata.equal metadata {entry.metadata with uuid = metadata.uuid}) |
| 33 | + end; |
| 34 | + match entry.entry_type with |
| 35 | + | LocationInvariant {location; location_invariant} -> |
| 36 | + let location = strip_location location in |
| 37 | + let invariant = invariant2invariant_set_invariant ~location location_invariant in |
| 38 | + {InvariantSet.Invariant.invariant_type = LocationInvariant invariant} |
| 39 | + | LoopInvariant {location; loop_invariant} -> |
| 40 | + let location = strip_location location in |
| 41 | + let invariant = invariant2invariant_set_invariant ~location loop_invariant in |
| 42 | + {InvariantSet.Invariant.invariant_type = LoopInvariant invariant} |
| 43 | + | _ -> failwith "unsupported entry type" |
| 44 | + ) yaml_entries |
| 45 | + in |
| 46 | + |
| 47 | + let invariant_set: InvariantSet.t = {content = invariants} in |
| 48 | + let entry': Entry.t = { |
| 49 | + metadata = Option.get !metadata'; |
| 50 | + entry_type = InvariantSet invariant_set |
| 51 | + } |
| 52 | + in |
| 53 | + |
| 54 | + let yaml' = `A [Entry.to_yaml entry'] in |
| 55 | + (* to_file/to_string uses a fixed-size buffer... *) |
| 56 | + let yaml_str' = match GobYaml.to_string' yaml' with |
| 57 | + | Ok text -> text |
| 58 | + | Error (`Msg m) -> failwith ("Yaml.to_string: " ^ m) |
| 59 | + in |
| 60 | + Batteries.output_string Batteries.stdout yaml_str' |
| 61 | + |
| 62 | +let () = main () |
0 commit comments