Skip to content

Commit b16f170

Browse files
committed
Merge #34: Types
f5d7201 Refactor inference (Christian Lewe) 1b510f0 Implement fmt::Display for variable types (Christian Lewe) 705d2f6 Give names to variables (Christian Lewe) 576a62c Refactor types (Christian Lewe) 5807df7 Move inference to separate module (Christian Lewe) 6bebb38 Move TypeName conversion to jet module (Christian Lewe) Pull request description: This PR refactors the type system: Types are kept separate from type inference, identifiers were changed, and documentation was added. The big addition is that variables have `String`s as identifiers and variable types implement `Display` using that. As these types are variable, we cannot use the optimisation of storing formatted strings in the struct. Instead, we create a large string and replace occurrences of powers of two using relatively few allocations. This formatting can be used in a later PR to create helpful type errors. ACKs for top commit: apoelstra: ACK f5d7201 Tree-SHA512: e7d2221ab46ab414302962c4c2ed8a335e4724ef2951e95ac4beb50d07aa489aea15cb5e8a46a8685c0ec4104a226cd604a8b7abd1e21c72a4ec64a223a294de
2 parents 3312b08 + f5d7201 commit b16f170

File tree

13 files changed

+633
-535
lines changed

13 files changed

+633
-535
lines changed

