---
# System prepended metadata

title: Example for typing rules v2

---

# Example for typing rules v2

## Example in rust

```rust
#[flux::sig(fn(bool) -> i32{v : v >= 0})]
fn ref_join(b: bool) -> i32 {
    let mut x = 1;
    let mut y = 2;
    let r = if b {
        &mut x
    } else {
        &mut y
    };
    decr(r);
    x
}

#[flux::sig(fn(&mut i32{v : v >= 0}))]
fn decr(r: &mut i32);
```


## Lambda_flux


```rust
let ref_join = rec f〈a0〉(b) :=
    let x = new(ρx) in
    let y = new(ρy) in
    x := 1;
    y := 2;
    let r = if b {
        &mut x
    } else {
        &mut y
    } in
    call decr(r);
    *x


decr : fn(&mut i32{v : v >= 0}) -> ↯
```



## Typechecking
Comments show the state of the checker _after_ the statement

```rust
let ref_join = rec f〈a0〉(b) := // t-fun with type ∀a0:bool. fn(bool〈a0〉) -> i32{v : v ≥ 0}
    // Δ := a0:bool
    // T := ∅
    // Γ := b:bool〈a0〉   // technically Γ also contains f: ∀a0:bool. fn(bool〈a0〉) -> i32{v : v ≥ 0}, which I'm going to omit...

    let x = new(ρx) in  // t-new
      // a0:bool, ρx:loc
      // ρx↦↯
      // b:bool〈a0〉, x:ptr(ρx)

    let y = new(ρy) in // t-new
      // a0:bool, ρx:loc, ρy:loc                  
      // ρx↦↯, ρy↦↯
      // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)                   

    x := 1; // t-assign-strg
      // a0:bool, ρx:loc, ρy:loc 
      // ρx↦i32〈1〉, ρy↦↯
      // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)

    y := 2; // t-assign-strg            
      // a0:bool, ρx:loc, ρy:loc 
      // ρx → i32〈1〉, ρy → i32〈2〉
      // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)                    

    let r = if b { // t-if
      // a0:bool, ρx:loc, ρy:loc, a0 
      // ρx → i32〈1〉, ρy → i32〈2〉
      // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)  

        &mut x // t-strg-mut-rebor
          // a0:bool, ρx:loc, ρy:loc, a0 
          // ρx↦{v. i32〈v〉 | v ≥ 0}, ρy↦i32〈2〉
          // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)
          // 
          // ρx:loc, ρy:loc ⊢ i32〈1〉 <: {v. i32〈v〉 | v ≥ 0}
    } else { // t-if
      // a0:bool, ρx:loc, ρy:loc, ~a0 
      // ρx → i32〈1〉, ρy → i32〈2〉
      // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)    
        
        &mut y  // t-strg-mut-rebor       
           // a0:bool, ρx:loc, ρy:loc, ~a0             
           // ρx↦i32〈1〉, ρy↦{v. i32〈v〉 | v ≥ 0}
           // b:bool〈a0〉, x:ptr(ρx), y:ptr(ρy)             
           //
           // a0: bool, ρx:loc, ρy:loc ⊢ i32〈2〉 <: {v. i32〈v〉 | v ≥ 0}             
    } in // t-if + t-let
      // a0:bool, ρx:loc, ρy:loc                
      // b:bool〈a0〉, ρx↦{v. i32〈v〉 | v ≥ 0}, ρy↦{v. i32〈v〉 | v ≥ 0}
      // x:ptr(ρx), y:ptr(ρy), r:&mut {v. i32〈v〉 | v ≥ 0}

    call decr(r); // t-call
      // a0:bool, ρx:loc, ρy:loc                
      // b:bool〈a0〉, ρx↦{v. i32〈v〉 | v ≥ 0}, ρy↦{v. i32〈v〉 | v ≥ 0}
      // x:ptr(ρx), y:ptr(ρy), r:&mut {v. i32〈v〉 | v ≥ 0}
      //
      // arg subtyping:
      //   a0:bool, ρx:loc, ρy:loc ⊢ &mut {v. i32〈v〉 | v ≥ 0} <: &mut {v. i32〈v〉 | v ≥ 0}

    *x // t-deref-strg + t-fun
      //
      // return type:
      //   a0: bool, ρx:loc, ρy:loc, a1:int, a1 ≥ 0 ⊢ {v. i32〈v〉 | v ≥ 0} <: i32{v. i32〈v〉 | v ≥ 0}
```



```rust

let init_zeros = rec f<a0>(n) :=
  let x = new(ρx) in
  let vec = new(ρv) in
  x := 0;
  vec := Vec<f32>::new();
  let k = rec k<a, b>() :=
    if i < n {
        Vec::push<ρv,b>(vec, 0);
        i := *i + 1;
        call k<a+1, b+1>()
    } else {
        *vec
    } 
  in
  call k<0, 0>()
}
    
```