Skip to content

Difficulties with refinement subtyping in Steel  #220

@nikswamy

Description

@nikswamy

Some examples ... all the expect failures shouldn't really fail, but they currently do.

  1. Moving a refinement into the ensures clause seems to require an explicit let binding
assume
val test (_:unit) :
  SteelT nat emp (fun _ -> emp)

[@@expect_failure]
let use (_:unit) :
  Steel int emp (fun _ -> emp)
        (requires fun _ -> True)
        (ensures fun _ x _ -> (x >= 0) == true)
  = test() //SMT failure

let shift (_:unit) :
  Steel int emp (fun _ -> emp)
        (requires fun _ -> True)
        (ensures fun _ x _ -> (x >= 0) == true)
  = let x = test() in x
  1. We seem to need to promote SteelAtomic to SteelT before using it as Steel
module SEA= Steel.Effect.Atomic

assume
val atomic (#uses:_) (p:prop)
  : SEA.SteelAtomic (u:unit{p}) uses SEA.unobservable emp (fun _ -> emp)

let use_atomic (p:prop)
  : SteelT (u:unit{p})  emp (fun _ -> emp)
  = atomic p

[@@expect_failure]
let use_atomic_shift (p:prop)
  : Steel unit emp (fun _ -> emp) (fun _ -> True) (fun _ _ _ -> p)
  = atomic p

[@@expect_failure]
let use_atomic_shift (p:prop)
  : Steel unit emp (fun _ -> emp) (fun _ -> True) (fun _ _ _ -> p)
  = let _ = atomic p in ()

[@@expect_failure]
let use_atomic_shift (p:prop)
  : Steel unit emp (fun _ -> emp) (fun _ -> True) (fun _ _ _ -> p)
  = use_atomic p //SMT failure

let use_atomic_shift (p:prop)
  : Steel unit emp (fun _ -> emp) (fun _ -> True) (fun _ _ _ -> p)
  = let x = use_atomic p in x
  1. Local let bindings

This works:

assume 
val f (_:unit) :
  SteelT unit emp (fun _ -> emp)

let g (_:unit)
  : SteelT unit emp (fun _ -> emp) = 
  let f2 () 
    : SteelT unit emp (fun _ -> emp)
    = f (); f ()
  in
  f2 ()

But, this doesn't:

let elim_pure (p:prop)
  : Steel unit (pure p) (fun _ -> emp)
   (requires fun _ -> True)
   (ensures fun _ _ _ -> p)
  = let elim_pure_alt (p:prop)
      : SteelT (_:unit{p}) (pure p) (fun _ -> emp)
      = let _ = Steel.Effect.Atomic.elim_pure p in ()
    in
    let x = elim_pure_alt p in
    ()

Doesn't really seem related to atomic, since this also fails:


assume
val f (p:prop) :
  SteelT (u:unit{p}) emp (fun _ -> emp)

let g (p:prop)
  : Steel unit emp (fun _ -> emp) (requires fun _ -> True) (ensures fun _ _ _ -> p) =
  let f2 (p:prop)
    : SteelT (u:unit{p}) emp (fun _ -> emp)
    = f p
  in
  let x = f2 p in x

Metadata

Metadata

Assignees

No one assigned

    Labels

    steelIssues related to the Steel separation logic effect and tactic in F*

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions