(* * Dupfree vector *)
(* Author: Maximilian Wuttke *)
From Undecidability.Shared.Libs.PSL Require Import Prelim.
From Undecidability.Shared.Libs.PSL Require Import Tactics.Tactics.
From Undecidability.Shared.Libs.PSL Require Import Vectors.Vectors.
From Undecidability.Shared.Libs.PSL Require Import FiniteTypes.FinTypes.
From Undecidability.Shared.Libs.PSL Require Lists.Dupfree.
Open Scope vector_scope.
Inductive dupfree X : forall n, Vector.t X n -> Prop :=
dupfreeVN :
dupfree (@Vector.nil X)
| dupfreeVC n (x : X) (V : Vector.t X n) :
~ Vector.In x V -> dupfree V -> dupfree (x ::: V).
Ltac vector_dupfree :=
match goal with
| [ |- dupfree (Vector.nil _) ] =>
constructor
| [ |- dupfree (?a ::: ?bs)] =>
constructor; [vector_not_in | vector_dupfree]
end.
Goal dupfree [| 4; 8; 15; 16; 23; 42 |].

Lemma dupfree_tabulate_injective (X : Type) (n : nat) (f : Fin.t n -> X) :
(forall x y, f x = f y -> x = y) ->
dupfree (tabulate f).