(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require HighOrd.
Require int.Int.
Require map.Map.

(* Why3 assumption *)
Inductive ref (a:Type) :=
  | mk_ref : a -> ref a.
Axiom ref_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (ref a).
Existing Instance ref_WhyType.
Implicit Arguments mk_ref [[a]].

(* Why3 assumption *)
Definition contents {a:Type} {a_WT:WhyType a} (v:(ref a)): a :=
  match v with
  | (mk_ref x) => x
  end.

Axiom array : forall (a:Type), Type.
Parameter array_WhyType : forall (a:Type) {a_WT:WhyType a},
  WhyType (array a).
Existing Instance array_WhyType.

Parameter elts: forall {a:Type} {a_WT:WhyType a}, (array a) -> (Z -> a).

Parameter length: forall {a:Type} {a_WT:WhyType a}, (array a) -> Z.

Axiom array'invariant : forall {a:Type} {a_WT:WhyType a}, forall (self:(array
  a)), (0%Z <= (length self))%Z.

(* Why3 assumption *)
Definition mixfix_lbrb {a:Type} {a_WT:WhyType a} (a1:(array a)) (i:Z): a :=
  ((elts a1) i).

Parameter mixfix_lblsmnrb: forall {a:Type} {a_WT:WhyType a}, (array a) ->
  Z -> a -> (array a).

Axiom mixfix_lblsmnrb_spec : forall {a:Type} {a_WT:WhyType a},
  forall (a1:(array a)) (i:Z) (v:a), ((length (mixfix_lblsmnrb a1 i
  v)) = (length a1)) /\ ((elts (mixfix_lblsmnrb a1 i
  v)) = (map.Map.set (elts a1) i v)).

Axiom char : Type.
Parameter char_WhyType : WhyType char.
Existing Instance char_WhyType.

(* Why3 assumption *)
Definition matches (a1:(array char)) (i1:Z) (a2:(array char)) (i2:Z)
  (n:Z): Prop := ((0%Z <= i1)%Z /\ (i1 <= ((length a1) - n)%Z)%Z) /\
  (((0%Z <= i2)%Z /\ (i2 <= ((length a2) - n)%Z)%Z) /\ forall (i:Z),
  ((0%Z <= i)%Z /\ (i < n)%Z) -> ((mixfix_lbrb a1
  (i1 + i)%Z) = (mixfix_lbrb a2 (i2 + i)%Z))).

Axiom matches_empty : forall (a1:(array char)) (a2:(array char)) (i1:Z)
  (i2:Z), ((0%Z <= i1)%Z /\ (i1 <= (length a1))%Z) -> (((0%Z <= i2)%Z /\
  (i2 <= (length a2))%Z) -> (matches a1 i1 a2 i2 0%Z)).

Axiom matches_right_extension : forall (a1:(array char)) (a2:(array char))
  (i1:Z) (i2:Z) (n:Z), (matches a1 i1 a2 i2 n) ->
  ((i1 <= (((length a1) - n)%Z - 1%Z)%Z)%Z ->
  ((i2 <= (((length a2) - n)%Z - 1%Z)%Z)%Z -> (((mixfix_lbrb a1
  (i1 + n)%Z) = (mixfix_lbrb a2 (i2 + n)%Z)) -> (matches a1 i1 a2 i2
  (n + 1%Z)%Z)))).

Axiom matches_contradiction_at_first : forall (a1:(array char)) (a2:(array
  char)) (i1:Z) (i2:Z) (n:Z), (0%Z < n)%Z -> ((~ ((mixfix_lbrb a1
  i1) = (mixfix_lbrb a2 i2))) -> ~ (matches a1 i1 a2 i2 n)).

Axiom matches_contradiction_at_i : forall (a1:(array char)) (a2:(array char))
  (i1:Z) (i2:Z) (i:Z) (n:Z), (0%Z < n)%Z -> (((0%Z <= i)%Z /\ (i < n)%Z) ->
  ((~ ((mixfix_lbrb a1 (i1 + i)%Z) = (mixfix_lbrb a2 (i2 + i)%Z))) ->
  ~ (matches a1 i1 a2 i2 n))).

Axiom matches_right_weakening : forall (a1:(array char)) (a2:(array char))
  (i1:Z) (i2:Z) (n:Z) (n':Z), (matches a1 i1 a2 i2 n) -> ((n' < n)%Z ->
  (matches a1 i1 a2 i2 n')).


(* Why3 goal *)
Theorem matches_left_weakening : forall (a1:(array char)) (a2:(array char))
  (i1:Z) (i2:Z) (n:Z) (n':Z), (matches a1 (i1 - (n - n')%Z)%Z a2
  (i2 - (n - n')%Z)%Z n) -> ((n' < n)%Z -> (matches a1 i1 a2 i2 n')).
(* Why3 intros a1 a2 i1 i2 n n' h1 h2. *)
(* YOU MAY EDIT THE PROOF BELOW *)
intros a1 a2 i1 i2 n n' Hmatch Hn.
destruct Hmatch. destruct H0.
red.
split.
 omega.
split.
 omega.
intros i Hi.
replace (i1 + i)%Z with (i1 - (n - n') + (i + (n - n')))%Z.
replace (i2 + i)%Z with (i2 - (n - n') + (i + (n - n')))%Z.
apply H1.
omega.
 omega.
 omega.
Qed.

