Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use implicit parameters in the generated code #333

Merged
merged 27 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9952995
Update the lean toolchain
sonmarcho Jul 1, 2024
dd3a7c5
Start computing which type parameters should be implicit/explicit
sonmarcho Sep 7, 2024
e2a7083
Merge remote-tracking branch 'origin/main' into son/implicit
sonmarcho Sep 7, 2024
0aa815e
Update the Primitives.fst file
sonmarcho Sep 7, 2024
9be0681
Update the Lean library
sonmarcho Sep 7, 2024
fd3c5a5
Fix an issue with builtin definitions
sonmarcho Sep 9, 2024
d7f6555
Update the computation of the implicit parameters
sonmarcho Sep 9, 2024
83acae9
Update the extraction
sonmarcho Sep 9, 2024
5f99ae1
Update the extraction of types, trait refs and trait decl refs
sonmarcho Sep 9, 2024
24b7497
Update the extraction of globals
sonmarcho Sep 9, 2024
4333792
Regenerate some of the Lean files
sonmarcho Sep 9, 2024
17afc39
Update the extraction of aggregated arrays
sonmarcho Sep 9, 2024
c8d0f50
Update more Lean tests
sonmarcho Sep 9, 2024
714f2be
Update the F* test files
sonmarcho Sep 9, 2024
8d5d701
Update the test proofs
sonmarcho Sep 9, 2024
9cc2dfb
Update the Primitives.v file
sonmarcho Sep 9, 2024
a630dd7
Regenerate the Coq files
sonmarcho Sep 9, 2024
19e6953
Update the Primitives.v file
sonmarcho Sep 9, 2024
653092b
Fix minor mistakes
sonmarcho Sep 9, 2024
a8b0b32
Update the README
sonmarcho Sep 9, 2024
6553c6b
Update the .gitignore
sonmarcho Sep 9, 2024
53dbdf8
Merge remote-tracking branch 'origin/main' into son/implicit
sonmarcho Sep 9, 2024
c2ce2a3
Fix minor issues
sonmarcho Sep 9, 2024
734163d
Fix a mistake in Primitives.fst
sonmarcho Sep 9, 2024
a14d4c6
Fix more issues
sonmarcho Sep 9, 2024
c95a328
Fix an issue with the Coq projectors
sonmarcho Sep 9, 2024
53a07ee
Reformat the code
sonmarcho Sep 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ tests/fstar/misc/obj/
*.d
*Makefile.coq
*CoqMakefile.conf
*_CoqProject*

# HOL4
.HOLMK
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,13 @@ You need to install OCaml, together with some packages.
We suggest you to follow those [instructions](https://ocaml.org/docs/install.html),
and install OPAM on the way (same instructions).

We use **OCaml 4.13.1**: `opam switch create 4.13.1+options`
Any recent version of **OCaml 4** should do. For instance, if you want to use OCaml
4.14.2:
```
opam switch create 4.14.2
```

The dependencies can then be installed with the following command:
You can then install the dependencies with the following command:

```
opam install ppx_deriving visitors easy_logging zarith yojson core_unix odoc \
Expand Down
156 changes: 78 additions & 78 deletions backends/coq/Primitives.v

Large diffs are not rendered by default.

158 changes: 79 additions & 79 deletions backends/fstar/Primitives.fst

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions backends/lean/Base/Primitives/Alloc.lean
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ namespace boxed -- alloc.boxed

namespace Box -- alloc.boxed.Box

def deref (T : Type) (x : T) : Result T := ok x
def deref_mut (T : Type) (x : T) : Result (T × (T → Result T)) := ok (x, λ x => ok x)
def deref {T : Type} (x : T) : Result T := ok x
def deref_mut {T : Type} (x : T) : Result (T × (T → Result T)) := ok (x, λ x => ok x)

/-- Trait instance -/
def coreopsDerefInst (Self : Type) :
core.ops.deref.Deref Self := {
Target := Self
deref := deref Self
deref := deref
}

/-- Trait instance -/
def coreopsDerefMutInst (Self : Type) :
core.ops.deref.DerefMut Self := {
derefInst := coreopsDerefInst Self
deref_mut := deref_mut Self
deref_mut := deref_mut
}

end Box -- alloc.boxed.Box
Expand Down
156 changes: 78 additions & 78 deletions backends/lean/Base/Primitives/ArraySlice.lean

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions backends/lean/Base/Primitives/Core.lean
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,22 @@ def clone.CloneBool : clone.Clone Bool := {
This acts like a swap effectively in a functional pure world.
We return the old value of `dst`, i.e. `dst` itself.
The new value of `dst` is `src`. -/
@[simp] def mem.replace (a : Type) (dst : a) (src : a) : a × a := (dst, src)
@[simp] def mem.replace {a : Type} (dst : a) (src : a) : a × a := (dst, src)

/- [core::mem::swap] -/
@[simp] def mem.swap (T: Type) (a b: T): T × T := (b, a)
@[simp] def mem.swap {T : Type} (a b : T): T × T := (b, a)

end core

/- [core::option::{core::option::Option<T>}::unwrap] -/
@[simp] def core.option.Option.unwrap (T : Type) (x : Option T) : Result T :=
@[simp] def core.option.Option.unwrap {T : Type} (x : Option T) : Result T :=
Result.ofOption x Error.panic

/- [core::option::Option::take] -/
@[simp] def core.option.Option.take (T: Type) (self: Option T): Option T × Option T := (self, .none)
@[simp] def core.option.Option.take {T: Type} (self: Option T): Option T × Option T := (self, .none)

/- [core::option::Option::is_none] -/
@[simp] def core.option.Option.is_none (T: Type) (self: Option T): Bool := self.isNone
@[simp] def core.option.Option.is_none {T: Type} (self: Option T): Bool := self.isNone

/- [core::clone::Clone::clone_from]:
Source: '/rustc/library/core/src/clone.rs', lines 175:4-175:43
Expand Down
70 changes: 28 additions & 42 deletions backends/lean/Base/Primitives/Vec.lean
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,16 @@ instance (α : Type u) : Inhabited (Vec α) := by
constructor
apply Vec.new

-- TODO: very annoying that the α is an explicit parameter
@[simp]
abbrev Vec.len (α : Type u) (v : Vec α) : Usize :=
abbrev Vec.len {α : Type u} (v : Vec α) : Usize :=
Usize.ofIntCore v.val.length (by constructor <;> scalar_tac)

@[simp]
theorem Vec.len_val {α : Type u} (v : Vec α) : (Vec.len α v).val = v.length :=
theorem Vec.len_val {α : Type u} (v : Vec α) : (Vec.len v).val = v.length :=
by rfl

@[irreducible]
def Vec.push (α : Type u) (v : Vec α) (x : α) : Result (Vec α)
def Vec.push {α : Type u} (v : Vec α) (x : α) : Result (Vec α)
:=
let nlen := List.length v.val + 1
if h : nlen ≤ U32.max || nlen ≤ Usize.max then
Expand All @@ -72,21 +71,13 @@ def Vec.push (α : Type u) (v : Vec α) (x : α) : Result (Vec α)

@[pspec]
theorem Vec.push_spec {α : Type u} (v : Vec α) (x : α) (h : v.val.length < Usize.max) :
∃ v1, v.push α x = ok v1 ∧
∃ v1, v.push x = ok v1 ∧
v1.val = v.val ++ [x] := by
rw [push]; simp
split <;> simp_all <;>
split <;> simp_all
scalar_tac

-- This shouldn't be used
def Vec.insert_fwd (α : Type u) (v: Vec α) (i: Usize) (_: α) : Result Unit :=
if i.val < v.length then
ok ()
else
fail arrayOutOfBounds

-- This is actually the backward function
def Vec.insert (α : Type u) (v: Vec α) (i: Usize) (x: α) : Result (Vec α) :=
def Vec.insert {α : Type u} (v: Vec α) (i: Usize) (x: α) : Result (Vec α) :=
if i.val < v.length then
ok ⟨ v.val.update i.toNat x, by have := v.property; simp [*] ⟩
else
Expand All @@ -95,19 +86,14 @@ def Vec.insert (α : Type u) (v: Vec α) (i: Usize) (x: α) : Result (Vec α) :=
@[pspec]
theorem Vec.insert_spec {α : Type u} (v: Vec α) (i: Usize) (x: α)
(hbound : i.val < v.length) :
∃ nv, v.insert α i x = ok nv ∧ nv.val = v.val.update i.toNat x := by
∃ nv, v.insert i x = ok nv ∧ nv.val = v.val.update i.toNat x := by
simp [insert, *]

def Vec.index_usize {α : Type u} (v: Vec α) (i: Usize) : Result α :=
match v.val.indexOpt i.toNat with
| none => fail .arrayOutOfBounds
| some x => ok x

/- In the theorems below: we don't always need the `∃ ..`, but we use one
so that `progress` introduces an opaque variable and an equality. This
helps control the context.
-/

@[pspec]
theorem Vec.index_usize_spec {α : Type u} [Inhabited α] (v: Vec α) (i: Usize)
(hbound : i.val < v.length) :
Expand Down Expand Up @@ -154,90 +140,90 @@ theorem Vec.index_mut_usize_spec {α : Type u} [Inhabited α] (v: Vec α) (i: Us
simp [h]

/- [alloc::vec::Vec::index]: forward function -/
def Vec.index (T I : Type) (inst : core.slice.index.SliceIndex I (Slice T))
def Vec.index {T I : Type} (inst : core.slice.index.SliceIndex I (Slice T))
(self : Vec T) (i : I) : Result inst.Output :=
sorry -- TODO

/- [alloc::vec::Vec::index_mut]: forward function -/
def Vec.index_mut (T I : Type) (inst : core.slice.index.SliceIndex I (Slice T))
def Vec.index_mut {T I : Type} (inst : core.slice.index.SliceIndex I (Slice T))
(self : Vec T) (i : I) :
Result (inst.Output × (inst.Output → Result (Vec T))) :=
sorry -- TODO

/- Trait implementation: [alloc::vec::Vec] -/
@[reducible]
def Vec.coreopsindexIndexInst (T I : Type)
def Vec.coreopsindexIndexInst {T I : Type}
(inst : core.slice.index.SliceIndex I (Slice T)) :
core.ops.index.Index (alloc.vec.Vec T) I := {
Output := inst.Output
index := Vec.index T I inst
index := Vec.index inst
}

/- Trait implementation: [alloc::vec::Vec] -/
@[reducible]
def Vec.coreopsindexIndexMutInst (T I : Type)
def Vec.coreopsindexIndexMutInst {T I : Type}
(inst : core.slice.index.SliceIndex I (Slice T)) :
core.ops.index.IndexMut (alloc.vec.Vec T) I := {
indexInst := Vec.coreopsindexIndexInst T I inst
index_mut := Vec.index_mut T I inst
indexInst := Vec.coreopsindexIndexInst inst
index_mut := Vec.index_mut inst
}

@[simp]
theorem Vec.index_slice_index {α : Type} (v : Vec α) (i : Usize) :
Vec.index α Usize (core.slice.index.SliceIndexUsizeSliceTInst α) v i =
Vec.index (core.slice.index.SliceIndexUsizeSliceTInst α) v i =
Vec.index_usize v i :=
sorry

@[simp]
theorem Vec.index_mut_slice_index {α : Type} (v : Vec α) (i : Usize) :
Vec.index_mut α Usize (core.slice.index.SliceIndexUsizeSliceTInst α) v i =
Vec.index_mut (core.slice.index.SliceIndexUsizeSliceTInst α) v i =
index_mut_usize v i :=
sorry

end alloc.vec

/-- [alloc::slice::{@Slice<T>}::to_vec] -/
def alloc.slice.Slice.to_vec
(T : Type) (cloneInst : core.clone.Clone T) (s : Slice T) : Result (alloc.vec.Vec T) :=
{T : Type} (cloneInst : core.clone.Clone T) (s : Slice T) : Result (alloc.vec.Vec T) :=
-- TODO: we need a monadic map
sorry

/-- [core::slice::{@Slice<T>}::reverse] -/
def core.slice.Slice.reverse (T : Type) (s : Slice T) : Slice T :=
def core.slice.Slice.reverse {T : Type} (s : Slice T) : Slice T :=
⟨ s.val.reverse, by sorry ⟩

def alloc.vec.Vec.with_capacity (T : Type) (_ : Usize) : alloc.vec.Vec T := Vec.new T
def alloc.vec.Vec.with_capacity {T : Type} (_ : Usize) : alloc.vec.Vec T := Vec.new T

/- [alloc::vec::{(core::ops::deref::Deref for alloc::vec::Vec<T, A>)#9}::deref]:
Source: '/rustc/d59363ad0b6391b7fc5bbb02c9ccf9300eef3753/library/alloc/src/vec/mod.rs', lines 2624:4-2624:27
Name pattern: alloc::vec::{core::ops::deref::Deref<alloc::vec::Vec<@T, @A>>}::deref -/
def alloc.vec.DerefVec.deref (T : Type) (v : Vec T) : Slice T :=
def alloc.vec.DerefVec.deref {T : Type} (v : Vec T) : Slice T :=
⟨ v.val, v.property ⟩

@[reducible]
def core.ops.deref.DerefVec (T : Type) : core.ops.deref.Deref (alloc.vec.Vec T) := {
def core.ops.deref.DerefVec {T : Type} : core.ops.deref.Deref (alloc.vec.Vec T) := {
Target := Slice T
deref := fun v => ok (alloc.vec.DerefVec.deref T v)
deref := fun v => ok (alloc.vec.DerefVec.deref v)
}

/- [alloc::vec::{(core::ops::deref::DerefMut for alloc::vec::Vec<T, A>)#10}::deref_mut]:
Source: '/rustc/d59363ad0b6391b7fc5bbb02c9ccf9300eef3753/library/alloc/src/vec/mod.rs', lines 2632:4-2632:39
Name pattern: alloc::vec::{core::ops::deref::DerefMut<alloc::vec::Vec<@T, @A>>}::deref_mut -/
def alloc.vec.DerefMutVec.deref_mut (T : Type) (v : alloc.vec.Vec T) :
def alloc.vec.DerefMutVec.deref_mut {T : Type} (v : alloc.vec.Vec T) :
Result ((Slice T) × (Slice T → Result (alloc.vec.Vec T))) :=
ok (⟨ v.val, v.property ⟩, λ s => ok ⟨ s.val, s.property ⟩)

/- Trait implementation: [alloc::vec::{(core::ops::deref::DerefMut for alloc::vec::Vec<T, A>)#10}]
Source: '/rustc/d59363ad0b6391b7fc5bbb02c9ccf9300eef3753/library/alloc/src/vec/mod.rs', lines 2630:0-2630:49
Name pattern: core::ops::deref::DerefMut<alloc::vec::Vec<@Self, @>> -/
@[reducible]
def core.ops.deref.DerefMutVec (T : Type) :
def core.ops.deref.DerefMutVec {T : Type} :
core.ops.deref.DerefMut (alloc.vec.Vec T) := {
derefInst := core.ops.deref.DerefVec T
deref_mut := alloc.vec.DerefMutVec.deref_mut T
derefInst := core.ops.deref.DerefVec
deref_mut := alloc.vec.DerefMutVec.deref_mut
}

def alloc.vec.Vec.resize (T : Type) (cloneInst : core.clone.Clone T)
def alloc.vec.Vec.resize {T : Type} (cloneInst : core.clone.Clone T)
(v : alloc.vec.Vec T) (new_len : Usize) (value : T) : Result (alloc.vec.Vec T) := do
if new_len.val < v.length then
ok ⟨ v.val.resize new_len.toNat value, by scalar_tac ⟩
Expand All @@ -249,7 +235,7 @@ def alloc.vec.Vec.resize (T : Type) (cloneInst : core.clone.Clone T)
theorem alloc.vec.Vec.resize_spec {T} (cloneInst : core.clone.Clone T)
(v : alloc.vec.Vec T) (new_len : Usize) (value : T)
(hClone : cloneInst.clone value = ok value) :
∃ nv, alloc.vec.Vec.resize T cloneInst v new_len value = ok nv ∧
∃ nv, alloc.vec.Vec.resize cloneInst v new_len value = ok nv ∧
nv.val = v.val.resize new_len.toNat value := by
rw [resize]
split
Expand Down
31 changes: 16 additions & 15 deletions compiler/AssociatedTypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,11 @@ let compute_norm_trait_types_from_preds (span : Meta.span option)
in
TraitTypeRefMap.of_list rbindings

let ctx_add_norm_trait_types_from_preds (span : Meta.span) (ctx : eval_ctx)
(trait_type_constraints : trait_type_constraint list) : eval_ctx =
let ctx_add_norm_trait_types_from_preds (span : Meta.span option)
(ctx : eval_ctx) (trait_type_constraints : trait_type_constraint list) :
eval_ctx =
let norm_trait_types =
compute_norm_trait_types_from_preds (Some span) trait_type_constraints
compute_norm_trait_types_from_preds span trait_type_constraints
in
{ ctx with norm_trait_types }

Expand Down Expand Up @@ -417,9 +418,9 @@ let norm_ctx_normalize_trait_type_constraint (ctx : norm_ctx)
let ty = norm_ctx_normalize_ty ctx ty in
{ trait_ref; type_name; ty }

let mk_norm_ctx (span : Meta.span) (ctx : eval_ctx) : norm_ctx =
let mk_norm_ctx (span : Meta.span option) (ctx : eval_ctx) : norm_ctx =
{
span = Some span;
span;
norm_trait_types = ctx.norm_trait_types;
type_decls = ctx.type_ctx.type_decls;
fun_decls = ctx.fun_ctx.fun_decls;
Expand All @@ -430,17 +431,17 @@ let mk_norm_ctx (span : Meta.span) (ctx : eval_ctx) : norm_ctx =
const_generic_vars = ctx.const_generic_vars;
}

let ctx_normalize_ty (span : Meta.span) (ctx : eval_ctx) (ty : ty) : ty =
let ctx_normalize_ty (span : Meta.span option) (ctx : eval_ctx) (ty : ty) : ty =
norm_ctx_normalize_ty (mk_norm_ctx span ctx) ty

(** Normalize a type and erase the regions at the same time *)
let ctx_normalize_erase_ty (span : Meta.span) (ctx : eval_ctx) (ty : ty) : ty =
let ty = ctx_normalize_ty span ctx ty in
let ty = ctx_normalize_ty (Some span) ctx ty in
Subst.erase_regions ty

let ctx_normalize_trait_type_constraint (span : Meta.span) (ctx : eval_ctx)
(ttc : trait_type_constraint) : trait_type_constraint =
norm_ctx_normalize_trait_type_constraint (mk_norm_ctx span ctx) ttc
norm_ctx_normalize_trait_type_constraint (mk_norm_ctx (Some span) ctx) ttc

(** Same as [type_decl_get_instantiated_variants_fields_types] but normalizes the types *)
let type_decl_get_inst_norm_variants_fields_rtypes (span : Meta.span)
Expand All @@ -451,7 +452,7 @@ let type_decl_get_inst_norm_variants_fields_rtypes (span : Meta.span)
in
List.map
(fun (variant_id, types) ->
(variant_id, List.map (ctx_normalize_ty span ctx) types))
(variant_id, List.map (ctx_normalize_ty (Some span) ctx) types))
res

(** Same as [type_decl_get_instantiated_field_types] but normalizes the types *)
Expand All @@ -461,15 +462,15 @@ let type_decl_get_inst_norm_field_rtypes (span : Meta.span) (ctx : eval_ctx)
let types =
Subst.type_decl_get_instantiated_field_types def opt_variant_id generics
in
List.map (ctx_normalize_ty span ctx) types
List.map (ctx_normalize_ty (Some span) ctx) types

(** Same as [ctx_adt_value_get_instantiated_field_rtypes] but normalizes the types *)
let ctx_adt_value_get_inst_norm_field_rtypes (span : Meta.span) (ctx : eval_ctx)
(adt : adt_value) (id : type_id) (generics : generic_args) : ty list =
let types =
Subst.ctx_adt_value_get_instantiated_field_types span ctx adt id generics
in
List.map (ctx_normalize_ty span ctx) types
List.map (ctx_normalize_ty (Some span) ctx) types

(** Same as [ctx_adt_value_get_instantiated_field_types] but normalizes the types
and erases the regions. *)
Expand All @@ -479,7 +480,7 @@ let type_decl_get_inst_norm_field_etypes (span : Meta.span) (ctx : eval_ctx)
let types =
Subst.type_decl_get_instantiated_field_types def opt_variant_id generics
in
let types = List.map (ctx_normalize_ty span ctx) types in
let types = List.map (ctx_normalize_ty (Some span) ctx) types in
List.map Subst.erase_regions types

(** Same as [ctx_adt_get_instantiated_field_types] but normalizes the types and
Expand All @@ -491,7 +492,7 @@ let ctx_adt_get_inst_norm_field_etypes (span : Meta.span) (ctx : eval_ctx)
Subst.ctx_adt_get_instantiated_field_types ctx def_id opt_variant_id
generics
in
let types = List.map (ctx_normalize_ty span ctx) types in
let types = List.map (ctx_normalize_ty (Some span) ctx) types in
List.map Subst.erase_regions types

(** Same as [substitute_signature] but normalizes the types *)
Expand All @@ -507,8 +508,8 @@ let ctx_subst_norm_signature (span : Meta.span) (ctx : eval_ctx)
sg regions_hierarchy
in
let { regions_hierarchy; inputs; output; trait_type_constraints } = sg in
let inputs = List.map (ctx_normalize_ty span ctx) inputs in
let output = ctx_normalize_ty span ctx output in
let inputs = List.map (ctx_normalize_ty (Some span) ctx) inputs in
let output = ctx_normalize_ty (Some span) ctx output in
let trait_type_constraints =
List.map
(ctx_normalize_trait_type_constraint span ctx)
Expand Down
Loading
Loading