atomic factory

This commit is contained in:
AF 2023-04-21 10:04:10 +00:00
parent db879642bc
commit 379e8bc2cd
10 changed files with 373 additions and 34 deletions

1
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1 @@
{}

View File

@ -1,4 +1,4 @@
use std::{error::Error, rc::Rc};
use std::{error::Error, fmt::Display, rc::Rc};
use crate::func::*;
@ -8,52 +8,84 @@ pub trait Context {
fn hash(s: &[u8]) -> Hash;
}
type Hash = [u8; 32];
pub const HASH_SIZE: usize = 32;
pub type Hash = [u8; HASH_SIZE];
pub trait Serializer {
fn write(&mut self, buf: &[u8]);
fn tell(&self) -> usize;
}
impl<F: FnMut(&[u8])> Serializer for F {
impl Serializer for Vec<u8> {
fn write(&mut self, buf: &[u8]) {
self(buf);
self.extend(buf);
}
fn tell(&self) -> usize {
self.len()
}
}
pub trait Mentionable<Ctx: Context> {
type Fctr: Factory<Ctx, Mtbl = Self>;
pub trait Serializable {
fn serialize(&self, serializer: &mut dyn Serializer);
}
pub trait Mentionable<'a, Ctx: 'a + Context>: 'a + Serializable {
type Fctr: Factory<'a, Ctx, Mtbl = Self>;
fn serialize<F: Serializer>(&self, serializer: F);
fn factory(&self) -> Self::Fctr;
fn topology(&self) -> Hash;
fn topology(&self) -> Hash {
let mut vec = Vec::new();
for point in self.points() {
vec.extend(point.point);
}
Ctx::hash(&vec)
}
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>;
}
pub trait Deserializer {
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
fn read_n(&mut self, n: usize) -> &[u8];
fn read_all(&mut self, n: usize) -> &[u8];
}
pub trait Factory<Ctx: Context>: Clone {
type Mtbl: Mentionable<Ctx, Fctr = Self>;
type ParseError: Error;
fn deserialize<F: Deserializer>(&self, deserializer: F)
-> Result<Self::Mtbl, Self::ParseError>;
pub trait ExtDeserialiser {
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]>;
}
pub trait Origin<'a, Ctx: Context>: 'a {
type Mtbl: Mentionable<Ctx>;
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr;
impl<D: ?Sized + Deserializer> ExtDeserialiser for D {
fn read_n_const<const N: usize>(&mut self) -> Result<[u8; N], &[u8]> {
let slice = self.read_n(N);
match slice.try_into() {
Ok(array) => Ok(array),
Err(_) => Err(slice),
}
}
}
pub trait Factory<'a, Ctx: 'a + Context>: Clone + 'a {
type Mtbl: Mentionable<'a, Ctx, Fctr = Self>;
type ParseError: Error;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Self::Mtbl, Self::ParseError>;
}
pub trait Origin<'a, Ctx: 'a + Context>: 'a {
type Mtbl: Mentionable<'a, Ctx>;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr;
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>>;
}
struct LocalOrigin<A>(Rc<A>);
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for LocalOrigin<A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<Ctx>>::Fctr {
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.0.factory()
}
@ -68,16 +100,24 @@ impl<A> From<A> for LocalOrigin<A> {
}
}
#[derive(Clone)]
pub struct Point<'a, Ctx: Context, A: Mentionable<Ctx>> {
pub struct Point<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
pub point: Hash,
pub origin: Rc<dyn Origin<'a, Ctx, Mtbl = A>>,
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Point<'a, Ctx, A> {
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Clone for Point<'a, Ctx, A> {
fn clone(&self) -> Self {
Self {
point: self.point,
origin: self.origin.clone(),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
fn prepare_bytes_for_hashing(mentioned: &A) -> Vec<u8> {
let mut vec = mentioned.topology().to_vec();
mentioned.serialize(|x: &[u8]| vec.extend(x.iter()));
mentioned.serialize(&mut vec);
vec
}
@ -94,7 +134,7 @@ impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> Point<'a, Ctx, A> {
}
}
impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> for Point<'a, Ctx, A> {
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> From<A> for Point<'a, Ctx, A> {
fn from(value: A) -> Self {
Self::from_values(
Ctx::hash(Self::prepare_bytes_for_hashing(&value).as_slice()),
@ -102,3 +142,106 @@ impl<'a, Ctx: 'a + Context, A: 'a + Mentionable<Ctx>> From<A> for Point<'a, Ctx,
)
}
}
type TypelessSerialize<'a> = dyn 'a + Fn(&mut dyn Serializer);
pub struct TypelessMentionable<'a, Ctx: 'a + Context> {
t_serialize: Box<TypelessSerialize<'a>>,
t_factory: TypelessFactory<'a, Ctx>,
t_topology: Hash,
t_points: Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>>,
}
type TypelessParsed<'a, Ctx> = Result<TypelessMentionable<'a, Ctx>, Box<dyn 'a + Error>>;
type TypelessDeserialize<'a, Ctx> = dyn 'a + Fn(&mut dyn Deserializer) -> TypelessParsed<'a, Ctx>;
pub struct TypelessFactory<'a, Ctx: 'a + Context> {
t_deserialize: Rc<TypelessDeserialize<'a, Ctx>>,
}
impl<'a, Ctx: 'a + Context> Serializable for TypelessMentionable<'a, Ctx> {
fn serialize(&self, serializer: &mut dyn Serializer) {
(self.t_serialize)(serializer);
}
}
impl<'a, Ctx: 'a + Context> Mentionable<'a, Ctx> for TypelessMentionable<'a, Ctx> {
type Fctr = TypelessFactory<'a, Ctx>;
fn factory(&self) -> Self::Fctr {
self.t_factory.clone()
}
fn topology(&self) -> Hash {
self.t_topology
}
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
self.t_points.clone()
}
}
impl<'a, Ctx: 'a + Context> Clone for TypelessFactory<'a, Ctx> {
fn clone(&self) -> Self {
Self {
t_deserialize: self.t_deserialize.clone(),
}
}
}
#[derive(Debug)]
pub struct TypelessError<'a>(Box<dyn 'a + Error>);
impl<'a> Display for TypelessError<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<'a> Error for TypelessError<'a> {}
impl<'a, Ctx: 'a + Context> Factory<'a, Ctx> for TypelessFactory<'a, Ctx> {
type Mtbl = TypelessMentionable<'a, Ctx>;
type ParseError = TypelessError<'a>;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Self::Mtbl, Self::ParseError> {
match (self.t_deserialize)(deserializer) {
Ok(mentionable) => Ok(mentionable),
Err(error) => Err(TypelessError(error)),
}
}
}
impl<'a, Ctx: 'a + Context> TypelessMentionable<'a, Ctx> {
pub fn from_mentionable<A: Mentionable<'a, Ctx>>(mentionable: Rc<A>) -> Self {
let factory = TypelessFactory::from_factory(mentionable.factory());
let topology = mentionable.topology();
let points = mentionable.points();
TypelessMentionable {
t_serialize: Box::new(move |serializer| mentionable.serialize(serializer)),
t_factory: factory,
t_topology: topology,
t_points: points,
}
}
}
impl<'a, Ctx: 'a + Context> TypelessFactory<'a, Ctx> {
pub fn from_factory<F: Factory<'a, Ctx>>(factory: F) -> Self {
TypelessFactory {
t_deserialize: Rc::new(
move |deserializer| match factory.deserialize(deserializer) {
Ok(mentionable) => {
Ok(TypelessMentionable::from_mentionable(Rc::new(mentionable)))
}
Err(error) => Err(Box::new(error)),
},
),
}
}
}