src/analysis.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ pub(crate) fn compute_extra_cells_bound<App: Application>(
2828
program[node.index - i].extra_cells_bound
2929
}
3030
Term::Comp(i, j) => {
31-
program[node.index - i].target_ty().bit_width()
31+
program[node.index - i].target_ty().bit_width
3232
+ cmp::max(
3333
program[node.index - i].extra_cells_bound,
3434
program[node.index - j].extra_cells_bound,
@@ -41,8 +41,8 @@ pub(crate) fn compute_extra_cells_bound<App: Application>(
4141
)
4242
}
4343
Term::Disconnect(i, j) => {
44-
program[node.index - i].source_ty().bit_width()
45-
+ program[node.index - i].target_ty().bit_width()
44+
program[node.index - i].source_ty().bit_width
45+
+ program[node.index - i].target_ty().bit_width
4646
+ cmp::max(
4747
program[node.index - i].extra_cells_bound,
4848
program[node.index - j].extra_cells_bound,

src/bit_machine/exec.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use std::cmp;
2222
use std::error;
2323
use std::fmt;
2424

25-
use crate::core::types::FinalTypeInner;
25+
use crate::core::types::TypeInner;
2626
use crate::core::{LinearProgram, Program, Term, Value};
2727
use crate::decode;
2828
use crate::jet::{AppError, Application};
@@ -47,7 +47,7 @@ impl BitMachine {
4747
/// the given program
4848
pub fn for_program<App: Application>(program: &Program<App>) -> BitMachine {
4949
let prog = program.root();
50-
let io_width = prog.source_ty().bit_width() + prog.target_ty().bit_width();
50+
let io_width = prog.source_ty().bit_width + prog.target_ty().bit_width;
5151
BitMachine {
5252
data: vec![0; (io_width + prog.extra_cells_bound + 7) / 8],
5353
next_frame_start: 0,
@@ -286,14 +286,14 @@ impl BitMachine {
286286
let mut call_stack = vec![];
287287
let mut iters = 0u64;
288288

289-
let input_width = ip.source_ty.bit_width();
289+
let input_width = ip.source_ty.bit_width;
290290
if input_width > 0 && self.read.is_empty() {
291291
panic!(
292292
"Pleas call `Program::input` to add an input value for this program {}",
293293
ip
294294
);
295295
}
296-
let output_width = ip.target_ty.bit_width();
296+
let output_width = ip.target_ty.bit_width;
297297
if output_width > 0 {
298298
self.new_frame(output_width);
299299
}
@@ -306,22 +306,22 @@ impl BitMachine {
306306

307307
match ip.term {
308308
Term::Unit => {}
309-
Term::Iden => self.copy(ip.source_ty.bit_width()),
309+
Term::Iden => self.copy(ip.source_ty.bit_width),
310310
Term::InjL(t) => {
311311
self.write_bit(false);
312-
if let FinalTypeInner::Sum(ref a, _) = ip.target_ty.ty {
313-
let aw = a.bit_width();
314-
self.skip(ip.target_ty.bit_width() - aw - 1);
312+
if let TypeInner::Sum(ref a, _) = ip.target_ty.ty {
313+
let aw = a.bit_width;
314+
self.skip(ip.target_ty.bit_width - aw - 1);
315315
call_stack.push(CallStack::Goto(ip.index - t));
316316
} else {
317317
panic!("type error")
318318
}
319319
}
320320
Term::InjR(t) => {
321321
self.write_bit(true);
322-
if let FinalTypeInner::Sum(_, ref b) = ip.target_ty.ty {
323-
let bw = b.bit_width();
324-
self.skip(ip.target_ty.bit_width() - bw - 1);
322+
if let TypeInner::Sum(_, ref b) = ip.target_ty.ty {
323+
let bw = b.bit_width;
324+
self.skip(ip.target_ty.bit_width - bw - 1);
325325
call_stack.push(CallStack::Goto(ip.index - t));
326326
} else {
327327
panic!("type error")
@@ -332,7 +332,7 @@ impl BitMachine {
332332
call_stack.push(CallStack::Goto(ip.index - s));
333333
}
334334
Term::Comp(s, t) => {
335-
let size = program.nodes[ip.index - s].target_ty().bit_width();
335+
let size = program.nodes[ip.index - s].target_ty().bit_width;
336336
self.new_frame(size);
337337

338338
call_stack.push(CallStack::DropFrame);
@@ -342,23 +342,22 @@ impl BitMachine {
342342
}
343343
Term::Disconnect(s, t) => {
344344
// Write `t`'s CMR followed by `s` input to a new read frame
345-
let size = program.nodes[ip.index - s].source_ty().bit_width();
345+
let size = program.nodes[ip.index - s].source_ty().bit_width;
346346
assert!(size >= 256);
347347
self.new_frame(size);
348348
self.write_bytes(program.nodes[ip.index - t].cmr().as_ref());
349349
self.copy(size - 256);
350350
self.move_frame();
351351

352-
let s_target_size = program.nodes[ip.index - s].target_ty().bit_width();
352+
let s_target_size = program.nodes[ip.index - s].target_ty().bit_width;
353353
self.new_frame(s_target_size);
354354
// Then recurse. Remembering that call stack pushes are executed
355355
// in reverse order:
356356

357357
// 3. Delete the two frames we created, which have both moved to the read stack
358358
call_stack.push(CallStack::DropFrame);
359359
call_stack.push(CallStack::DropFrame);
360-
let b_size =
361-
s_target_size - program.nodes[ip.index - t].source_ty().bit_width();
360+
let b_size = s_target_size - program.nodes[ip.index - t].source_ty().bit_width;
362361
// Back not required since we are dropping the frame anyways
363362
// call_stack.push(CallStack::Back(b_size));
364363
// 2. Copy the first half of `s`s output directly then execute `t` on the second half
@@ -370,8 +369,8 @@ impl BitMachine {
370369
}
371370
Term::Take(t) => call_stack.push(CallStack::Goto(ip.index - t)),
372371
Term::Drop(t) => {
373-
if let FinalTypeInner::Product(ref a, _) = ip.source_ty.ty {
374-
let aw = a.bit_width();
372+
if let TypeInner::Product(ref a, _) = ip.source_ty.ty {
373+
let aw = a.bit_width;
375374
self.fwd(aw);
376375
call_stack.push(CallStack::Back(aw));
377376
call_stack.push(CallStack::Goto(ip.index - t));
@@ -383,10 +382,10 @@ impl BitMachine {
383382
let sw = self.read[self.read.len() - 1].peek_bit(&self.data);
384383
let aw;
385384
let bw;
386-
if let FinalTypeInner::Product(ref a, _) = ip.source_ty.ty {
387-
if let FinalTypeInner::Sum(ref a, ref b) = a.ty {
388-
aw = a.bit_width();
389-
bw = b.bit_width();
385+
if let TypeInner::Product(ref a, _) = ip.source_ty.ty {
386+
if let TypeInner::Sum(ref a, ref b) = a.ty {
387+
aw = a.bit_width;
388+
bw = b.bit_width;
390389
} else {
391390
panic!("type error");
392391
}

src/core/program.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use std::collections::{HashMap, HashSet};
2323
use std::{fmt, io};
2424

2525
use crate::bititer::BitIter;
26-
use crate::core::types::FinalType;
26+
use crate::core::types::Type;
2727
use crate::core::{iter, LinearProgram, Term, TypedNode, TypedProgram, Value};
2828
use crate::encode::BitWriter;
2929
use crate::jet::Application;
@@ -58,12 +58,12 @@ impl<App: Application> ProgramNode<App> {
5858
}
5959

6060
/// Return the source type of the node.
61-
pub fn source_ty(&self) -> &FinalType {
61+
pub fn source_ty(&self) -> &Type {
6262
&self.typed.source_ty
6363
}
6464

6565
/// Return the target type of the node.
66-
pub fn target_ty(&self) -> &FinalType {
66+
pub fn target_ty(&self) -> &Type {
6767
&self.typed.target_ty
6868
}
6969

src/core/term.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@
2626
use crate::bititer::BitIter;
2727
use crate::core::iter::DagIterable;
2828
use crate::core::typed::TypedProgram;
29-
use crate::core::{iter, LinearProgram};
30-
use crate::core::{types, Value};
29+
use crate::core::{iter, LinearProgram, Value};
3130
use crate::encode::BitWriter;
3231
use crate::jet::{Application, JetNode};
3332
use crate::merkle::cmr::Cmr;
34-
use crate::{decode, encode, Error};
33+
use crate::{decode, encode, inference, Error};
3534
use std::collections::HashMap;
3635
use std::hash::Hash;
3736
use std::io;
@@ -246,7 +245,7 @@ impl<Witness, App: Application> UntypedProgram<Witness, App> {
246245

247246
/// Type-check the program and add metadata for the time of commitment.
248247
pub fn type_check(self) -> Result<TypedProgram<Witness, App>, Error> {
249-
types::type_check(self)
248+
inference::type_check(self)
250249
}
251250
}
252251

src/core/typed.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
//
1414

1515
use crate::bititer::BitIter;
16-
use crate::core::types::FinalType;
17-
use crate::core::{iter, types, LinearProgram, Program, ProgramNode, Term, UntypedProgram, Value};
16+
use crate::core::types::Type;
17+
use crate::core::{iter, LinearProgram, Program, ProgramNode, Term, UntypedProgram, Value};
1818
use crate::encode::BitWriter;
1919
use crate::jet::Application;
2020
use crate::merkle::cmr::Cmr;
2121
use crate::merkle::imr;
22-
use crate::{analysis, decode, encode, Error};
22+
use crate::{analysis, decode, encode, inference, Error};
2323
use std::sync::Arc;
2424
use std::{fmt, io};
2525

@@ -29,9 +29,9 @@ pub struct TypedNode<Witness, App: Application> {
2929
/// Underlying term
3030
pub term: Term<Witness, App>,
3131
/// Source type of the node
32-
pub source_ty: Arc<FinalType>,
32+
pub source_ty: Arc<Type>,
3333
/// Target type of the node
34-
pub target_ty: Arc<FinalType>,
34+
pub target_ty: Arc<Type>,
3535
/// Index of the node inside the surrounding program
3636
pub index: usize,
3737
/// Commitment Merkle root of the node
@@ -73,7 +73,7 @@ impl<App: Application> TypedProgram<(), App> {
7373
/// Decode a typed program from bits.
7474
pub fn decode<I: Iterator<Item = u8>>(iter: &mut BitIter<I>) -> Result<Self, Error> {
7575
let program = UntypedProgram::<(), App>::decode(iter)?;
76-
types::type_check(program)
76+
inference::type_check(program)
7777
}
7878

7979
/// Encode the program into bits.
@@ -127,7 +127,7 @@ impl<Witness, App: Application> TypedProgram<Witness, App> {
127127
}
128128

129129
/// Return a vector of the types of values that make up a valid witness for the program.
130-
pub fn get_witness_types(&self) -> Vec<&FinalType> {
130+
pub fn get_witness_types(&self) -> Vec<&Type> {
131131
let mut witness_types = Vec::new();
132132

133133
for node in &self.0 {

0 commit comments

Comments
 (0)