# Generic Refinements ``` b ::= % keys are u32, values are String | HashMap[valid: u32 -> bool] % values are String | OptionString[is_some: bool] ``` ```rust let if<a> : forall b: Bool. forall x: a. forall y: a. Bool[b] -> ({() | b = true} -> a[x]) -> ({() | b = false} -> a[y]) -> a[if b then x else y] let new : () -> HashMap[\k: u32. false]; let lookup : forall valid: (u32 -> Bool). HashMap[valid] -> {k. String[k] | valid(k)} -> String; let contains_key : forall valid: (u32 -> Bool). forall key: u32. HashMap[valid] -> String[key] -> bool[valid(key)]; let insert : forall valid: (u32 -> Bool). forall key: u32. forall value: String. HashMap[valid] -> {String[key] | !valid(key)} -> String[value] -> HashMap[\k -> valid(k) || k == key]; let get : forall valid: (u32 -> Bool). forall key: u32. HashMap[valid] -> String[key] -> OptionString[valid(key)] = \m : HashMap[valid]. \k : String[key]. if<Option>( contains_key(m, k), \(): {() | contains_key(m, k) = true}. Some(index(m, k)), \(): {() | contains_key(m, k) = false}. None); let test : () -> () = let zero: u32 = 0 in let one: u32 = 1 in let two: u32 = 2 in let m: HashMap[\k: u32. false] = new() in let m: HashMap[\k: u32. false || k = 0] = insert(m, zero, "cat") in let m: HashMap[\k: u32. false || k = 0 || k = 1] = insert(m, one, "dog") in let _: String = lookup(m, zero) in let _: OptionString[(\k: u32. false || k = 0 || k = 1) 1] = m.get(two) in () ``` ``` Φ; Γ ⊢ e1: bool[b] Φ,b=true; Γ ⊢ e2 <= t Φ,b=false; Γ ⊢ e3 <= t Φ,b=true; Γ ⊢ e2 : {t | r1} Φ,b=false; Γ ⊢ e3 : {t | r2} ---------------------------------- Φ;Γ ⊢ if e1 then e2 else e3 : {t | if b then r1 else r2} ``` ``` Φ; Γ ⊢ e1: bool[b] Φ,b=true; Γ ⊢ e2 : t1 t1 <: t Φ,b=false; Γ ⊢ e3 : t2 t2 <: t ---------------------------------- Φ;Γ ⊢ if e1 then e2 else e3 : t ``` ``` Φ; Γ ⊢ e1: bool[b] Φ,b=true; Γ ⊢ e1 : {v. int[v] | v >= 10} int[1 + 1] <: {v. int[v] | b => v >= 10 && !b => v >= 4} Φ,b=false; Γ ⊢ 2 + 2 : int[2 + 2] int[2 + 2] <: {v. int[v] | v >= 4} ---------------------------------- Φ;Γ ⊢ if b then 1 + 1 else 2 + 2 : int[if b then 1 + 1 else 2 + 2] ``` ```rust let if<a> : forall b: Bool. Bool[b] -> ({() | b = true} -> a) -> ({() | b = false} -> a) -> a ``` ``` λx: {v. int[v] | v > 0}. x + 1 λx: {v. int[v] | v > 0}. // Γ= x: {v. int[v] | v > 0} // Γ = x: int[a], Φ = a:Z, a > 0 x + 1 : int[a + 1] {v. int[v] | v > 0} -> {a. int[a + 1] | a > 0 } (λx. x + 1 : ∀a.int[a] -> int[a + 1]) (λx. x + 1 : {v. int[v] | v > 0} -> {v. int[v] | v > 1}) +: ∀a,b. int[a] -> int[b] -> int[a + b] ```