Fixing noun list and batteries list construction

This commit is contained in:
Chris Allen 2024-10-16 11:35:40 -05:00 committed by Chris A.
parent 91c74226fd
commit b585da2419

View File

@ -1035,7 +1035,12 @@ impl<T: Nounable + Copy + mem::Preserve> Nounable for Hamt<T> {
// FIXME: This should be reversed for linked-list construction
fn into_noun<A: NounAllocator>(self, stack: &mut A) -> Noun {
let mut list = D(0);
for slice in self.iter() {
let mut reverse = Vec::new();
for item in self.iter() {
reverse.push(item);
}
reverse.reverse();
for slice in reverse {
for (key, value) in slice {
let key_noun = key.into_noun(stack);
let value_noun = value.into_noun(stack);
@ -1057,7 +1062,7 @@ impl<T: Nounable + Copy + mem::Preserve> Nounable for Hamt<T> {
let value = T::from_noun(stack, &cell.tail())?;
items.push((key, value));
}
items.reverse();
// items.reverse();
Ok(items)
}
}
@ -1083,9 +1088,9 @@ impl Nounable for Cold {
let mut battery_to_paths_noun = D(0);
let mut path_to_batteries_noun = D(0);
unsafe {
println!("root_to_paths.count(): {}", (*cold_mem).root_to_paths.iter().count());
println!("battery_to_paths.count(): {}", (*cold_mem).battery_to_paths.iter().count());
println!("path_to_batteries.count(): {}", (*cold_mem).path_to_batteries.iter().count());
println!("root_to_paths.iter().count(): {}", (*cold_mem).root_to_paths.iter().count());
println!("battery_to_paths.iter().count(): {}", (*cold_mem).battery_to_paths.iter().count());
println!("path_to_batteries.iter().count(): {}", (*cold_mem).path_to_batteries.iter().count());
}
unsafe {
for slice in (*cold_mem).root_to_paths.iter() {
@ -1117,7 +1122,7 @@ impl Nounable for Cold {
}
}
// multi-step the cons'ing for correct associativity
let items = T(stack, &[root_to_paths_noun, battery_to_paths_noun]);
// let items = T(stack, &[root_to_paths_noun, battery_to_paths_noun]);
let cold_noun = T(stack, &[root_to_paths_noun, battery_to_paths_noun, path_to_batteries_noun]);
cold_noun
}
@ -1179,12 +1184,15 @@ mod test {
fn make_cold_state(stack: &mut NockStack) -> Cold {
let cold = Cold::new(stack);
unsafe {
let root_noun_list = make_noun_list(stack);
(*cold.0).root_to_paths = (*cold.0).root_to_paths.insert(stack, &mut D(1), root_noun_list);
let battery_to_paths_list = make_noun_list(stack);
(*cold.0).battery_to_paths = (*cold.0).battery_to_paths.insert(stack, &mut D(2), battery_to_paths_list);
let batteries_list = make_batteries_list(stack);
(*cold.0).path_to_batteries = (*cold.0).path_to_batteries.insert(stack, &mut D(3), batteries_list);
let root_noun_list = make_noun_list(stack, &[1, 2]);
(*cold.0).root_to_paths = (*cold.0).root_to_paths.insert(stack, &mut D(100), root_noun_list);
let root_noun_list = make_noun_list(stack, &[3, 4]);
(*cold.0).root_to_paths = (*cold.0).root_to_paths.insert(stack, &mut D(101), root_noun_list);
let battery_to_paths_list = make_noun_list(stack, &[5, 6]);
(*cold.0).battery_to_paths = (*cold.0).battery_to_paths.insert(stack, &mut D(200), battery_to_paths_list);
let batteries_list = make_batteries_list(stack, &[7, 8]);
(*cold.0).path_to_batteries = (*cold.0).path_to_batteries.insert(stack, &mut D(300), batteries_list);
}
cold
}
@ -1197,7 +1205,7 @@ mod test {
let new_cold = Cold::from_noun(&mut stack, &cold_noun).expect("Failed to convert noun to cold");
// Use zipped iteration to compare the two cold states
let old_root_to_paths = unsafe { &(*cold.0).root_to_paths };
let new_root_to_paths = new_cold.0;
let new_root_to_paths = new_cold.0.clone();
for (a, b) in old_root_to_paths.iter().flatten().zip(new_root_to_paths.iter()) {
let key_a = &mut a.0.clone() as *mut Noun;
let key_b = &mut b.0.clone() as *mut Noun;
@ -1206,7 +1214,33 @@ mod test {
let mut value_b_noun = b.1.into_noun(&mut stack);
let value_a = &mut value_a_noun as *mut Noun;
let value_b = &mut value_b_noun as *mut Noun;
assert!(unsafe { unifying_equality(&mut stack, value_a, value_b) }, "Values don't match: {:?} {:?}", value_a_noun, value_b_noun);
assert!(unsafe { unifying_equality(&mut stack, value_a, value_b) }, "Values don't match: old: {:?} new: {:?}", value_a_noun, value_b_noun);
}
// battery_to_paths
let old_battery_to_paths = unsafe { &(*cold.0).battery_to_paths };
let new_battery_to_paths = new_cold.1.clone();
for (a, b) in old_battery_to_paths.iter().flatten().zip(new_battery_to_paths.iter()) {
let key_a = &mut a.0.clone() as *mut Noun;
let key_b = &mut b.0.clone() as *mut Noun;
assert!(unsafe { unifying_equality(&mut stack, key_a, key_b) }, "Keys don't match: {:?} {:?}", a.0, b.0);
let mut value_a_noun = a.1.into_noun(&mut stack);
let mut value_b_noun = b.1.into_noun(&mut stack);
let value_a = &mut value_a_noun as *mut Noun;
let value_b = &mut value_b_noun as *mut Noun;
assert!(unsafe { unifying_equality(&mut stack, value_a, value_b) }, "Values don't match: old: {:?} new: {:?}", value_a_noun, value_b_noun);
}
// path_to_batteries
let old_path_to_batteries = unsafe { &(*cold.0).path_to_batteries };
let new_path_to_batteries = new_cold.2.clone();
for (a, b) in old_path_to_batteries.iter().flatten().zip(new_path_to_batteries.iter()) {
let key_a = &mut a.0.clone() as *mut Noun;
let key_b = &mut b.0.clone() as *mut Noun;
assert!(unsafe { unifying_equality(&mut stack, key_a, key_b) }, "Keys don't match: {:?} {:?}", a.0, b.0);
let mut value_a_noun = a.1.into_noun(&mut stack);
let mut value_b_noun = b.1.into_noun(&mut stack);
let value_a = &mut value_a_noun as *mut Noun;
let value_b = &mut value_b_noun as *mut Noun;
assert!(unsafe { unifying_equality(&mut stack, value_a, value_b) }, "Values don't match: old: {:?} new: {:?}", value_a_noun, value_b_noun);
}
}
@ -1228,32 +1262,34 @@ mod test {
}
}
fn make_batteries_list(stack: &mut NockStack) -> BatteriesList {
let batteries_list_mem: *mut BatteriesListMem = unsafe { stack.alloc_struct(1) };
let batteries = make_batteries(stack);
unsafe {
batteries_list_mem.write(BatteriesListMem {
batteries,
next: BATTERIES_LIST_NIL,
});
fn make_batteries_list(stack: &mut NockStack, v: &[u64]) -> BatteriesList {
let mut batteries_list = BATTERIES_LIST_NIL;
for &item in v.iter().rev() {
let batteries_mem: *mut BatteriesMem = unsafe { stack.alloc_struct(1) };
unsafe {
batteries_mem.write(BatteriesMem {
battery: D(item),
parent_axis: D(0).as_atom().unwrap(),
parent_batteries: NO_BATTERIES,
});
}
let batteries = Batteries(batteries_mem);
let batteries_list_mem: *mut BatteriesListMem = unsafe { stack.alloc_struct(1) };
unsafe {
batteries_list_mem.write(BatteriesListMem {
batteries,
next: batteries_list,
});
}
batteries_list = BatteriesList(batteries_list_mem);
}
let batteries_list = BatteriesList(batteries_list_mem);
let batteries_list_mem2: *mut BatteriesListMem = unsafe { stack.alloc_struct(1) };
let batteries2 = make_batteries(stack);
unsafe {
batteries_list_mem2.write(BatteriesListMem {
batteries: batteries2,
next: batteries_list,
});
}
let batteries_list2 = BatteriesList(batteries_list_mem2);
batteries_list2
batteries_list
}
#[test]
fn batteries_list_bidirectional_conversion() {
let mut stack = make_test_stack();
let batteries_list2 = make_batteries_list(&mut stack);
let batteries_list2 = make_batteries_list(&mut stack, &[1, 2]);
let batteries_list_noun = batteries_list2.into_noun(&mut stack);
let new_batteries_list2 = BatteriesList::from_noun(&mut stack, &batteries_list_noun).expect("Failed to convert noun to batteries list");
for (a, b) in batteries_list2.zip(new_batteries_list2) {
@ -1324,31 +1360,26 @@ mod test {
assert!(unsafe { unifying_equality(&mut stack, c_ptr, &mut D(3) as *mut Noun) }, "Third item doesn't match");
}
fn make_noun_list(stack: &mut NockStack) -> NounList {
let noun_list_mem: *mut NounListMem = unsafe { stack.alloc_struct(1) };
unsafe {
noun_list_mem.write(NounListMem {
element: D(1),
next: NOUN_LIST_NIL,
});
fn make_noun_list(stack: &mut NockStack, v: &[u64]) -> NounList {
let mut noun_list = NOUN_LIST_NIL;
for &item in v.iter().rev() {
let noun_list_mem: *mut NounListMem = unsafe { stack.alloc_struct(1) };
unsafe {
noun_list_mem.write(NounListMem {
element: D(item),
next: NOUN_LIST_NIL,
});
}
noun_list = NounList(noun_list_mem);
}
let noun_list = NounList(noun_list_mem);
let noun_list_mem2: *mut NounListMem = unsafe { stack.alloc_struct(1) };
unsafe {
noun_list_mem2.write(NounListMem {
element: D(2),
next: noun_list,
});
}
let noun_list2 = NounList(noun_list_mem2);
noun_list2
noun_list
}
#[test]
fn noun_list_bidirectional_conversion() {
let mut stack = make_test_stack();
let items = vec![D(1), D(2)];
let noun_list = make_noun_list(&mut stack);
let noun_list = make_noun_list(&mut stack, &[1, 2]);
let noun = noun_list.into_noun(&mut stack);
let new_noun_list: NounList = <NounList as Nounable>::from_noun::<NockStack>(&mut stack, &noun).unwrap();
for (a, b) in new_noun_list.zip(items.iter()) {