View File

@ -7,7 +7,7 @@ pub mod test_suite;
pub mod tests;
pub trait WeakFunctor {
type F<'a, A: 'a>: 'a;
type F<'a, A: 'a>: 'a where Self: 'a;
}
/// Rust-specific implementation of [Functor], respecting `move` semantics.

View File

@ -3,7 +3,7 @@ use crate::func::*;
struct CompositionClass<U, V>(U, V);
impl<U: WeakFunctor, V: WeakFunctor> WeakFunctor for CompositionClass<U, V> {
type F<'a, A: 'a> = U::F<'a, V::F<'a, A>>;
type F<'a, A: 'a> = U::F<'a, V::F<'a, A>> where U: 'a, V: 'a;
}
impl<U: Functor, V: Functor> Functor for CompositionClass<U, V> {

View File

@ -3,12 +3,14 @@ use std::{cell::Cell, rc::Rc};
use crate::func::*;
enum EvalTree<'a> {
Atom(Box<dyn 'a + FnOnce() -> Option<EvalTree<'a>>>),
Atom(Box<dyn 'a + FnOnce() -> Oet<'a>>),
Composite(Box<EvalTree<'a>>, Box<EvalTree<'a>>),
}
type Oet<'a> = Option<EvalTree<'a>>;
impl<'a> EvalTree<'a> {
fn next(self) -> Option<EvalTree<'a>> {
fn next(self) -> Oet<'a> {
match self {
EvalTree::Atom(f) => f(),
EvalTree::Composite(left, right) => match *left {
@ -25,11 +27,13 @@ impl<'a> EvalTree<'a> {
}
}
type StackessDyn<'a, A> = dyn 'a + FnOnce(Box<dyn 'a + FnOnce(A)>) -> Oet<'a>;
pub struct Stackless<'a, A: 'a>(
Box<dyn 'a + FnOnce(Box<dyn 'a + FnOnce(A)>) -> Option<EvalTree<'a>>>,
Box<StackessDyn<'a, A>>,
);
fn set_cell<A>(cell: Rc<Cell<Option<A>>>, a: A) -> () {
fn set_cell<A>(cell: Rc<Cell<Option<A>>>, a: A) {
if cell.replace(Some(a)).is_some() {
panic!("MITM overwritten")
}
@ -43,7 +47,7 @@ fn get_cell<A>(cell: Rc<Cell<Option<A>>>) -> A {
}
impl<'a, A: 'a> Stackless<'a, A> {
fn call(self, f: impl 'a + FnOnce(A)) -> Option<EvalTree<'a>> {
fn call(self, f: impl 'a + FnOnce(A)) -> Oet<'a> {
self.0(Box::new(f))
}
@ -273,6 +277,7 @@ mod stackless_test {
#[test]
fn test_dumb() {
assert_eq!(dumb(1000).evaluate(), 1000);
let n = 1000;
assert_eq!(dumb(n).evaluate(), n);
}
}

View File

@ -3,7 +3,7 @@ use super::{tests::*, *};
pub trait FunctorTestSuite: WeakFunctor + Eqr {
fn sample<'a, A: 'a, F: FnMut(&'a dyn Fn(A) -> Self::F<'a, A>)>(f: F)
where
Self::F<'a, A>: 'a;
Self::F<'a, A>: 'a, Self: 'a;
}
pub fn functor_follows_laws<T: Functor + FunctorTestSuite>() -> R {

View File

@ -1,4 +1,5 @@
pub mod core;
pub mod func;
pub mod std;
#[cfg(test)]
mod xrcs;

138
src/std.rs Normal file
View File

@ -0,0 +1,138 @@
pub mod atomic;
pub mod inlining;
use std::{error::Error, fmt::Display, rc::Rc};
use crate::core::*;
use crate::func::*;
struct WrappedOrigin<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> {
w_factory: A::Fctr,
w_resolve: Box<dyn 'a + Fn() -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<A>>>,
}
trait MappableOrigin<'a, Ctx: 'a + Context>: Origin<'a, Ctx> {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_mentionable: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B>;
}
fn map_resolve<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>, B: Mentionable<'a, Ctx>>(
resolve: impl 'a + Fn() -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<A>>,
map_mentionable: impl 'a + Fn(Rc<A>) -> B,
) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<B>> {
Ctx::T::fmap(
move |resolved| Rc::new(map_mentionable(resolved)),
resolve(),
)
}
impl<'a, Ctx: 'a + Context, O: ?Sized + Origin<'a, Ctx>> MappableOrigin<'a, Ctx> for O {
fn map<B: Mentionable<'a, Ctx>>(
self: Rc<Self>,
map_mentionable: impl 'a + Clone + Fn(Rc<Self::Mtbl>) -> B,
map_factory: impl 'a + FnOnce(<Self::Mtbl as Mentionable<'a, Ctx>>::Fctr) -> B::Fctr,
) -> WrappedOrigin<'a, Ctx, B> {
let origin = self.clone();
WrappedOrigin {
w_factory: map_factory(self.factory()),
w_resolve: Box::new(move || {
let origin = origin.clone();
let map_mentionable = map_mentionable.clone();
map_resolve(
move || origin.resolve(),
map_mentionable,
)
}),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Origin<'a, Ctx> for WrappedOrigin<'a, Ctx, A> {
type Mtbl = A;
fn factory(&self) -> <Self::Mtbl as Mentionable<'a, Ctx>>::Fctr {
self.w_factory.clone()
}
fn resolve(&self) -> <<Ctx as Context>::T as WeakFunctor>::F<'a, Rc<Self::Mtbl>> {
(self.w_resolve)()
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Point<'a, Ctx, A> {
pub fn typeless(&self) -> Point<'a, Ctx, TypelessMentionable<'a, Ctx>> {
Point {
point: self.point,
origin: Rc::new(self.origin.clone().map(
TypelessMentionable::from_mentionable,
TypelessFactory::from_factory,
)),
}
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Serializable for Point<'a, Ctx, A> {
fn serialize(&self, serializer: &mut dyn Serializer) {
serializer.write(&self.point)
}
}
impl<'a, Ctx: 'a + Context, A: Mentionable<'a, Ctx>> Mentionable<'a, Ctx> for Point<'a, Ctx, A> {
type Fctr = PointFactory<A::Fctr>;
fn factory(&self) -> Self::Fctr {
PointFactory {
factory: self.origin.factory(),
}
}
fn topology(&self) -> Hash {
Ctx::hash(&self.point)
}
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
vec![self.typeless()]
}
}
#[derive(Clone)]
pub struct PointFactory<F> {
factory: F,
}
#[derive(Debug)]
pub enum PointParseError {
WrongLength(usize),
}
impl Display for PointParseError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PointParseError::WrongLength(length) => f.write_fmt(format_args!(
"expected {} bytes, received {}",
HASH_SIZE, length
)),
}
}
}
impl Error for PointParseError {}
impl<'a, Ctx: 'a + Context, F: Factory<'a, Ctx>> Factory<'a, Ctx> for PointFactory<F> {
type Mtbl = Point<'a, Ctx, F::Mtbl>;
type ParseError = PointParseError;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Self::Mtbl, Self::ParseError> {
match deserializer.read_n_const::<HASH_SIZE>() {
Ok(point) => Ok(Point {point, origin: todo!()}),
Err(slice) => Err(PointParseError::WrongLength(slice.len())),
}
}
}

51
src/std/atomic.rs Normal file
View File

@ -0,0 +1,51 @@
use std::{error::Error, marker::PhantomData};
use crate::core::*;
pub trait Atomic: 'static + Sized + Clone + Serializable {
type ParseError: Error;
fn deserialize(deserializer: &mut dyn Deserializer) -> Result<Self, Self::ParseError>;
}
pub struct AtomicFactory<A: Atomic>(PhantomData<A>);
impl<A: Atomic> AtomicFactory<A> {
fn new() -> Self {
AtomicFactory(PhantomData)
}
}
impl<A: Atomic> Clone for AtomicFactory<A> {
fn clone(&self) -> Self {
Self::new()
}
}
impl<'a, Ctx: 'a + Context, A: Atomic> Mentionable<'a, Ctx> for A {
type Fctr = AtomicFactory<A>;
fn factory(&self) -> Self::Fctr {
AtomicFactory::new()
}
fn topology(&self) -> Hash {
Ctx::hash(b"")
}
fn points(&self) -> Vec<Point<'a, Ctx, TypelessMentionable<'a, Ctx>>> {
vec![]
}
}
impl<'a, Ctx: 'a + Context, A: Atomic> Factory<'a, Ctx> for AtomicFactory<A> {
type Mtbl = A;
type ParseError = A::ParseError;
fn deserialize(
&self,
deserializer: &mut dyn Deserializer,
) -> Result<Self::Mtbl, Self::ParseError> {
A::deserialize(deserializer)
}
}

0
src/std/inlining.rs Normal file
View File