(* Copyright 2017 IMDEA Software Institute Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. *)
Set Implicit Arguments.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
(******************************************************************************)
(* This file implementations of Canonical structure lemmas (a.k.a. overloaded *)
(* lemmas) for automating three tasks:                                        *)
(*                                                                            *)
(* 1. checking if implications of the form valid e1 -> valid e2 hold by       *)
(* deciding if the terms in e2 are all contained in e1                        *)
(*                                                                            *)
(* 2. checking if dom_eq e1 e2 holds by cancelling the common terms, to       *)
(*    obtain residuals rs1 and rs2, and then issuing a subgoal dom_eq rs1     *)
(*    rs2.                                                                    *)
(*                                                                            *)
(* 3. checking if the union e is undef, because it contains duplicate         *)
(*    pointers or an undef                                                    *)
(******************************************************************************)
(* For each task, we have two implementations: a naive and a                  *)
(* sophisticated one. The lemmas validO, domeqO, invalidO are the naive       *)
(* ones, and validX, domeqX, invalidX are the sophisticated ones. I keep      *)
(* both O/X versions for now, for experimentation purposes, but               *)
(* eventually should retain only validX and domeqX.                           *)
(* First, two general helper concepts for searching in sequences. They will   *)
(* be useful in syntactifying the expressions e1 and e2 for both tasks.       *)
(* The concepts are:                                                          *)
(*                                                                            *)
(* - onth: returns None to signal that an element is not found prefix:        *)
(* - will be used for growing interpretation contexts                         *)
Section Helpers.
Variable A : Type.
Fixpoint onth (s : seq A) n : option A :=
if s is x::sx then if n is nx.+1 then onth sx nx else Some x else None.
Definition prefix s1 s2 :=
forall n x, onth s1 n = some x -> onth s2 n = some x.
(* Lemmas *)

(* Specifications: *)
Lemma size_onth s n : n < size s -> exists x, onth s n = Some x.
Lemma onth_size s n x : onth s n = Some x -> n < size s.
Lemma prefix_onth s t x : x < size s -> prefix s t -> onth s x = onth t x.
End Helpers.