Skip to content
Snippets Groups Projects
Commit 8f4fbfa6 authored by Cookiebowser's avatar Cookiebowser
Browse files

continued lazy_btypes rust

parent 929914e6
No related branches found
No related tags found
1 merge request!28Rust support
[package]
name = "bmachine"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.3"
im = "15.0.0"
threadpool = "1.8.1"
derivative = "2.2.0"
dashmap = "5.1.0"
btypes = { path = "../btypes" }
[profile.release]
opt-level = 3
[profile.dev]
opt-level = 0
...@@ -6,6 +6,8 @@ use crate::bstring::BString; ...@@ -6,6 +6,8 @@ use crate::bstring::BString;
use crate::bobject::BObject; use crate::bobject::BObject;
use crate::btuple::BTuple; use crate::btuple::BTuple;
use crate::orderedhashset::OrderedHashSet as OrdSet; use crate::orderedhashset::OrderedHashSet as OrdSet;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
use crate::lazy_ops::set_ops::union::Union;
use std::any::TypeId; use std::any::TypeId;
use std::borrow::Borrow; use std::borrow::Borrow;
...@@ -16,7 +18,6 @@ use std::collections::LinkedList; ...@@ -16,7 +18,6 @@ use std::collections::LinkedList;
use std::fmt; use std::fmt;
use std::fmt::Debug; use std::fmt::Debug;
use rand::Rng; use rand::Rng;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
pub trait TBSet: BObject { pub trait TBSet: BObject {
type Item: BObject; type Item: BObject;
...@@ -41,9 +42,7 @@ impl<T: BObject> BSet<T> { ...@@ -41,9 +42,7 @@ impl<T: BObject> BSet<T> {
const OP_NAME: &'static str = "set"; const OP_NAME: &'static str = "set";
} }
impl<T: BObject> SetOp for BSet<T> { impl<T: 'static + BObject> SetOp for BSet<T> {
type Item = T;
fn compute(&self, _: &BSet<Self::Item>) -> BSet<Self::Item> { fn compute(&self, _: &BSet<Self::Item>) -> BSet<Self::Item> {
match self.transformation.borrow() { match self.transformation.borrow() {
Some(trans) => trans.compute(&self) , //todo save computation? Some(trans) => trans.compute(&self) , //todo save computation?
...@@ -52,45 +51,80 @@ impl<T: BObject> SetOp for BSet<T> { ...@@ -52,45 +51,80 @@ impl<T: BObject> SetOp for BSet<T> {
} }
fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> { fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> {
todo!() Box::new(self.clone())
} }
fn get_op_name(&self) -> &str { fn get_op_name(&self) -> &str {
return BSet::<T>::OP_NAME; return BSet::<T>::OP_NAME;
} }
fn get_rhs(&self) -> Option<&Box<dyn SetOp<Item=Self::Item>>> { fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> {
return self.transformation.as_ref(); return self.transformation.clone();
}
fn to_string(&self, _lhs: Option<&str>) -> String {
let mut result = "{".to_owned();
let mut first = true;
for e in self.set.iter() {
if !first { result = result + ", " }
else { first = false; }
result = result + &format!("{}", e).to_string();
}
result = result + "}";
match &self.transformation {
Some(op) => return op.to_string(Option::Some(result.as_str())),
None => return result,
}
} }
} }
impl<T: BObject> SetOpTraits for BSet<T> { impl<T: 'static + BObject> SetOpTraits for BSet<T> {
type Item = T;
fn iter_lazy(&self, _lhs: &BSet<Self::Item>) -> Iter<'_, T> {
match &self.transformation {
Some(op) => op.iter_lazy(self),
None => self.iter_directly(),
}
}
fn contains_lazy(&self, _lhs: &BSet<Self::Item>, o: &Self::Item) -> bool {
match &self.transformation {
Some(op) => op.contains_lazy(self, o),
None => self.contains_directly(o),
}
}
fn is_empty_lazy(&self, _lhs: &BSet<Self::Item>) -> bool {
match &self.transformation {
Some(op) => op.is_empty_lazy(self),
None => self.is_empty_directly(),
}
}
fn size_lazy(&self, _lhs: &BSet<Self::Item>) -> usize {
match &self.transformation {
Some(op) => op.size_lazy(self),
None => self.size_directly(),
}
}
} }
impl<I: BObject> Hash for BSet<I> { impl<I: BObject> Hash for BSet<I> {
fn hash<H: Hasher>(self: &BSet<I>, state: &mut H) { self.set.hash(state); } fn hash<H: Hasher>(self: &BSet<I>, state: &mut H) { self.set.hash(state); }
} }
impl<T: BObject> BObject for BSet<T> {} impl<T: 'static + BObject> BObject for BSet<T> {}
impl<T: BObject> TBSet for BSet<T> { impl<T: 'static + BObject> TBSet for BSet<T> {
type Item = T; type Item = T;
fn as_ord_set(&self) -> OrdSet<Self::Item> { self.set.clone() } fn as_ord_set(&self) -> OrdSet<Self::Item> { self.set.clone() }
fn as_bset(&self) -> &BSet<Self::Item> { self } fn as_bset(&self) -> &BSet<Self::Item> { self }
} }
impl<T: BObject> fmt::Display for BSet<T> { impl<T: 'static + BObject> fmt::Display for BSet<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut result = "{".to_owned(); return write!(f, "{}", <BSet<T> as SetOp>::to_string(self, Option::None));
let mut first = true;
for e in self.set.iter() {
if !first { result = result + ", " }
else { first = false; }
result = result + &format!("{}", e).to_string();
}
result = result + "}";
return write!(f, "{}", result);
} }
} }
...@@ -126,20 +160,20 @@ impl<T: 'static + BObject> BSet<T> { ...@@ -126,20 +160,20 @@ impl<T: 'static + BObject> BSet<T> {
return BSet { set: set, transformation: Option::None }; return BSet { set: set, transformation: Option::None };
} }
pub fn iter(&self) -> Iter<'_, T> { self.iter_lazy(self) }
pub fn iter(&self) -> Iter<'_, T> { pub fn iter_directly(&self) -> Iter<'_, T> { self.set.iter() }
return self.set.iter();
}
pub fn size(&self) -> usize { pub fn size(&self) -> usize { self.size_lazy(self) }
pub fn size_directly(&self) -> usize {
return self.set.len(); return self.set.len();
} }
pub fn isEmpty(&self) -> bool { pub fn isEmpty(&self) -> bool { return self.is_empty_lazy(self); }
return self.set.is_empty(); pub fn is_empty_directly(&self) -> bool { return self.set.is_empty() }
}
pub fn contains(&self, o: &T) -> bool { pub fn contains(&self, o: &T) -> bool { self.contains_lazy(self, o) }
pub fn contains_directly(&self, o: &T) -> bool {
return self.set.contains(o); return self.set.contains(o);
} }
...@@ -148,10 +182,15 @@ impl<T: 'static + BObject> BSet<T> { ...@@ -148,10 +182,15 @@ impl<T: 'static + BObject> BSet<T> {
} }
pub fn difference(&self, set: &BSet<T>) -> BSet<T> { pub fn difference(&self, set: &BSet<T>) -> BSet<T> {
return BSet{ set: self.set.clone().relative_complement(set.set.clone()), transformation: Option::None }; let result: OrdSet<T> = self.iter().fold(OrdSet::new(), |r_set, element| if set.contains(element) { r_set } else { r_set.update(element.clone()) });
return BSet::fromOrdSet(result);
} }
pub fn _union(&self, set: &BSet<T>) -> BSet<T> { pub fn _union(&self, set: &BSet<T>) -> BSet<T> {
return BSet { set: self.set.clone(), transformation: Option::Some(Box::new(Union::new(set.clone())))}
}
pub fn real_union(&self, set: &BSet<T>) -> BSet<T> {
return BSet{ set: self.set.clone().union(set.set.clone()), transformation: Option::None }; return BSet{ set: self.set.clone().union(set.set.clone()), transformation: Option::None };
} }
...@@ -168,7 +207,7 @@ impl<T: 'static + BObject> BSet<T> { ...@@ -168,7 +207,7 @@ impl<T: 'static + BObject> BSet<T> {
} }
pub fn _size(&self) -> BInteger { pub fn _size(&self) -> BInteger {
return BInteger::new(self.set.len().try_into().unwrap()); return BInteger::new(self.size().try_into().unwrap());
} }
pub fn elementOf(&self, object: &T) -> BBoolean { pub fn elementOf(&self, object: &T) -> BBoolean {
...@@ -184,15 +223,15 @@ impl<T: 'static + BObject> BSet<T> { ...@@ -184,15 +223,15 @@ impl<T: 'static + BObject> BSet<T> {
} }
pub fn notSubset(&self, set: &BSet<T>) -> BBoolean { pub fn notSubset(&self, set: &BSet<T>) -> BBoolean {
return BBoolean::new(!self.set.is_subset(&set.set)); return self.subset(set).not();
} }
pub fn strictSubset(&self, set: &BSet<T>) -> BBoolean { pub fn strictSubset(&self, set: &BSet<T>) -> BBoolean {
return BBoolean::new(self.set.len() < set.set.len() && self.set.is_subset(&set.set)); return BBoolean::new(self.size() < set.size() && self.subset(set));
} }
pub fn strictNotSubset(&self, set: &BSet<T>) -> BBoolean { pub fn strictNotSubset(&self, set: &BSet<T>) -> BBoolean {
return BBoolean::new(self.set.len() == set.set.len() || !self.set.is_subset(&set.set)); return BBoolean::new(self.size() >= set.size() || !self.subset(set));
} }
pub fn fin(&self) -> BSet<BSet<T>> { pub fn fin(&self) -> BSet<BSet<T>> {
...@@ -235,7 +274,7 @@ impl<T: 'static + BObject> BSet<T> { ...@@ -235,7 +274,7 @@ impl<T: 'static + BObject> BSet<T> {
pub fn nondeterminism(&self) -> T { pub fn nondeterminism(&self) -> T {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
return self.set.iter().nth(rng.gen_range(0..self.set.len())).unwrap().clone(); return self.iter().nth(rng.gen_range(0..self.set.len())).unwrap().clone();
} }
pub fn equal(&self, other: &BSet<T>) -> BBoolean { pub fn equal(&self, other: &BSet<T>) -> BBoolean {
......
use crate::bobject::BObject;
use crate::bset::BSet;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::marker::PhantomData;
#[derive(Clone)]
pub struct Identity<T: BObject> {
phantom: PhantomData<T>,
}
impl<T: BObject> Identity<T> {
const OP_NAME: &'static str = "Identity";
}
impl<T: BObject> Debug for Identity<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Identity()")
}
}
impl<T: 'static + BObject> SetOp for Identity<T> {
fn compute(&self, lhs: &BSet<T>) -> BSet<T> {
lhs.clone()
}
fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> {
Box::new(Identity{phantom: PhantomData})
}
fn get_op_name(&self) -> &str {
return Identity::<T>::OP_NAME;
}
fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> {
return Option::None;
}
}
impl<T: 'static + BObject> SetOpTraits for Identity<T>{
type Item = T;
fn contains_lazy(&self, lhs: &BSet<Self::Item>, o: &Self::Item) -> bool { lhs.contains_directly(o) }
fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool { lhs.is_empty_directly() }
fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize { lhs.size_directly() }
}
\ No newline at end of file
pub mod setops; pub mod setops;
//pub mod identity;
pub mod union;
\ No newline at end of file
use std::cmp::Ordering; use std::cmp::Ordering;
use std::fmt; use std::fmt::{Debug};
use std::fmt::{Debug, Formatter}; use std::iter::Chain;
use std::marker::PhantomData; use im::ordset::Iter;
use crate::bobject::BObject; use crate::bobject::BObject;
use crate::bset::BSet; use crate::bset::BSet;
pub trait SetOp: SetOpTraits + Debug { pub trait SetOp: SetOpTraits + Debug {
type Item: BObject;
fn compute(&self, lhs: &BSet<Self::Item>) -> BSet<Self::Item>; fn compute(&self, lhs: &BSet<Self::Item>) -> BSet<Self::Item>;
fn clone_box(&self) -> Box<dyn SetOp<Item = Self::Item>>; fn clone_box(&self) -> Box<dyn SetOp<Item = Self::Item>>;
fn get_op_name(&self) -> &str; fn get_op_name(&self) -> &str;
fn get_rhs(&self) -> Option<&Box<dyn SetOp<Item = Self::Item>>>; fn get_rhs(&self) -> Option<Box<dyn SetOp<Item = Self::Item>>>;
fn to_string(&self, lhs: Option<&str>) -> String {
let mut result = format!("{}(", self.get_op_name());
let mut has_lhs = false;
if lhs.is_some() {
result.push_str(lhs.unwrap());
has_lhs = true;
}
match self.get_rhs() {
Some(v) => {
if has_lhs { result.push_str(", "); }
result.push_str(format!("{}", v.to_string(Option::None)).as_str())
},
None => {},
}
result.push_str(")");
return result;
}
//PartialEq //PartialEq
fn eq_box(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool { fn eq_box(&self, other: &Box<dyn SetOp<Item = Self::Item>>) -> bool {
...@@ -71,12 +90,25 @@ pub trait SetOp: SetOpTraits + Debug { ...@@ -71,12 +90,25 @@ pub trait SetOp: SetOpTraits + Debug {
} }
pub trait SetOpTraits { pub trait SetOpTraits {
//type Bla: BObject; type Item: BObject;
//fn clone_box(&self) -> Box<dyn SetOp<Item = Self::Bla>>; fn iter_lazy(&self, lhs: &BSet<Self::Item>) -> Box<dyn Iterator<Item=Self::Item> + '_>;
//fn default_box() -> Box<dyn SetOp>; fn contains_lazy(&self, lhs: &BSet<Self::Item>, o:&Self::Item) -> bool;
fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool;
fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize;
} }
/* /*
struct IterWrapper<T: BObject> {
chain_iter: Option<Chain<Iter<T>, Iter<T>>>,
}
impl<T: BObject> IterWrapper<T> {
pub fn from_chain_iter(iter: Chain<Iter<T>, Iter<T>>) {
IterWrapper { chain_iter: Option::Some(iter) }
}
}
*/
/*
impl<T> SetOpTraits for T impl<T> SetOpTraits for T
where T: 'static + SetOp + Clone, where T: 'static + SetOp + Clone,
{ {
...@@ -117,44 +149,3 @@ impl<T: 'static + BObject> Default for Box<dyn SetOp<Item = T>> { ...@@ -117,44 +149,3 @@ impl<T: 'static + BObject> Default for Box<dyn SetOp<Item = T>> {
} }
} }
*/ */
\ No newline at end of file
#[derive(Clone)]
pub struct Identity<T: BObject> {
phantom: PhantomData<T>,
}
impl<T: BObject> Identity<T> {
const OP_NAME: &'static str = "Identity";
}
impl<T: BObject> Debug for Identity<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Identity()")
}
}
impl<T: 'static + BObject> SetOp for Identity<T> {
type Item = T;
fn compute(&self, lhs: &BSet<T>) -> BSet<T> {
lhs.clone()
}
fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> {
Box::new(Identity{phantom: PhantomData})
}
fn get_op_name(&self) -> &str {
return Identity::<T>::OP_NAME;
}
fn get_rhs(&self) -> Option<&Box<dyn SetOp<Item=Self::Item>>> {
return Option::None;
}
}
impl<T: 'static + BObject> SetOpTraits for Identity<T>{}
\ No newline at end of file
use std::cell::RefCell;
use std::convert::TryInto;
use crate::bobject::BObject;
use crate::bset::BSet;
use crate::lazy_ops::set_ops::setops::{SetOp, SetOpTraits};
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::iter::Chain;
use std::ops::Not;
use im::ordset::Iter;
#[derive(Clone)]
pub struct Union<T: BObject> {
rhs: RefCell<BSet<T>>,
rhs_is_reduced: RefCell<bool>,
}
impl<T: BObject> Union<T> {
const OP_NAME: &'static str = "Union";
}
impl<T: 'static + BObject> Debug for Union<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "Union({})", self.rhs.borrow())
}
}
impl<T: BObject> Union<T> {
pub fn new(rhs: BSet<T>) -> Union<T> {
Union {rhs: RefCell::new(rhs), rhs_is_reduced: RefCell::new(false)}
}
}
impl<T: 'static + BObject> SetOpTraits for Union<T>{
type Item = T;
fn iter_lazy(&self, lhs: &BSet<Self::Item>) -> Chain<Iter<T>, Iter<T>> {
return lhs.iter_directly().chain(self.rhs.borrow().iter());
}
fn contains_lazy(&self, lhs: &BSet<Self::Item>, o: &Self::Item) -> bool {
lhs.contains_directly(o) || self.rhs.borrow().contains_directly(o)
}
fn is_empty_lazy(&self, lhs: &BSet<Self::Item>) -> bool {
lhs.is_empty_directly() && self.rhs.borrow().is_empty_directly()
}
fn size_lazy(&self, lhs: &BSet<Self::Item>) -> usize {
if (*self.rhs_is_reduced.borrow()).not() {
let new_rhs = self.rhs.borrow().difference(lhs);
self.rhs.replace(new_rhs);
self.rhs_is_reduced.replace(true);
}
return lhs.size_directly() + self.rhs.borrow().size_directly();
}
}
impl<T: 'static + BObject> SetOp for Union<T> {
fn compute(&self, lhs: &BSet<T>) -> BSet<T> {
lhs.real_union(&self.rhs.borrow())
}
fn clone_box(&self) -> Box<dyn SetOp<Item=Self::Item>> {
Box::new(Union{rhs: RefCell::new(self.rhs.borrow().clone()),
rhs_is_reduced: RefCell::new(*self.rhs_is_reduced.borrow())})
}
fn get_op_name(&self) -> &str {
return Union::<T>::OP_NAME;
}
fn get_rhs(&self) -> Option<Box<dyn SetOp<Item=Self::Item>>> {
return Option::Some(self.rhs.borrow().clone_box());
}
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment