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

implemented some BRelation methods

also fixed wrong SetItem impl
parent dfcedf2e
No related branches found
No related tags found
No related merge requests found
#![ allow( non_snake_case) ]
use core::marker::PhantomData;
use crate::bboolean::BBoolean;
use crate::binteger::BInteger;
use crate::bset::{BSet, PowSetItem, Set, SetItem};
......@@ -24,9 +25,9 @@ pub trait RelLeftItem<const LEFT_SIZE: usize, RightItem: SetItem<RIGHT_SIZE>, co
fn rel_to_idx(rel_arr: [[bool; RIGHT_SIZE]; LEFT_SIZE]) -> usize {
let mut flat_arr = [false; REL_SIZE];
for left_idx in 0..6 {
for right_idx in 0..6 {
flat_arr[left_idx * 6 + right_idx] = rel_arr[left_idx][right_idx];
for left_idx in 0..LEFT_SIZE {
for right_idx in 0..RIGHT_SIZE {
flat_arr[left_idx * RIGHT_SIZE + right_idx] = rel_arr[left_idx][right_idx];
}
}
return Self::RelEnum::arr_to_idx(flat_arr);
......@@ -37,7 +38,7 @@ pub trait RelLeftItem<const LEFT_SIZE: usize, RightItem: SetItem<RIGHT_SIZE>, co
let mut result = [[false; RIGHT_SIZE]; LEFT_SIZE];
for left_idx in 0..LEFT_SIZE {
for right_idx in 0..RIGHT_SIZE {
result[left_idx][right_idx] = flat_arr[left_idx * 6 + right_idx];
result[left_idx][right_idx] = flat_arr[left_idx * RIGHT_SIZE + right_idx];
}
}
return result;
......@@ -56,6 +57,10 @@ where L: SetItem<LS> + RelLeftItem<LS, R, RS, SIZE, REL_SIZE>,
}
}
//impl<I> PowAble<> for I
//where I: SetItem<>
//TODO: pow/fin/pow1/fin1, maybe
impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L, LS, R, RS, REL_SIZE>
where L: SetItem<LS>,
R: SetItem<RS>{
......@@ -95,16 +100,6 @@ impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L,
BSet::const_from_arr(self.rel[key.as_idx()])
}
pub fn _union(&self, other: &Self) -> Self {
let mut result = self.copy();
for left_idx in 0..LS {
for right_idx in 0..RS {
if other.rel[left_idx][right_idx] { result.rel[left_idx][right_idx] = true; }
}
}
return result;
}
pub fn card(&self) -> BInteger {
let mut result: BInteger = 0;
for left_idx in 0..LS {
......@@ -182,6 +177,17 @@ impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L,
return BSet::const_from_arr(result);
}
pub fn range(&self) -> BSet<R, RS> {
let mut result = [false; RS];
for left_idx in 0..LS {
let current_arr = self.rel[left_idx];
for right_idx in 0..RS {
result[right_idx] |= current_arr[right_idx];
}
}
return BSet::const_from_arr(result);
}
pub fn cartesian_product<TL, TR>(left_set: &TL, right_set: &TR) -> Self
where TL: Set<LS, ItemType = L>,
TR: Set<RS, ItemType = R> {
......@@ -193,6 +199,153 @@ impl<L, const LS: usize, R, const RS: usize, const REL_SIZE: usize> BRelation<L,
}
return result;
}
pub fn inverse(&self) -> BRelation<R, RS, L, LS, REL_SIZE> {
let mut result = BRelation::<R, RS, L, LS, REL_SIZE>::empty();
for left_idx in 0..LS {
for right_idx in 0..RS {
result.rel[right_idx][left_idx] = self.rel[left_idx][right_idx];
}
}
return result;
}
pub fn domainRestriction(&self, domain_set: &BSet<L, LS>) -> Self {
let mut result = self.copy();
for left_idx in 0..LS {
if !domain_set.contains_idx(left_idx) { result.rel[left_idx] = [false; RS]; }
}
return result;
}
pub fn domainSubstraction(&self, domain_set: &BSet<L, LS>) -> Self {
let mut result = self.copy();
for left_idx in 0..LS {
if domain_set.contains_idx(left_idx) { result.rel[left_idx] = [false; RS]; }
}
return result;
}
pub fn rangeRestriction(&self, range_set: &BSet<R, RS>) -> Self {
let mut result = self.copy();
let range_arr = range_set.as_arr();
for left_idx in 0..LS {
for right_idx in 0..RS {
//retain only elements that are in self *and* in range_set
result.rel[left_idx][right_idx] &= range_arr[right_idx];
}
}
return result;
}
pub fn rangeSubstraction(&self, range_set: &BSet<R, RS>) -> Self {
let mut result = self.copy();
let range_arr = range_set.as_arr();
for left_idx in 0..LS {
for right_idx in 0..RS {
//retain only elements that are in self *but not* in range_set
result.rel[left_idx][right_idx] &= !range_arr[right_idx];
}
}
return result;
}
pub fn relationImage(&self, result_domain: &BSet<L, LS>) -> BSet<R, RS> {
let mut result_arr = [false; RS];
for left_idx in 0..LS {
if result_domain.contains_idx(left_idx) {
for right_idx in 0..RS {
result_arr[right_idx] |= self.rel[left_idx][right_idx];
}
}
}
return BSet::<R, RS>::const_from_arr(result_arr);
}
pub fn intersect(&self, other: &Self) -> Self {
return self.relation_combine(other, |s, o| s && o);
}
pub fn difference(&self, other: &Self) -> Self {
return self.relation_combine(other, |s, o| s && !o);
}
pub fn _union(&self, other: &Self) -> Self {
return self.relation_combine(other, |s, o| s | o);
}
fn relation_combine(&self, other: &Self, combine_fn: fn(bool, bool) -> bool) -> Self {
let mut result = self.copy();
for left_idx in 0..LS {
for right_idx in 0..RS {
result.rel[left_idx][right_idx] = combine_fn(result.rel[left_idx][right_idx], other.rel[left_idx][right_idx]);
}
}
return result;
}
pub fn equal(&self, other: &Self) -> BBoolean {
return self.rel.eq(&other.rel);
}
pub fn unequal(&self, other: &Self) -> BBoolean {
return !self.rel.eq(&other.rel);
}
pub fn elementOf(&self, (k, v): (L, R)) -> BBoolean {
return self.rel[k.as_idx()][v.as_idx()];
}
pub fn noElementOf(&self, (k, v): (L, R)) -> BBoolean {
return !self.rel[k.as_idx()][v.as_idx()];
}
pub fn subset(&self, other: &Self) -> BBoolean {
for left_idx in 0..LS {
for right_idx in 0..RS {
if other.rel[left_idx][right_idx] && !self.rel[left_idx][right_idx] { return false; }
}
}
return true;
}
pub fn notSubset(&self, other: &Self) -> BBoolean {
return !self.subset(other);
}
pub fn _override(&self, other: &Self) -> Self {
let mut result = self.copy();
for left_idx in 0..LS {
if other.rel[left_idx].contains(&true) { result.rel[left_idx] = other.rel[left_idx]; }
}
return result;
}
//TODO: directProduct/ParallelProduct maybe?
//TODO: support const-params in template? maybe compiler can figure them out itself?
pub fn composition<NewR, const NewRS: usize, const ParamTotal: usize, const NewTotal: usize>(&self, arg: &BRelation<R, RS, NewR, NewRS, ParamTotal>) -> BRelation<L, LS, NewR, NewRS, NewTotal>
where NewR: SetItem<NewRS>{
let mut result = BRelation::<L, LS, NewR, NewRS, NewTotal>::empty();
for left_idx in 0..LS {
result.rel[left_idx] = arg.relationImage(&BSet::const_from_arr(self.rel[left_idx])).as_arr()
}
return result;
}
//TODO: projection1/2 maybe? would need to impl SetItem for (L,R) and (R,L), might need adjustment in codegenerator?
// or we use the relation-item enums for the tuples as well...
//TODO: support const-params in template? maybe compiler can figure them out itself?
pub fn fnc<NewR, const NewRS: usize, const newRelTotal: usize>(&self) -> BRelation<L, LS, NewR, NewRS, newRelTotal>
where NewR: Set<RS> + SetItem<NewRS>{ //BRelation<L, LS, BSet<R, RS>, NewRS, newRelTotal
//NewR::ItemType = R; not yet supported in rust, NewR: Set<RS, I = R> might be, but I'd need to rewrite the trait for that and the related code. For now, we assume the code-generator creates correct code (if it wouldn't the code probably wouldn't run anyway...)
let mut result = BRelation::<L, LS, NewR, NewRS, newRelTotal>::empty();
for left_idx in 0..LS {
result.rel[left_idx][NewR::from_arr(self.rel[left_idx]).as_idx()] = true;
}
return result;
}
}
#[macro_export]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment