Implicit Type (l : list (nat*nat)).Inductive fractran_step : list (nat*nat) -> nat -> nat -> Prop :=
    | in_ft_0 : forall p q l x y, q*y = p*x -> (p,q)::l // x → y
    | in_ft_1 : forall p q l x y, ~ divides q (p*x) -> l // x → y -> (p,q)::l // x → y
  where "l // x → y" := (fractran_step l x y).Inductive fractran_step : list (nat*nat) -> nat -> nat -> Prop :=
    | in_ft_0 : forall p q l x y, q*y = p*x -> (p,q)::l // x → y
    | in_ft_1 : forall p q l x y, ~ divides q (p*x) -> l // x → y -> (p,q)::l // x → y
  where "l // x → y" := (fractran_step l x y).Inductive fractran_step : list (nat*nat) -> nat -> nat -> Prop :=
    | in_ft_0 : forall p q l x y, q*y = p*x -> (p,q)::l // x → y
    | in_ft_1 : forall p q l x y, ~ divides q (p*x) -> l // x → y -> (p,q)::l // x → y
  where "l // x → y" := (fractran_step l x y).Inductive fractran_step : list (nat*nat) -> nat -> nat -> Prop :=
    | in_ft_0 : forall p q l x y, q*y = p*x -> (p,q)::l // x → y
    | in_ft_1 : forall p q l x y, ~ divides q (p*x) -> l // x → y -> (p,q)::l // x → y
  where "l // x → y" := (fractran_step l x y).Definition fractran_regular l := Forall (fun c => snd c <> 0) l.Fact fractran_step_nil_inv x y : nil // x → y <-> False.Fact fractran_step_cons_inv p q l x y : (p,q)::l // x → y <-> q*y = p*x \/ ~ divides q (p*x) /\ l // x → y.Fact mul_pos_inj_l q x y : q <> 0 -> q*x = q*y -> x = y.

(* Specifications: *)
Lemma fractran_step_inv P x y : P // x → y -> exists l p q r, P = l++(p,q)::r /\ (forall u v, In (u,v) l -> ~ divides v (u*x)) /\ q*y=p*x.
Lemma fractran_step_fun l x y1 y2 : fractran_regular l -> l // x → y1 -> l // x → y2 -> y1 = y2.
Lemma fractran_step_bound l : fractran_regular l -> { k | forall x y, l // x → y -> y <= k*x }.