Skip to content

Conversation

codyroux
Copy link
Contributor

…ions

Example usage:

open Core
open Bap.Std
open Core_kernel.Std
open Regular.Std
   
module Partition = Graphlib.Std.Partition




let _ =
  let pp = Partition.pp Int.pp in
  let s = Set.empty Int.comparator in
  let s = Set.add s 0 in
  let s = Set.add s 1 in
  let s = Set.add s 2 in
  let s = Set.add s 3 in
  let s = Set.add s 4 in
  let s = Set.add s 5 in
  let s = Set.add s 6 in
  let s = Set.add s 7 in
  let s = Set.add s 8 in
  let s = Set.add s 9 in
  let s = Set.add s 10 in
  let p0 = Partition.trivial s in
  Format.printf "Trivial partition:\n%a\n\n" pp p0;
  let p1 = Partition.discrete s in
  Format.printf "Discrete partition:\n%a\n\n" pp p1;
  let p2 = Partition.merge p1 1 2 in
  let p2 = Partition.merge p2 1 3 in
  Format.printf "Discrete with 1,2 and 3 merged:\n%a\n\n" pp p2;
  let p3 = Partition.refine p0 ~rel:(fun n m -> (n - m) mod 2) ~comp:(fun n m -> n - m) in
  Format.printf "Trivial refined by the relation n~m mod 2:\n%a\n\n" pp p3;
  let p4 = Partition.refine p3 ~rel:(fun n m -> (n - m) mod 3) ~comp:(fun n m -> n - m) in
  Format.printf "And then refined by the relation n~m mod 3:\n%a\n\n" pp p4

@codyroux
Copy link
Contributor Author

I went for simplicity rather than performance. At any rate, any significant performance improvement would probably involve making the representation of the classes themselves more concrete than a seq, e.g. a linked tree such as described in the wikipedia article on union find.

However, this interface should be enough for some of the common uses of partitions, e.g. bisimilarity.

@ivg ivg self-requested a review November 1, 2018 12:41
@ivg ivg self-assigned this Nov 1, 2018
Copy link
Member

@ivg ivg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, thanks!

There is a couple of minor issues, some things to discuss, and one important thing - the tests. We need to add tests to all newly added functions. Please, proceed to lib_test/bap_types/test_graph.ml and try to add tests that check all the invariants of partition. And don't forget to enable tests with the --enable-tests option to the configure script.

Takes an additional [comp] argument to compare for equality
within the equivalence classes. *)
val refine : 'a t -> rel:('a -> 'a -> int) -> comp:('a -> 'a -> int) -> 'a t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is rel having type 'a -> 'a -> int (i.e., the order type) instead of 'a -> 'a -> bool which the type for equivalence? Also, I think that equiv would be a better name, what do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also, let's rename comp to cmp to be consistent with Core's notation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good!

(** [merge p x y] returns the partition p with the classes of [x]
and [y] merged. Returns [p] unchanged if either [x] or [y] are
not part of any equivalence class. *)
val merge : 'a t -> 'a -> 'a -> 'a t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is merge not called union?

Also, both refine and merge should say something about equivalence class ordinals (equivs), i.e., whether they are preserved or not, e.g., whether eqclass p x = eqclass (merge p y z) when not (equiv x y) and not (equiv x z). So far we do not try to preserve them, and people might store class ordinals and apply ordinals obtained from the past partitions to the new partitions. We should either clearly indicate that ordinals make sense only with the partition from which they were obtained and are shuffled on every new repartitioning, or we can try to preserve them. So this is also a point of discussion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge and union are pretty much used interchangeably in this context, either is fine by me.

I'm not sure what you mean by "equivalence class ordinals". Do you mean the representatives of the classes (roots), or their position in the array of roots?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latter, values of type equiv

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's pick union as it more in the line with union/find and unification

@codyroux
Copy link
Contributor Author

codyroux commented Nov 9, 2018

I've addressed most of the comments, and wrote some tests. I'm not sure how to implement "random" equivalences that are refinements of other equivalences, and there are a few invariants of Partition that are hard to test without internal access, but in the meantime, is this acceptable?

@ivg
Copy link
Member

ivg commented Nov 9, 2018

yep, looks good, thanks for the contribution!

@ivg ivg merged commit ded29fd into BinaryAnalysisPlatform:master Nov 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants