Skip to content

Commit

Permalink
chore: generalize compact interning and fetching
Browse files Browse the repository at this point in the history
Interning/fetching environments and provenances share the same logic, so
we can unify their implementations to improve code reusability.
  • Loading branch information
arthurpaulino committed Apr 10, 2024
1 parent 8d77847 commit 15ac41d
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/coprocessor/gadgets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ pub(crate) fn deconstruct_provenance<F: LurkField, CS: ConstraintSystem<F>>(
let prov_ptr = s.to_ptr(&prov_zptr);

let (a, b, c, d) = {
if let Some([q, res, deps]) = s.deconstruct_provenance(prov_ptr) {
if let Some([q, res, deps]) = s.deconstruct_provenance(&prov_ptr) {
let q_zptr = s.hash_ptr(&q);
let res_zptr = s.hash_ptr(&res);
let deps_zptr = s.hash_ptr(&deps);
Expand Down
4 changes: 2 additions & 2 deletions src/lem/coroutine/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,8 +283,8 @@ fn run<F: LurkField>(
.store
.pop_binding(&img_ptr)
.context("cannot extract {img}'s binding")?;
for (var, ptr) in preimg.iter().zip(preimg_ptrs.iter()) {
bindings.insert_ptr(var.clone(), *ptr);
for (var, ptr) in preimg.iter().zip(preimg_ptrs.into_iter()) {
bindings.insert_ptr(var.clone(), ptr);
}
}
Op::Hide(tgt, sec, src) => {
Expand Down
59 changes: 30 additions & 29 deletions src/lem/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -400,53 +400,54 @@ impl<F: LurkField> Store<F> {
self.fetch_tag(tag).map(|tag| Ptr::new(tag, raw))
}

/// Interns 3 pointers using only 4 raw pointers by ignoring the tags of the
/// first and third pointers
fn intern_compact(&self, a: Ptr, b: Ptr, c: Ptr, tag: Tag) -> Ptr {
let (_, a_raw) = a.into_parts();
let (b_tag, b_raw) = b.into_parts();
let (_, c_raw) = c.into_parts();
let raw = self.intern_raw_ptrs([a_raw, self.tag(b_tag), b_raw, c_raw]);
Ptr::new(tag, raw)
}

/// Fetches 3 pointers that were interned with `intern_compact`
fn fetch_compact(&self, ptr: &Ptr, a_tag: Tag, c_tag: Tag) -> Option<[Ptr; 3]> {
let idx = ptr.get_index2()?;
let [a_raw, b_tag, b_raw, c_raw] = self.fetch_raw_ptrs(idx)?;
let b_tag = self.fetch_tag(b_tag)?;
let a = Ptr::new(a_tag, *a_raw);
let b = Ptr::new(b_tag, *b_raw);
let c = Ptr::new(c_tag, *c_raw);
Some([a, b, c])
}

#[inline]
pub fn push_binding(&self, sym: Ptr, val: Ptr, env: Ptr) -> Ptr {
let (sym_tag, sym_raw) = sym.into_parts();
let (val_tag, val_raw) = val.into_parts();
let (env_tag, env_raw) = env.into_parts();
assert_eq!(sym_tag, Tag::Expr(Sym));
assert_eq!(env_tag, Tag::Expr(Env));
let raw = self.intern_raw_ptrs([sym_raw, self.tag(val_tag), val_raw, env_raw]);
Ptr::new(Tag::Expr(Env), raw)
assert_eq!(sym.tag(), &Tag::Expr(Sym));
assert_eq!(env.tag(), &Tag::Expr(Env));
self.intern_compact(sym, val, env, Tag::Expr(Env))
}

#[inline]
pub fn pop_binding(&self, env: &Ptr) -> Option<[Ptr; 3]> {
assert_eq!(env.tag(), &Tag::Expr(Env));
let idx = env.get_index2()?;
let [sym_pay, val_tag, val_pay, env_pay] = self.fetch_raw_ptrs(idx)?;
let val_tag = self.fetch_tag(val_tag)?;
let sym = Ptr::new(Tag::Expr(Sym), *sym_pay);
let val = Ptr::new(val_tag, *val_pay);
let env = Ptr::new(Tag::Expr(Env), *env_pay);
Some([sym, val, env])
self.fetch_compact(env, Tag::Expr(Sym), Tag::Expr(Env))
}

#[inline]
pub fn intern_provenance(&self, query: Ptr, val: Ptr, deps: Ptr) -> Ptr {
let (query_tag, query_raw) = query.into_parts();
let (val_tag, val_raw) = val.into_parts();
let (deps_tag, deps_raw) = deps.into_parts();
assert_eq!(query_tag, Tag::Expr(Cons));
assert_eq!(query.tag(), &Tag::Expr(Cons));
// TODO: Deps must be a single Prov or a list (later, an N-ary tuple), but we discard the type tag. This is
// arguably okay, but it means that in order to recover the preimage we will need to know the expected arity
// based on the query.
assert!(matches!(deps_tag, Tag::Expr(Prov | Cons | Nil)));
let raw = self.intern_raw_ptrs([query_raw, self.tag(val_tag), val_raw, deps_raw]);
Ptr::new(Tag::Expr(Prov), raw)
assert!(matches!(deps.tag(), Tag::Expr(Prov | Cons | Nil)));
self.intern_compact(query, val, deps, Tag::Expr(Prov))
}

#[inline]
pub fn deconstruct_provenance(&self, prov: Ptr) -> Option<[Ptr; 3]> {
pub fn deconstruct_provenance(&self, prov: &Ptr) -> Option<[Ptr; 3]> {
assert_eq!(prov.tag(), &Tag::Expr(Prov));
let idx = prov.get_index2()?;
let [query_pay, val_tag, val_pay, deps_pay] = self.fetch_raw_ptrs::<4>(idx)?;
let val_tag = self.fetch_tag(val_tag)?;
let query = Ptr::new(Tag::Expr(Cons), *query_pay);
let val = Ptr::new(val_tag, *val_pay);
let deps = Ptr::new(Tag::Expr(Cons), *deps_pay);
Some([query, val, deps])
self.fetch_compact(prov, Tag::Expr(Cons), Tag::Expr(Cons))
}

#[inline]
Expand Down

0 comments on commit 15ac41d

Please sign in to comment.