Library hydras.rpo.list_permut

by Evelyne Contejean, LRI

Permutation over lists, and finite multisets.


Set Implicit Arguments.

From Coq Require Import List Multiset Arith Setoid.
From hydras Require Import decidable_set more_list.

Module Type Permut.

Declare Module DS : decidable_set.S.

Definition elt := DS.A.
Definition eq_elt_dec := DS.eq_A_dec.

Fixpoint list_to_multiset (l : list elt) {struct l} : multiset elt :=
  match l with
  | nilEmptyBag elt
  | h :: tl
      munion (SingletonBag _ eq_elt_dec h) (list_to_multiset tl)
  end.

Definition list_permut (l1 l2:list elt) : Prop :=
  meq (list_to_multiset l1) (list_to_multiset l2).

End Permut.

Definition of permutation over lists.

Module Make (DS1 : decidable_set.S) <: Permut with Module DS:= DS1.

Module DS := DS1.
Import DS1.

Definition elt := DS.A.
Definition eq_elt_dec : t1 t2 : elt, {t1 = t2} + {t1 t2} := DS.eq_A_dec.

Fixpoint list_to_multiset (l : list elt) {struct l} : multiset elt :=
  match l with
  | nilEmptyBag elt
  | h :: tl
      munion (SingletonBag _ eq_elt_dec h) (list_to_multiset tl)
  end.

Definition list_permut (l1 l2:list elt) : Prop :=
  meq (list_to_multiset l1) (list_to_multiset l2).

Properties over the multiplicity.

Permutation is a equivalence relation.

Reflexivity.
Theorem list_permut_refl :
  (l : list elt), list_permut l l.

Symetry.
Theorem list_permut_sym :
  l1 l2 : list elt, list_permut l1 l2 list_permut l2 l1.

#[global] Hint Immediate list_permut_refl : core.
#[global] Hint Resolve list_permut_sym : core.

Transitivity.
Theorem list_permut_trans :
   l1 l2 l3 : list elt, list_permut l1 l2 list_permut l2 l3 list_permut l1 l3.

Add Relation (list elt) list_permut
reflexivity proved by list_permut_refl
symmetry proved by list_permut_sym
transitivity proved by list_permut_trans as LP.

Permutation of an empty list.
Lemma list_permut_nil :
  l, list_permut l nil l = nil.

Compatibility Properties.

Permutation is compatible with In.
Lemma in_permut_in :
   l1 l2 e, In e l1 list_permut l1 l2 In e l2.
Add Morphism (In (A :=elt)) with signature (eq ==> list_permut ==> iff) as in_morph.

Lemma cons_permut_in :
   l1 l2 e, list_permut (e :: l1) l2 In e l2.

Permutation is compatible with adding an element.
Lemma context_list_permut_cons :
   e l1 l2, list_permut l1 l2 list_permut (e :: l1) (e :: l2).

Add Morphism (List.cons (A:=elt)) with signature (eq ==> list_permut ==> list_permut)
 as add_elt_morph.

Lemma list_permut_add_inside :
a l1 l2 l3 l4,
  list_permut (l1 ++ l2) (l3 ++ l4)
  list_permut (l1 ++ a :: l2) (l3 ++ a :: l4).

Lemma list_permut_add_cons_inside :
a l l1 l2,
  list_permut l (l1 ++ l2)
  list_permut (a :: l) (l1 ++ a :: l2).

Permutation is compatible with append.
Lemma context_list_permut_app1 :
   l l1 l2, list_permut l1 l2 list_permut (l ++ l1) (l ++ l2).

Lemma context_list_permut_app2 :
   l l1 l2, list_permut l1 l2 list_permut (l1 ++ l) (l2 ++ l).

Add Morphism (List.app (A:=elt))
with signature (list_permut ==> list_permut ==> list_permut) as app_morph.

Lemma list_permut_app_app :
  l1 l2, list_permut (l1 ++ l2) (l2 ++ l1).

Permutation is compatible with removal of common elements
Permutation is compatible with length.
Lemma list_permut_length :
  l1 l2, list_permut l1 l2 length l1 = length l2.

Add Morphism (length (A:=elt)) with signature (list_permut ==> eq) as length_morph.

Permutation is compatible with size.
Lemma list_permut_size :
   size l1 l2, list_permut l1 l2 list_size size l1 = list_size size l2.

Add Parametric Morphism size : (@list_size elt size) with signature (list_permut ==> @eq nat) as list_size_morph.

Permutation is compatible with map.
Lemma list_permut_map :
   f l1 l2, list_permut l1 l2 list_permut (map f l1) (map f l2).

Add Parametric Morphism f : (map f) with signature list_permut ==> list_permut as map_morph.

Permutation for short lists.

Link with AC syntactic decomposition.