Qcert.Basic.TypeSystem.RSubtype






Section subtype.

  Context {ftype:foreign_type}.
  Context {br:brand_relation}.

Inductive subtype : rtype rtype Prop :=
  | STop r : subtype r
  | SBottom r : subtype r
  | SRefl r : subtype r r
  | SColl r1 r2 : subtype r1 r2 subtype (Coll r1) (Coll r2)
  
Allow width subtyping of open records and depth subtyping of both types of records. Also, a closed record can be a subtype of an open record (but not vice versa)
  | SRec k1 k2 rl1 rl2 pf1 pf2 : ( s r',
                      lookup string_dec rl2 s = Some r'
                       r, lookup string_dec rl1 s = Some r
                                subtype r r')
                                (k2 = Closed k1 = Closed
                                 ( s, In s (domain rl1) In s (domain rl2)))
                                subtype (Rec k1 rl1 pf1) (Rec k2 rl2 pf2)
  | SEither l1 l2 r1 r2 :
      subtype l1 l2
      subtype r1 r2
      subtype (Either l1 r1) (Either l2 r2)
  | SArrow in1 in2 out1 out2:
      subtype in2 in1
      subtype out1 out2
      subtype (Arrow in1 out1) (Arrow in2 out2)
  | SBrand b1 b2 : sub_brands brand_relation_brands b1 b2 subtype (Brand b1) (Brand b2)
  | SForeign ft1 ft2 :
      foreign_type_sub ft1 ft2
      subtype (Foreign ft1) (Foreign ft2)
.

Lemma SRec_open k1 rl1 rl2 pf1 pf2 :
  ( s r',
     lookup string_dec rl2 s = Some r'
      r, lookup string_dec rl1 s = Some r
               subtype r r')
  subtype (Rec k1 rl1 pf1) (Rec Open rl2 pf2).

Lemma SRec_closed_in_domain {k1 k2 rl1 rl2 pf1 pf2} :
  subtype (Rec k1 rl1 pf1) (Rec k2 rl2 pf2)
  ( x, In x (domain rl2) In x (domain rl1)).

Lemma SRec_closed_equiv_domain {k1 rl1 rl2 pf1 pf2} :
  subtype (Rec k1 rl1 pf1) (Rec Closed rl2 pf2)
  ( x, In x (domain rl1) In x (domain rl2)).


  Lemma UIP_refl_dec
        {A:Type}
        (dec: x y:A, {x = y} + {x y})
        {x:A}
        (p1:x = x) : p1 = eq_refl x.

This follows trivially from the consistency of join and subtype. However, this version should have better computational properties.

  Lemma subtype_both_dec x y :
    (prod ({subtype x y} + {¬ subtype x y}) ({subtype y x} + {¬ subtype y x})).

  Theorem subtype_dec x y : {subtype x y} + {¬ subtype x y}.

End subtype.

Lemma subtype_ext {ftype:foreign_type} {br:brand_relation} {a b pfa pfb} :
  subtype (exist _ a pfa) (exist _ b pfb)
              pfa' pfb',
               subtype (exist _ a pfa') (exist _ b pfb').

Lemma subtype_Either_inv {ftype:foreign_type} {br:brand_relation} {τl τr τl' τr'} :
  subtype (Either τl τr) (Either τl' τr')
  subtype τl τl'
  subtype τr τr'.

Lemma subtype_Arrow_inv {ftype:foreign_type} {br:brand_relation} {τl τr τl' τr'} :
  subtype (Arrow τl τr) (Arrow τl' τr')
  subtype τl' τl
  subtype τr τr'.

Notation "r1 <: r2" := (subtype r1 r2) (at level 70).