diff --git a/izia/src/main.rs b/izia/src/main.rs index b8ca05dd..ab1f6d14 100755 --- a/izia/src/main.rs +++ b/izia/src/main.rs @@ -25,7 +25,7 @@ fn main() { let reader = Interface::new("IZia").unwrap(); println!("IZia Copyright (C) 2018 to 2019 Charles Johnson.\nThis program comes with ABSOLUTELY NO WARRANTY.\nThis is free software, and you are welcome to redistribute it under certain\nconditions; visit https://www.gnu.org/licenses/gpl-3.0.en.html for more details."); reader.set_prompt(">>> ").unwrap(); - let mut cont = Context::new().unwrap(); + let mut cont = Context::new(); while let ReadResult::Input(input) = reader.read_line().unwrap() { println!("{}", cont.execute(&input)); } diff --git a/presentations/src/main.rs b/presentations/src/main.rs index d0b7bee8..94025c8f 100644 --- a/presentations/src/main.rs +++ b/presentations/src/main.rs @@ -147,7 +147,7 @@ fn main() { }); } } - let mut context = Context::new().unwrap(); + let mut context = Context::new(); for command in commands { context.execute(&command); } diff --git a/zia-lang.org/crate/src/page/home/mod.rs b/zia-lang.org/crate/src/page/home/mod.rs index a0c6df0d..57dfde48 100644 --- a/zia-lang.org/crate/src/page/home/mod.rs +++ b/zia-lang.org/crate/src/page/home/mod.rs @@ -26,7 +26,7 @@ pub struct Model { impl Default for Model { fn default() -> Self { Self { - context: Context::new().unwrap(), + context: Context::new(), input: String::new(), history: Vec::new(), command_input: ElRef::new(), @@ -39,7 +39,7 @@ impl Default for Model { impl Model { fn reset(&mut self) { - self.context = Context::new().unwrap(); + self.context = Context::new(); self.history = Vec::new(); self.menu.is_open = false; } diff --git a/zia-lang.org/crate/src/page/home/tutorials.rs b/zia-lang.org/crate/src/page/home/tutorials.rs index d185acd4..dba54aa3 100644 --- a/zia-lang.org/crate/src/page/home/tutorials.rs +++ b/zia-lang.org/crate/src/page/home/tutorials.rs @@ -1,7 +1,7 @@ #[cfg(test)] use std::time::{Duration, Instant}; -pub const TUTORIALS: (Tutorial<18>, Tutorial<10>, Tutorial<12>) = ( +pub const TUTORIALS: (Tutorial<18>, Tutorial<12>, Tutorial<12>) = ( Tutorial { title: "Factorial", steps: [ @@ -178,6 +178,24 @@ pub const TUTORIALS: (Tutorial<18>, Tutorial<10>, Tutorial<12>) = ( #[cfg(test)] expected_evaluation: "true" }, + TutorialStep { + command: "let ((_y_ exists_such_that) (_y_ is parent of _x_) and (_y_ is parent of _z_)) => (_x_ is sibling of _z_)", + explanation: "Define sibling is terms of parent relationships", + #[cfg(test)] + expected_evaluation: "" + }, + TutorialStep { + command: "let Alice is parent of Eve", + explanation: "This should mean that Eve is sibling of Bob", + #[cfg(test)] + expected_evaluation: "" + }, + //TutorialStep { + // command: "Eve is sibling of Bob", + // explanation: "Let's check", + // #[cfg(test)] + // expected_evaluation: "true" + //} ] }, Tutorial { diff --git a/zia/src/ast/macro.rs b/zia/src/ast/macro.rs index f16e33f1..d14d68b2 100644 --- a/zia/src/ast/macro.rs +++ b/zia/src/ast/macro.rs @@ -45,7 +45,7 @@ impl GenericSyntaxTree { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct SyntaxKey { syntax: Option, - concept: Option, + pub concept: Option, } impl PartialEq diff --git a/zia/src/concepts/mod.rs b/zia/src/concepts/mod.rs index 63576802..e63d2ed1 100755 --- a/zia/src/concepts/mod.rs +++ b/zia/src/concepts/mod.rs @@ -26,7 +26,10 @@ use crate::{ }; use maplit::{hashmap, hashset}; use std::{ - collections::{hash_map::Iter, HashMap, HashSet}, + collections::{ + hash_map::{IntoIter, Iter}, + HashMap, HashSet, + }, fmt::{Debug, Display}, hash::Hash, iter::{Copied, Map}, @@ -441,6 +444,7 @@ impl<'a, Id: Copy + Debug + Eq + Hash> From<&'a NewDirectConceptDelta> type CopyPairFn = fn((&T, &T)) -> (T, T); type CopiedPairIter<'a, T> = Map, CopyPairFn>; +type OwnedPairIter = IntoIter; impl ConceptTrait for Concept @@ -449,6 +453,7 @@ impl ConceptTrait type IdIterator<'a> = Copied>; type IdPairIterator<'a> = CopiedPairIter<'a, Self::Id>; + type OwnedIdPairIterator = OwnedPairIter; fn id(&self) -> Id { self.id @@ -702,6 +707,14 @@ impl ConceptTrait .iter() .map(copy_pair_elements) } + + fn into_iter_hand_of(self, hand: Hand) -> Self::OwnedIdPairIterator { + match hand { + Hand::Left => self.concrete_part.lefthand_of, + Hand::Right => self.concrete_part.righthand_of, + } + .into_iter() + } } const fn copy_pair_elements((x, y): (&T, &T)) -> (T, T) { @@ -719,7 +732,7 @@ pub enum SpecificPart { String(String), } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] pub enum Hand { Left, Right, diff --git a/zia/src/concepts/trait.rs b/zia/src/concepts/trait.rs index 262cad33..0c5939ee 100644 --- a/zia/src/concepts/trait.rs +++ b/zia/src/concepts/trait.rs @@ -24,6 +24,7 @@ pub trait Concept: Sized { type IdIterator<'a>: Iterator where Self: 'a; + type OwnedIdPairIterator: Iterator + 'static; fn id(&self) -> Self::Id; fn maybe_composition(&self) -> Option>; @@ -103,8 +104,20 @@ pub trait Concept: Sized { } self.iter_hand_of(hand).map(f::) } + fn into_iter_composition_ids( + self, + hand: Hand, + ) -> Map> { + // the argument is dropped in the function but destructors cannot run in const contexts + #[allow(clippy::missing_const_for_fn)] + fn f(p: (Id, Id)) -> Id { + p.1 + } + self.into_iter_hand_of(hand).map(f::) + } fn iter_hand_of(&self, hand: Hand) -> Self::IdPairIterator<'_>; + fn into_iter_hand_of(self, hand: Hand) -> Self::OwnedIdPairIterator; /// Gets the index of the concept that `self` may reduce to. fn get_reduction(&self) -> Option; diff --git a/zia/src/context.rs b/zia/src/context.rs index 0f018b62..5b3db26d 100755 --- a/zia/src/context.rs +++ b/zia/src/context.rs @@ -21,9 +21,7 @@ use crate::{ ast::{GenericSyntaxTree, SyntaxKey, SyntaxLeaf}, concepts::{ConceptTrait, ConcreteConceptType, Hand}, context_cache::{GenericCache, SharedSyntax}, - context_delta::{ - DirectConceptDelta, NestedDelta, NewConceptDelta, SharedDelta, - }, + context_delta::{DirectConceptDelta, NestedDelta, NewConceptDelta}, context_search::{ContextReferences, ContextSearch}, context_updater::ContextUpdater, delta::Apply, @@ -38,28 +36,17 @@ use std::{ collections::{BinaryHeap, HashMap, HashSet}, default::Default, fmt::Debug, - marker::PhantomData, }; -pub struct Context +pub struct Context where - S: SnapShotReader - + Default - + Sync - + Apply - + Debug, - SDCD: Clone - + Debug - + AsRef> - + From>, - D: SharedDelta>, + S: SnapShotReader + Default + Sync + Apply + Debug, { snap_shot: S, - delta: D, + delta: SR::Share>, cache: GenericCache, new_variable_concepts_by_label: HashMap, bounded_variable_syntax: HashSet>, - phantom: PhantomData, } pub struct TokenSubsequence { @@ -83,25 +70,18 @@ impl Debug for TokenSubsequence { } } -impl Clone - for Context +impl Clone for Context where - S: SnapShotReader + S: SnapShotReader + Default + Sync - + Apply + + Apply + Debug + Clone, - SDCD: Clone - + Debug - + AsRef> - + From>, - D: SharedDelta>, { fn clone(&self) -> Self { Self { - delta: D::default(), - phantom: self.phantom, + delta: SR::share(NestedDelta::default()), bounded_variable_syntax: self.bounded_variable_syntax.clone(), cache: self.cache.clone(), new_variable_concepts_by_label: self @@ -112,24 +92,14 @@ where } } -impl - Context +impl Context where - S: SnapShotReader - + Default - + Sync - + Apply - + Debug, - SDCD: Clone - + Debug - + AsRef> - + From>, - D: SharedDelta>, + S: SnapShotReader + Default + Sync + Apply + Debug, { - pub fn new() -> ZiaResult { + pub fn new() -> Self { let mut cont = Self::default(); - cont.setup()?; - Ok(cont) + cont.setup(); + cont } pub fn lex(&self, command: &str) -> Vec> { @@ -289,13 +259,10 @@ where let string = self.execute_without_closing_scope(command); self.new_variable_concepts_by_label = HashMap::new(); self.bounded_variable_syntax = HashSet::new(); - string.unwrap() + string } - fn execute_without_closing_scope( - &mut self, - command: &str, - ) -> ZiaResult { + fn execute_without_closing_scope(&mut self, command: &str) -> String { let string = self .ast_from_expression(command) .and_then(|mut a| { @@ -307,8 +274,8 @@ where self.call(&a) }) .unwrap_or_else(|e| e.to_string()); - self.commit()?; - Ok(string) + self.commit(); + string } pub fn create_variable_concepts( @@ -331,8 +298,7 @@ where NewConceptDelta::FreeVariable }, ); - let maybe_inner_delta = self.delta.get_mut(); - let delta = maybe_inner_delta?; + let delta = SR::make_mut(&mut self.delta); // This might lead to variables being committed to snap shot unnecessarily let concept_id = delta .update_concept_delta(direct_delta, &mut self.cache); @@ -476,10 +442,7 @@ where ) -> ZiaResult> { let concept_id = concept.map_or_else( || { - let maybe_inner_delta = self.delta.get_mut(); - let Some(delta) = maybe_inner_delta else { - return Err(ZiaError::MultiplePointersToDelta); - }; + let delta = SR::make_mut(&mut self.delta); if let Some(id) = self.snap_shot.concept_from_label(delta, syntax) { @@ -493,8 +456,6 @@ where snap_shot: &self.snap_shot, delta, cache: &mut self.cache, - phantom: PhantomData, - phantom2: PhantomData, }; Ok(updater.new_labelled_concept(syntax, None, label_id)) }, @@ -779,14 +740,14 @@ where self.context_search().combine(left, right) } - fn commit(&mut self) -> ZiaResult<()> { - let taken_delta = std::mem::take(&mut self.delta); - let delta = taken_delta.into_nested()?; - self.snap_shot.apply(delta); - Ok(()) + fn commit(&mut self) { + let mut delta = SR::share(NestedDelta::default()); + std::mem::swap(&mut self.delta, &mut delta); + self.snap_shot.apply(delta.as_ref().clone()); // TODO: avoiding cloning using + // Arc::try_unwrap or Rc::try_unwrap } - fn label_concrete_concepts(&mut self) -> ZiaResult<()> { + fn label_concrete_concepts(&mut self) { let labels = vec![ (":=", ConcreteConceptType::Define), ("->", ConcreteConceptType::Reduction), @@ -802,16 +763,11 @@ where ("precedes", ConcreteConceptType::Precedes), ("forget", ConcreteConceptType::Forget), ]; - let maybe_inner_delta = self.delta.get_mut(); - let Some(delta) = maybe_inner_delta else { - return Err(ZiaError::MultiplePointersToDelta); - }; + let delta = SR::make_mut(&mut self.delta); let mut updater = ContextUpdater { snap_shot: &self.snap_shot, delta, cache: &mut self.cache, - phantom: PhantomData, - phantom2: PhantomData, }; let label_id = updater.new_labelled_concept( "label_of", @@ -825,12 +781,11 @@ where Some(label_id), ); } - Ok(()) } - fn setup(&mut self) -> ZiaResult<()> { - self.label_concrete_concepts()?; - self.commit()?; + fn setup(&mut self) { + self.label_concrete_concepts(); + self.commit(); let result = self.execute("let (true and true) -> true"); debug_assert_eq!(result, ""); let result = self.execute("let (false and _y_) -> false"); @@ -845,7 +800,6 @@ where debug_assert_eq!(result, ""); let result = self.execute("let := precedes let"); debug_assert_eq!(result, ""); - Ok(()) } fn reduce_and_call_pair( @@ -958,7 +912,7 @@ where }) .map(|r| r.map(|()| String::new())), ConcreteConceptType::Forget => right.get_concept().map(|c| { - self.updater()?.delete_reduction(c, right.to_string())?; + self.updater().delete_reduction(c, right.to_string())?; Ok(String::new()) }), ConcreteConceptType::Label => Some(Ok("'".to_string() @@ -1040,18 +994,13 @@ where } } - fn updater(&mut self) -> ZiaResult> { - let maybe_inner_delta = self.delta.get_mut(); - let Some(delta) = maybe_inner_delta else { - return Err(ZiaError::MultiplePointersToDelta); - }; - Ok(ContextUpdater { + fn updater(&mut self) -> ContextUpdater<'_, S, SR> { + let delta = SR::make_mut(&mut self.delta); + ContextUpdater { snap_shot: &self.snap_shot, delta, cache: &mut self.cache, - phantom: PhantomData, - phantom2: PhantomData, - }) + } } /// If the new syntax is an expanded expression then this returns `Err(ZiaError::BadComposition)`. Otherwise the result depends on whether the new or old syntax is associated with a concept and whether the old syntax is an expanded expression. @@ -1069,7 +1018,7 @@ where (_, Some(_), _, None) => Err(ZiaError::BadComposition), (_, None, None, None) => Err(ZiaError::RedundantRefactor), (None, _, Some(b), None) => { - self.updater()?.relabel(b, &old.to_string(), &new.to_string()) + self.updater().relabel(b, &old.to_string(), &new.to_string()) }, (None, _, Some(b), Some(_)) => { let syntax = { @@ -1083,9 +1032,9 @@ where .get_concept_of_label(self.delta.as_ref(), b) .is_none() { - self.updater()?.label(b, &syntax, &new.to_string()) + self.updater().label(b, &syntax, &new.to_string()) } else { - self.updater()?.relabel( + self.updater().relabel( b, &old.to_string(), &new.to_string(), @@ -1093,7 +1042,7 @@ where } }, (None, _, None, Some((ref left, ref right))) => { - self.updater()?.define_new_syntax(&new.to_string(), left, right) + self.updater().define_new_syntax(&new.to_string(), left, right) }, (Some(a), a_comp, Some(b), None) => { if a == b { @@ -1111,7 +1060,7 @@ where context_search.to_ast(&right).to_string(), ) }; - let mut updater = self.updater()?; + let mut updater = self.updater(); updater.try_delete_concept(a, &a.to_string())?; updater.try_delete_concept(left, &left_syntax)?; updater.try_delete_concept(right, &right_syntax) @@ -1119,7 +1068,7 @@ where } } else if a_comp.is_none() { if self.snap_shot.get_concept(b).is_some() { - let mut updater = self.updater()?; + let mut updater = self.updater(); updater.unlabel(a, &a.to_string())?; updater.relabel(b, &old.to_string(), &new.to_string()) } else { @@ -1141,7 +1090,7 @@ where Some((ref new_left, ref new_right)), None, Some((ref left, ref right)), - ) => self.updater()?.redefine_composition( + ) => self.updater().redefine_composition( &a, left, right, @@ -1149,7 +1098,7 @@ where &new_right.to_string(), ), (Some(a), None, None, Some((ref left, ref right))) => { - self.updater()?.redefine(&a, left, right) + self.updater().redefine(&a, left, right) }, } } @@ -1176,16 +1125,11 @@ where }); } drop(context_search); - let maybe_inner_delta = self.delta.get_mut(); - let Some(delta) = maybe_inner_delta else { - return Err(ZiaError::MultiplePointersToDelta); - }; + let delta = SR::make_mut(&mut self.delta); let mut updater = ContextUpdater { snap_shot: &self.snap_shot, delta, cache: &mut self.cache, - phantom: PhantomData, - phantom2: PhantomData, }; let syntax_concept = updater.concept_from_ast(syntax)?; let normal_form_concept = updater.concept_from_ast(normal_form)?; @@ -1201,10 +1145,7 @@ where &mut self, syntax: &GenericSyntaxTree, ) -> ZiaResult<()> { - let maybe_inner_delta = self.delta.get_mut(); - let Some(delta) = maybe_inner_delta else { - return Err(ZiaError::MultiplePointersToDelta); - }; + let delta = SR::make_mut(&mut self.delta); let snap_shot = &self.snap_shot; let cache = &mut self.cache; syntax.get_concept().map_or_else( @@ -1218,15 +1159,13 @@ where cache, delta, snap_shot, - phantom: PhantomData, - phantom2: PhantomData, } .delete_reduction(c, syntax.to_string()) }, ) } - fn context_search(&self) -> ContextSearch<'_, '_, S, SDCD, D, CCI, SR> { + fn context_search(&self) -> ContextSearch<'_, '_, S, CCI, SR> { ContextSearch::from(ContextReferences { snap_shot: &self.snap_shot, delta: self.delta.clone(), @@ -1236,45 +1175,24 @@ where } } -impl Default - for Context +impl Default for Context where - S: SnapShotReader - + Default - + Sync - + Apply - + Debug, - SDCD: Clone - + Debug - + AsRef> - + From>, - D: SharedDelta>, + S: SnapShotReader + Default + Sync + Apply + Debug, { fn default() -> Self { Self { snap_shot: S::default(), - delta: D::default(), + delta: SR::share(NestedDelta::default()), cache: GenericCache::::default(), new_variable_concepts_by_label: HashMap::new(), bounded_variable_syntax: HashSet::new(), - phantom: PhantomData, } } } -impl From - for Context +impl From for Context where - S: SnapShotReader - + Default - + Sync - + Apply - + Debug, - SDCD: Clone - + Debug - + AsRef> - + From>, - D: SharedDelta>, + S: SnapShotReader + Default + Sync + Apply + Debug, { fn from(snap_shot: S) -> Self { Self { diff --git a/zia/src/context_cache/macro.rs b/zia/src/context_cache/macro.rs index 50f0e19f..5f1a95ab 100644 --- a/zia/src/context_cache/macro.rs +++ b/zia/src/context_cache/macro.rs @@ -149,7 +149,7 @@ impl InferenceCacheList { #[derive(Debug, Clone)] pub struct ReductionCacheList { - head: SR::Share>, + pub head: SR::Share>, tail: Option>, } @@ -203,12 +203,24 @@ impl ReductionCacheList { ast: &SharedSyntax, reduction_result: &ReductionResult, ) { - if !ast.is_variable() - && reduction_result - .as_ref() - .map_or(true, |(r, _)| r.key() != ast.key()) + if reduction_result.as_ref().map_or(true, |(r, _)| r.key() != ast.key()) { + debug!( + "Caching reduction: {} -> {}", + ast.as_ref(), + reduction_result + .as_ref() + .map_or_else(|| String::from("None"), |r| r.0.to_string()) + ); self.head.insert(ast.key(), reduction_result.clone()); + } else { + debug!( + "Skipping caching reduction: {} -> {}", + ast.as_ref(), + reduction_result + .as_ref() + .map_or_else(|| String::from("None"), |r| r.0.to_string()) + ); } } } diff --git a/zia/src/context_delta.rs b/zia/src/context_delta.rs index 3ce9dfb8..7a8753ca 100644 --- a/zia/src/context_delta.rs +++ b/zia/src/context_delta.rs @@ -17,7 +17,6 @@ use crate::{ concepts::{ConcreteConceptType, LefthandOf, RighthandOf}, context_cache::GenericCache, - errors::ZiaResult, mixed_concept::{self, ConceptId, MixedConcept}, nester::SharedReference, }; @@ -31,34 +30,18 @@ use std::{ #[derive(Clone)] pub struct ContextDelta< ConceptId: mixed_concept::ConceptId, - SharedDirectConceptDelta, SR: SharedReference, > { string: HashMap>, number_of_uncommitted_concepts: usize, - concepts_to_apply_in_order: Vec<(ConceptId, SharedDirectConceptDelta)>, - concept: HashMap< - ConceptId, - Vec>, - >, + concepts_to_apply_in_order: + Vec<(ConceptId, SR::Share>)>, + concept: HashMap>>, phantom: PhantomData, } -pub trait SharedDelta: - Clone + Default + Debug + AsRef -{ - type NestedDelta; - fn get_mut(&mut self) -> Option<&mut Self::NestedDelta>; - fn from_nested(nested: Self::NestedDelta) -> Self; - fn into_nested(self) -> ZiaResult; - fn strong_count(&self) -> usize; -} - -impl< - ConceptId: mixed_concept::ConceptId, - SharedDirectConceptDelta, - SR: SharedReference, - > ContextDelta +impl + ContextDelta { fn new(number_of_uncommitted_concepts: usize) -> Self { Self { @@ -71,19 +54,16 @@ impl< } } -impl - ContextDelta +impl ContextDelta where CI: MixedConcept, - SharedDirectConceptDelta: - Clone + AsRef> + From>, { pub fn update_concept_delta( &mut self, concept_delta: DirectConceptDelta, cache_to_invalidate: &mut GenericCache, ) -> CI { - let concept_delta: SharedDirectConceptDelta = concept_delta.into(); + let concept_delta = SR::share(concept_delta); let dcd = ConceptDelta::Direct(concept_delta.clone()); let concept_id = match concept_delta.as_ref() { DirectConceptDelta::New(delta) => { @@ -182,7 +162,7 @@ where pub const fn concepts_to_apply_in_order( &self, - ) -> &Vec<(CI, SharedDirectConceptDelta)> { + ) -> &Vec<(CI, SR::Share>)> { &self.concepts_to_apply_in_order } @@ -193,16 +173,13 @@ where pub fn get_concept( &self, key: &CI, - ) -> Option>> - { + ) -> Option>> { self.concept.get(key).map(|v| v.iter()) } pub fn iter_concepts( &self, - ) -> impl Iterator< - Item = (&CI, Iter<'_, ConceptDelta>), - > { + ) -> impl Iterator>)> { self.concept.iter().map(|(c, v)| (c, v.iter())) } @@ -307,7 +284,7 @@ where fn insert_delta_for_existing_concept( &mut self, concept_id: CI, - cd: ConceptDelta, + cd: ConceptDelta, ) { self.insert_delta_for_concept( concept_id, @@ -335,7 +312,7 @@ where self.number_of_uncommitted_concepts += 1; self.insert_delta_for_concept( concept_id, - ConceptDelta::Direct(DirectConceptDelta::New(cd).into()), + ConceptDelta::Direct(SR::share(DirectConceptDelta::New(cd))), |last_delta, concept_id: CI| match last_delta { ConceptDelta::Direct(dcd) if matches!( @@ -351,8 +328,8 @@ where fn insert_delta_for_concept( &mut self, concept_id: CI, - cd: ConceptDelta, - sanity_check: impl Fn(&ConceptDelta, CI), + cd: ConceptDelta, + sanity_check: impl Fn(&ConceptDelta, CI), ) { match self.concept.entry(concept_id) { Entry::Occupied(mut e) => { @@ -370,11 +347,9 @@ where } } -impl Debug - for ContextDelta +impl Debug for ContextDelta where CI: ConceptId, - SharedDirectConceptDelta: Debug, { fn fmt( &self, @@ -405,26 +380,29 @@ where } } -#[derive(Debug)] -pub struct NestedDelta +#[derive(Clone)] +pub struct NestedDelta where CI: ConceptId, - SharedDirectConceptDelta: Debug, - D: SharedDelta, { - inner_delta: Option, - overlay_delta: ContextDelta, + inner_delta: Option>>, + overlay_delta: ContextDelta, } -impl< - CI, - SharedDirectConceptDelta, - D: SharedDelta, - SR: SharedReference, - > Default for NestedDelta +impl Debug for NestedDelta { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.debug_struct("NestedDelta") + .field( + "inner_delta", + &self.inner_delta.as_ref().map(std::convert::AsRef::as_ref), + ) + .field("overlay_delta", &self.overlay_delta) + .finish() + } +} +impl Default for NestedDelta where CI: ConceptId + Clone, - SharedDirectConceptDelta: Debug, { fn default() -> Self { Self { @@ -433,32 +411,19 @@ where } } } -type BoxedTupleIterator<'a, ConceptId, SharedDirectConceptDelta> = Box< +type BoxedTupleIterator<'a, ConceptId, SR> = Box< dyn Iterator< Item = ( &'a ConceptId, - Box< - dyn Iterator< - Item = &'a ConceptDelta< - ConceptId, - SharedDirectConceptDelta, - >, - > + 'a, - >, + Box> + 'a>, ), > + 'a, >; -impl - NestedDelta +impl NestedDelta where CI: MixedConcept, - SharedDirectConceptDelta: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta, { - pub fn spawn(inner_delta: D) -> Self { + pub fn spawn(inner_delta: SR::Share) -> Self { Self { overlay_delta: ContextDelta::new( inner_delta @@ -577,36 +542,25 @@ where pub fn get_concept<'a>( &'a self, key: &'a CI, - ) -> Option< - impl Iterator>, - > { + ) -> Option>> { let maybe_inner_concept_deltas = self.inner_delta.as_ref().and_then(|d| d.as_ref().get_concept(key)); let maybe_over_concept_deltas = self.overlay_delta.get_concept(key); match (maybe_inner_concept_deltas, maybe_over_concept_deltas) { (None, None) => None, (Some(cd), None) => { - let new_box: Box< - dyn Iterator< - Item = &ConceptDelta, - >, - > = Box::new(cd); + let new_box: Box>> = + Box::new(cd); Some(new_box) }, (None, Some(cd)) => { - let new_box: Box< - dyn Iterator< - Item = &ConceptDelta, - >, - > = Box::new(cd); + let new_box: Box>> = + Box::new(cd); Some(new_box) }, (Some(inner_cd), Some(outer_cd)) => { - let new_box: Box< - dyn Iterator< - Item = &ConceptDelta, - >, - > = Box::new(inner_cd.chain(outer_cd)); + let new_box: Box>> = + Box::new(inner_cd.chain(outer_cd)); Some(new_box) }, } @@ -617,15 +571,11 @@ where ) -> impl Iterator< Item = ( &'a CI, - Box< - dyn Iterator< - Item = &'a ConceptDelta, - > + 'a, - >, + Box> + 'a>, ), > + 'a { let inner_delta = self.inner_delta.as_ref(); - let new_box: BoxedTupleIterator<'a, CI, SharedDirectConceptDelta> = + let new_box: BoxedTupleIterator<'a, CI, SR> = Box::new(self.overlay_delta.iter_concepts().map(move |(k, v)| { (k, { let inner_concept_iter = @@ -633,23 +583,13 @@ where match inner_concept_iter { None => { let new_box: Box< - dyn Iterator< - Item = &ConceptDelta< - CI, - SharedDirectConceptDelta, - >, - >, + dyn Iterator>, > = Box::new(v); new_box }, Some(inner_concept_iter) => { let new_box: Box< - dyn Iterator< - Item = &ConceptDelta< - CI, - SharedDirectConceptDelta, - >, - >, + dyn Iterator>, > = Box::new(inner_concept_iter.chain(v)); new_box }, @@ -661,19 +601,12 @@ where .as_ref() .map_or_else( || { - let new_box: BoxedTupleIterator< - 'a, - CI, - SharedDirectConceptDelta, - > = Box::new(std::iter::empty()); + let new_box: BoxedTupleIterator<'a, CI, SR> = + Box::new(std::iter::empty()); new_box }, |d| { - let new_box: BoxedTupleIterator< - 'a, - CI, - SharedDirectConceptDelta, - > = Box::new( + let new_box: BoxedTupleIterator<'a, CI, SR> = Box::new( d.as_ref() .iter_concepts() .filter(move |(k, _)| !concepts.contains_key(*k)), @@ -695,7 +628,7 @@ where pub fn concepts_to_apply_in_order( &self, - ) -> Vec<(CI, SharedDirectConceptDelta)> { + ) -> Vec<(CI, SR::Share>)> { let mut concepts = self .inner_delta .as_ref() @@ -714,15 +647,15 @@ where } #[derive(Clone)] -pub enum ConceptDelta { - Direct(SharedDirectConceptDelta), +pub enum ConceptDelta { + Direct(SR::Share>), Indirect(IndirectConceptDelta), } -impl - ConceptDelta -{ - pub const fn try_direct(&self) -> Option<&SharedDirectConceptDelta> { +impl ConceptDelta { + pub const fn try_direct( + &self, + ) -> Option<&SR::Share>> { if let Self::Direct(dcd) = &self { Some(dcd) } else { @@ -731,27 +664,27 @@ impl } } -impl - From> - for ConceptDelta +impl From> + for ConceptDelta { fn from(icd: IndirectConceptDelta) -> Self { Self::Indirect(icd) } } -impl Debug - for ConceptDelta +impl Debug for ConceptDelta where - SharedDirectConceptDelta: Debug, - Id: Debug, + Id: ConceptId, + SR: SharedReference, { fn fmt( &self, formatter: &mut std::fmt::Formatter, ) -> Result<(), std::fmt::Error> { formatter.write_str(&match *self { - Self::Direct(ref c) => format!("+ {c:#?}") + " (direct) ", + Self::Direct(ref c) => { + format!("+ {:#?}", c.as_ref()) + " (direct) " + }, Self::Indirect(ref c) => format!("- {c:#?}") + " (indirect) ", }) } diff --git a/zia/src/context_search.rs b/zia/src/context_search.rs index 66613269..d0c502b5 100644 --- a/zia/src/context_search.rs +++ b/zia/src/context_search.rs @@ -21,9 +21,7 @@ use crate::{ concepts::{format_string, ConceptTrait, ConcreteConceptType, Hand}, consistent_merge::ConsistentMerge, context_cache::{GenericCache, ReductionCache}, - context_delta::{ - DirectConceptDelta, NestedDelta, NewConceptDelta, SharedDelta, - }, + context_delta::{DirectConceptDelta, NestedDelta, NewConceptDelta}, mixed_concept::{ConceptId, MixedConcept}, nester::SharedReference, reduction_reason::{ReductionReason, ReductionResult, SharedSyntax}, @@ -31,52 +29,40 @@ use crate::{ substitute::substitute, variable_mask_list::{VariableMask, VariableMaskList}, }; +use dashmap::DashSet; use log::debug; use maplit::{hashmap, hashset}; -use std::{collections::HashSet, fmt::Debug, iter, marker::PhantomData}; +use std::{ + collections::HashSet, + fmt::Debug, + iter::{self, empty}, + marker::PhantomData, +}; -pub struct ContextSearch< - 's, - 'v, - S, - SDCD, - D, - CCI: ConceptId, - SR: SharedReference, -> where - S: SnapShotReader + Sync + std::fmt::Debug, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta>, +pub struct ContextSearch<'s, 'v, S, CCI: ConceptId, SR: SharedReference> +where + S: SnapShotReader + Sync + std::fmt::Debug, { snap_shot: &'s S, variable_mask: SR::Share>, - delta: D, + delta: SR::Share>, caches: GenericCache, syntax_evaluating: HashSet>, concept_inferring: HashSet, bound_variable_syntax: &'v HashSet>, - phantom: PhantomData, + phantom: PhantomData>>, phantom2: PhantomData, } -impl Debug - for ContextSearch<'_, '_, S, SDCD, D, CCI, SR> +impl Debug + for ContextSearch<'_, '_, S, CCI, SR> where - S: SnapShotReader + Sync + std::fmt::Debug, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: AsRef> - + SharedDelta>, + S: SnapShotReader + Sync + std::fmt::Debug, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ContextSearch") .field("snap_shot", &self.snap_shot) .field("variable_mask", &"[variable_mask]") - .field("delta", &self.delta) + .field("delta", self.delta.as_ref()) .field("caches", &"[caches]") .field("syntax_evaluating", &self.syntax_evaluating) .field("concept_inferring", &self.concept_inferring) @@ -87,16 +73,10 @@ where } } -impl<'s, 'v, S, SDCD, D, CCI: MixedConcept, SR: SharedReference> - ContextSearch<'s, 'v, S, SDCD, D, CCI, SR> +impl<'s, 'v, S, CCI: MixedConcept, SR: SharedReference> + ContextSearch<'s, 'v, S, CCI, SR> where - S: SnapShotReader + Sync + std::fmt::Debug, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: AsRef> - + SharedDelta>, + S: SnapShotReader + Sync + std::fmt::Debug, { fn infer_reduction( &self, @@ -116,21 +96,38 @@ where let result = composition_concept .iter_hand_of(Hand::Right) .find_map(|(condition_id, implication_rule_id)| { - let condition = self.to_ast(&condition_id); - let (reduced_condition, reason) = - self.reduce(&condition)?; - let x = reduced_condition.get_concept()?; - self.is_concrete_type(ConcreteConceptType::True, &x) - .map(|x| { - ( - // TODO: this should be the "true" concept only if the implication result is equivalent to the `concept` - self.to_ast(&x), - ReductionReason::::inference( - self.to_ast(&implication_rule_id), - reason, - ), + let implication_rule = + self.to_ast(&implication_rule_id); + if let Some((reduction, _)) = + self.reduce(&implication_rule) + { + if self.concrete_type_of_ast(&reduction) + == Some(ConcreteConceptType::True) + { + let condition = self.to_ast(&condition_id); + let (reduced_condition, reason) = + self.reduce(&condition)?; + let x = reduced_condition.get_concept()?; + self.is_concrete_type( + ConcreteConceptType::True, + &x, ) - }) + .map(|x| { + ( + // TODO: this should be the "true" concept only if the implication result is equivalent to the `concept` + self.to_ast(&x), + ReductionReason::::inference( + self.to_ast(&implication_rule_id), + reason, + ), + ) + }) + } else { + None + } + } else { + None + } }); result }); @@ -178,9 +175,11 @@ where ) -> ReductionResult { debug!("reduce({})", ast.to_string()); self.caches.get_reduction_or_else(ast, || { + debug!("Cache miss: {}", ast.as_ref()); let maybe_concept: Option = ast.get_concept(); if let Some(id) = maybe_concept { if self.concrete_type(&id).is_some() { + // TODO: cache this result without breaking tests return None; } } @@ -237,9 +236,9 @@ where let cache = SR::share(ReductionCache::::default()); match (left_result, right_result) { (None, None) => { - let ast = self.contract_pair(left, right); - let generalisation_candidates = self.find_generalisations(&ast); - let ast = ast.share(); + let ast = SR::share(self.contract_pair(left, right)); + let generalisation_candidates = + self.find_generalisations(ast.as_ref())?; generalisation_candidates .into_iter() .filter_map(move |gc| { @@ -258,8 +257,9 @@ where context_search .insert_variable_mask(variable_mask.clone()) .ok()?; - context_search.reduce_concept(&generalisation).map( - |(ast, reason)| { + let reduction_result = context_search + .reduce_concept(&generalisation) + .map(|(ast, reason)| { ( context_search .substitute(&ast, &variable_mask), @@ -269,8 +269,17 @@ where reason, ), ) - }, - ) + }); + for item in + context_search.caches.reductions.head.as_ref() + { + let Some(c) = item.key().concept else { + continue; + }; + let ast = self.to_ast(&c); + self.caches.insert_reduction(&ast, item.value()); + } + reduction_result }) }, (Some((left_ast, left_reason)), None) => Some(( @@ -354,42 +363,16 @@ where .bind_pair(lefthand.clone(), righthand.clone()) } - fn find_generalisations( - &self, + fn find_generalisations<'a>( + &'a self, ast: &GenericSyntaxTree, - ) -> HashSet { - let mut generalisations = HashSet::::new(); - if let Some((l, r)) = ast.get_expansion() { - if let Some(c) = l.get_concept() { - generalisations.extend( - self.snap_shot - .read_concept(self.delta.as_ref(), c) - .iter_composition_ids(Hand::Left), - ); - } - if let Some(c) = r.get_concept() { - generalisations.extend( - self.snap_shot - .read_concept(self.delta.as_ref(), c) - .iter_composition_ids(Hand::Right), - ); - } - self.find_generalisations(&l).iter().for_each(|g| { - generalisations.extend( - self.snap_shot - .read_concept(self.delta.as_ref(), *g) - .iter_composition_ids(Hand::Left), - ); - }); - self.find_generalisations(&r).iter().for_each(|g| { - generalisations.extend( - self.snap_shot - .read_concept(self.delta.as_ref(), *g) - .iter_composition_ids(Hand::Right), - ); - }); - } - generalisations + ) -> Option + 'a> { + GeneralisationFinder::<'a, S, CCI, SR>::new( + ast, + self.snap_shot, + self.delta.clone(), + SR::share(DashSet::default()), + ) } /// Reduces the syntax as much as possible (returns the normal form syntax). @@ -417,6 +400,12 @@ where leftright: &SharedSyntax, right: &SharedSyntax, ) -> ReductionResult { + debug!( + "reduce_by_expanded_left_branch({}, {}, {})", + leftleft.as_ref(), + leftright.as_ref(), + right.as_ref() + ); let cct = self.concrete_type_of_ast(leftright)?; match cct { ConcreteConceptType::ExistsSuchThat @@ -449,6 +438,7 @@ where generalisation: &SharedSyntax, truths: impl Iterator, ) -> Option> { + debug!("find_example({})", generalisation.as_ref()); self.find_examples(generalisation.clone(), truths).next() } @@ -457,6 +447,10 @@ where &self, ast_to_reduce: &SharedSyntax, ) -> ReductionResult { + debug!( + "find_examples_of_inferred_reduction({})", + ast_to_reduce.as_ref() + ); let implication_id = self.concrete_concept_id(ConcreteConceptType::Implication)?; let reduction_operator = @@ -483,7 +477,7 @@ where .share(); let cache = SR::share(ReductionCache::::default()); let mut spawned_context_search = - self.spawn(&cache, D::from_nested(spawned_delta)); + self.spawn(&cache, SR::share(spawned_delta)); if let Some(concept) = ast_to_reduce.get_concept() { spawned_context_search.concept_inferring.insert(concept); } @@ -567,6 +561,11 @@ where }) }) }); + for item in spawned_context_search.caches.reductions.head.as_ref() { + if let Some(c) = item.key().concept { + self.caches.insert_reduction(&self.to_ast(&c), item.value()); + } + } result } @@ -575,6 +574,7 @@ where generalisation: SharedSyntax, equivalence_set: impl Iterator + 'a, /* All concepts that are equal to generalisation */ ) -> impl Iterator> + 'a { + debug!("find_examples({})", generalisation.as_ref()); let iterator: Box>>; if let Some((left, right)) = generalisation.get_expansion() { iterator = Box::new(self.find_examples_of_branched_generalisation( @@ -714,7 +714,7 @@ where }, (true, false) => Box::new( self.find_examples_of_half_generalisation( - left.clone(), + &left, right.clone(), equivalence_set, Hand::Right, @@ -723,7 +723,7 @@ where ), (false, true) => Box::new( self.find_examples_of_half_generalisation( - right.clone(), + &right, left.clone(), equivalence_set, Hand::Left, @@ -737,53 +737,89 @@ where fn find_examples_of_half_generalisation<'a>( &'a self, - generalised_part: SharedSyntax, + generalised_part: &SharedSyntax, non_generalised_part: SharedSyntax, mut equivalence_set_of_composition: impl Iterator + 'a, non_generalised_hand: Hand, ) -> Option> { - let non_generalised_part_clone = non_generalised_part.clone(); - let generalised_part_clone = generalised_part; + debug!("find_examples_of_half_generalisation({}, {}, {non_generalised_hand:?})", generalised_part.as_ref(), non_generalised_part.as_ref()); // TODO try to test if this needs to be a flat_map call equivalence_set_of_composition.find_map(move |equivalent_concept_id| { - let equivalent_concept = self - .snap_shot - .read_concept(self.delta.as_ref(), equivalent_concept_id); - let (left, right) = equivalent_concept.get_composition()?; - let (equivalent_non_generalised_hand, equivalent_generalised_hand) = match non_generalised_hand { + self.find_example_of_half_generalisation( + generalised_part, + &non_generalised_part, + equivalent_concept_id, + non_generalised_hand, + |example_hand| { + // TODO handle case when a concept implicitly reduces to `non_generalised_hand` + let equivalence_set = iter::once(example_hand); + let non_generalised_hand_concept = self + .snap_shot + .read_concept(self.delta.as_ref(), example_hand); + self.find_example( + generalised_part, + equivalence_set.chain( + non_generalised_hand_concept + .find_what_reduces_to_it(), + ), + ) + }, + ) + }) + } + + fn find_example_of_half_generalisation( + &self, + generalised_part_clone: &SharedSyntax, + non_generalised_part: &SharedSyntax, + equivalent_concept_id: S::ConceptId, + non_generalised_hand: Hand, + or_else: impl FnOnce(S::ConceptId) -> Option>, + ) -> Option> { + // TODO cache this calculation + let equivalent_concept = self + .snap_shot + .read_concept(self.delta.as_ref(), equivalent_concept_id); + let (left, right) = equivalent_concept.get_composition()?; + let (equivalent_non_generalised_hand, equivalent_generalised_hand) = + match non_generalised_hand { Hand::Left => (left, right), - Hand::Right => (right, left) + Hand::Right => (right, left), }; - if Some(equivalent_non_generalised_hand) != non_generalised_part_clone.get_concept() { - if self.snap_shot.read_concept(self.delta.as_ref(), equivalent_non_generalised_hand).free_variable() { - return self.find_example(&generalised_part_clone, iter::once(equivalent_generalised_hand)).and_then(|subs| { + if Some(equivalent_non_generalised_hand) + != non_generalised_part.get_concept() + { + if self + .snap_shot + .read_concept( + self.delta.as_ref(), + equivalent_non_generalised_hand, + ) + .free_variable() + { + return self.find_example(generalised_part_clone, iter::once(equivalent_generalised_hand)).and_then(|subs| { // Could have a more efficient method for this - subs.consistent_merge(ExampleSubstitutions{example: hashmap!{equivalent_non_generalised_hand => non_generalised_part_clone.clone()}, ..Default::default()}) - }) - } - return None; + subs.consistent_merge(ExampleSubstitutions{example: hashmap!{equivalent_non_generalised_hand => non_generalised_part.clone()}, ..Default::default()}) + }); } - self.find_example(&generalised_part_clone, iter::once(equivalent_generalised_hand)).or_else(|| { - let non_generalised_id = non_generalised_part.get_concept()?; - let example_hand = match non_generalised_hand { - Hand::Left => (left == non_generalised_id).then_some(right)?, - Hand::Right => (right == non_generalised_id).then_some(left)?, - }; - let example_hand_syntax = self.to_ast(&example_hand); - GenericSyntaxTree::::check_example( - &example_hand_syntax, - &generalised_part_clone, - ) - .or_else(|| { - // TODO handle case when a concept implicitly reduces to `non_generalised_hand` - let equivalence_set = iter::once(example_hand); - let non_generalised_hand_concept = self - .snap_shot - .read_concept(self.delta.as_ref(), example_hand); - self.find_example(&generalised_part_clone, equivalence_set.chain(non_generalised_hand_concept - .find_what_reduces_to_it())) - }) - }) + return None; + } + self.find_example( + generalised_part_clone, + iter::once(equivalent_generalised_hand), + ) + .or_else(|| { + let non_generalised_id = non_generalised_part.get_concept()?; + let example_hand = match non_generalised_hand { + Hand::Left => (left == non_generalised_id).then_some(right)?, + Hand::Right => (right == non_generalised_id).then_some(left)?, + }; + let example_hand_syntax = self.to_ast(&example_hand); + GenericSyntaxTree::::check_example( + &example_hand_syntax, + generalised_part_clone, + ) + .or_else(|| or_else(example_hand)) }) } @@ -794,6 +830,12 @@ where rightleft: &SharedSyntax, rightright: &SharedSyntax, ) -> ReductionResult { + debug!( + "reduce_by_expanded_right_branch({}, {}, {})", + left.as_ref(), + rightleft.as_ref(), + rightright.as_ref() + ); let cct = self.concrete_type_of_ast(rightleft)?; match cct { ConcreteConceptType::GreaterThan => { @@ -1087,7 +1129,7 @@ where pub fn spawn<'b, 'c>( &'b self, cache: &'c SR::Share>, - delta: D, + delta: SR::Share>, ) -> Self { ContextSearch::<'s, 'v> { concept_inferring: self.concept_inferring.clone(), @@ -1264,6 +1306,147 @@ where } } +struct GeneralisationFinder< + 'a, + S: SnapShotReader, + CI: ConceptId + 'static, + SR: SharedReference, +> { + snap_shot: &'a S, + generalisations: SR::Share>, + delta: SR::Share>, + concepts_used: bool, + composition_id_iter: Box>, + left_syntax: SR::Share>, + right_syntax: SR::Share>, + left_finder: Option>, + right_finder: Option>, +} + +impl< + 'a, + S: SnapShotReader, + CI: ConceptId + 'static, + SR: SharedReference, + > GeneralisationFinder<'a, S, CI, SR> +{ + fn new( + ast: &GenericSyntaxTree, + snap_shot: &'a S, + delta: SR::Share>, + generalisations: SR::Share>, + ) -> Option { + ast.get_expansion().map(move |(l, r)| { + let left_finder = GeneralisationFinder::new( + l.as_ref(), + snap_shot, + delta.clone(), + generalisations.clone(), + ) + .map(Box::new); + let right_finder = GeneralisationFinder::new( + r.as_ref(), + snap_shot, + delta.clone(), + generalisations.clone(), + ) + .map(Box::new); + Self { + generalisations, + snap_shot, + delta, + composition_id_iter: Box::new(empty()), + left_syntax: l, + right_syntax: r, + left_finder, + right_finder, + concepts_used: false, + } + }) + } +} + +impl< + 'a, + S: SnapShotReader, + CI: ConceptId + 'static, + SR: SharedReference, + > Iterator for GeneralisationFinder<'a, S, CI, SR> +{ + type Item = CI; + + fn next(&mut self) -> Option { + loop { + for id in self.composition_id_iter.by_ref() { + if self.generalisations.insert(id) { + return Some(id); + } + } + + // Need to replenish composition_id_iter + self.composition_id_iter = match ( + if self.concepts_used { + None + } else { + self.left_syntax + .get_concept() + .map(|c| { + self.snap_shot.read_concept(self.delta.as_ref(), c) + }) + .map(|l| l.into_iter_composition_ids(Hand::Left)) + }, + if self.concepts_used { + None + } else { + self.right_syntax + .get_concept() + .map(|c| { + self.snap_shot.read_concept(self.delta.as_ref(), c) + }) + .map(|r| r.into_iter_composition_ids(Hand::Right)) + }, + ) { + (Some(iter), None) | (None, Some(iter)) => { + self.concepts_used = true; + Box::new(iter) + }, + (Some(l_iter), Some(r_iter)) => { + self.concepts_used = true; + Box::new(l_iter.chain(r_iter)) + }, + (None, None) => { + self.concepts_used = true; + match ( + self.left_finder.as_deref_mut().and_then(|finder| { + let g = finder.next()?; + + let concept = self + .snap_shot + .read_concept(self.delta.as_ref(), g); + Some(concept.into_iter_composition_ids(Hand::Left)) + }), + self.right_finder.as_mut().and_then(|finder| { + finder.next().map(|g| { + self.snap_shot + .read_concept(self.delta.as_ref(), g) + .into_iter_composition_ids(Hand::Right) + }) + }), + ) { + (None, None) => return None, + (Some(iter), None) | (None, Some(iter)) => { + Box::new(iter) + }, + (Some(l_iter), Some(r_iter)) => { + Box::new(l_iter.chain(r_iter)) + }, + } + }, + }; + } + } +} + #[derive(PartialEq, Debug, Eq)] pub enum Comparison { GreaterThan, @@ -1286,17 +1469,11 @@ pub enum ComparisonReason { impl Eq for ComparisonReason {} -impl<'c, 's, 'v, S, SDCD, D, CCI: ConceptId, SR: SharedReference> - From> - for ContextSearch<'s, 'v, S, SDCD, D, CCI, SR> +impl<'c, 's, 'v, S, CCI: ConceptId, SR: SharedReference> + From> + for ContextSearch<'s, 'v, S, CCI, SR> where - S: SnapShotReader + Sync + std::fmt::Debug, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: AsRef> - + SharedDelta>, + S: SnapShotReader + Sync + std::fmt::Debug, { fn from( ContextReferences { @@ -1304,7 +1481,7 @@ where delta, cache, bound_variable_syntax, - }: ContextReferences<'c, 's, 'v, S, D, SR, CCI>, + }: ContextReferences<'c, 's, 'v, S, SR, CCI>, ) -> Self { Self { concept_inferring: HashSet::default(), @@ -1320,17 +1497,10 @@ where } } -pub struct ContextReferences< - 'c, - 's, - 'v, - S, - D, - SR: SharedReference, - CCI: ConceptId, -> { +pub struct ContextReferences<'c, 's, 'v, S, SR: SharedReference, CCI: ConceptId> +{ pub snap_shot: &'s S, - pub delta: D, + pub delta: SR::Share>, pub cache: &'c GenericCache, pub bound_variable_syntax: &'v HashSet>, } diff --git a/zia/src/context_search_test/basic_comparison.rs b/zia/src/context_search_test/basic_comparison.rs index 2cf3385a..c9574027 100644 --- a/zia/src/context_search_test/basic_comparison.rs +++ b/zia/src/context_search_test/basic_comparison.rs @@ -4,10 +4,7 @@ use crate::{ context_search::{Comparison, ComparisonReason, ContextReferences}, context_search_test::ReductionReason, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -15,17 +12,12 @@ use std::collections::HashMap; #[test] fn basic_comparison() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/basic_composition.rs b/zia/src/context_search_test/basic_composition.rs index 90580e43..691e2f02 100644 --- a/zia/src/context_search_test/basic_composition.rs +++ b/zia/src/context_search_test/basic_composition.rs @@ -4,10 +4,7 @@ use crate::{ context_delta::NestedDelta, context_search::ContextReferences, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -15,17 +12,12 @@ use std::collections::HashMap; #[test] fn basic_composition() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/basic_existence.rs b/zia/src/context_search_test/basic_existence.rs index f6eaa50d..9ce97d45 100644 --- a/zia/src/context_search_test/basic_existence.rs +++ b/zia/src/context_search_test/basic_existence.rs @@ -5,10 +5,7 @@ use crate::{ context_search::ContextReferences, context_search_test::ReductionReason, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -16,18 +13,13 @@ use std::collections::HashMap; #[test] fn basic_existence() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let variable_syntax = Syntax::from("_x_").share(); let bound_variables = hashset! {variable_syntax.key()}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/basic_inference.rs b/zia/src/context_search_test/basic_inference.rs index bcf499c7..783eda5f 100644 --- a/zia/src/context_search_test/basic_inference.rs +++ b/zia/src/context_search_test/basic_inference.rs @@ -5,10 +5,7 @@ use crate::{ context_search::ContextReferences, context_search_test::ReductionReason, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -16,17 +13,12 @@ use std::collections::HashMap; #[test] fn basic_inference() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/basic_reduction.rs b/zia/src/context_search_test/basic_reduction.rs index 4e0fcc71..46c5b8db 100644 --- a/zia/src/context_search_test/basic_reduction.rs +++ b/zia/src/context_search_test/basic_reduction.rs @@ -5,10 +5,7 @@ use crate::{ context_search::ContextReferences, context_search_test::ReductionReason, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -16,17 +13,12 @@ use std::collections::HashMap; #[test] fn basic_reduction() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/basic_rule.rs b/zia/src/context_search_test/basic_rule.rs index ea5823bd..99cb9cee 100644 --- a/zia/src/context_search_test/basic_rule.rs +++ b/zia/src/context_search_test/basic_rule.rs @@ -5,10 +5,7 @@ use crate::{ context_search::ContextReferences, context_search_test::ReductionReason, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -16,17 +13,12 @@ use std::collections::HashMap; #[test] fn basic_rule() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = NestedDelta::< - ConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - _, - >::default(); + let delta = NestedDelta::::default(); let cache = MTContextCache::default(); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/comparison_existence_implication_rule.rs b/zia/src/context_search_test/comparison_existence_implication_rule.rs index d185c8ec..ef2af877 100644 --- a/zia/src/context_search_test/comparison_existence_implication_rule.rs +++ b/zia/src/context_search_test/comparison_existence_implication_rule.rs @@ -4,10 +4,7 @@ use crate::{ context_search::{Comparison, ComparisonReason, ContextReferences}, context_search_test::ReductionReason, mock_snap_shot::MockSnapShot, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -15,13 +12,12 @@ use std::collections::HashMap; #[test] fn comparison_existence_implication_rule_test() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta<_>, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/existence_inference_rule.rs b/zia/src/context_search_test/existence_inference_rule.rs index 58350694..d5db8e8a 100644 --- a/zia/src/context_search_test/existence_inference_rule.rs +++ b/zia/src/context_search_test/existence_inference_rule.rs @@ -4,10 +4,7 @@ use crate::{ context_delta::NestedDelta, context_search::ContextReferences, mock_snap_shot::MockSnapShot, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use pretty_assertions::assert_eq; @@ -29,13 +26,12 @@ fn labels() -> HashMap { #[test] fn existence_inference_rule() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta<_>, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variables = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variables, }); diff --git a/zia/src/context_search_test/implied_reduction_via_implication_chain.rs b/zia/src/context_search_test/implied_reduction_via_implication_chain.rs index e78505c7..56efa6a6 100644 --- a/zia/src/context_search_test/implied_reduction_via_implication_chain.rs +++ b/zia/src/context_search_test/implied_reduction_via_implication_chain.rs @@ -2,11 +2,8 @@ use crate::{ concepts::{Concept, ConcreteConceptType, SpecificPart}, context_delta::NestedDelta, context_search::ContextReferences, - mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + mock_snap_shot::MockSnapShot, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use pretty_assertions::assert_eq; @@ -120,13 +117,12 @@ fn labels() -> HashMap { #[test] fn inference_rule() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variable_syntax = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variable_syntax, }); diff --git a/zia/src/context_search_test/inference_rule.rs b/zia/src/context_search_test/inference_rule.rs index 82428244..ac0b4f72 100644 --- a/zia/src/context_search_test/inference_rule.rs +++ b/zia/src/context_search_test/inference_rule.rs @@ -3,11 +3,8 @@ use crate::{ concepts::{Concept, ConcreteConceptType, SpecificPart}, context_delta::NestedDelta, context_search::ContextReferences, - mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + mock_snap_shot::MockSnapShot, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use pretty_assertions::assert_eq; @@ -75,13 +72,12 @@ fn labels() -> HashMap { #[test] fn inference_rule() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variable_syntax = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variable_syntax, }); diff --git a/zia/src/context_search_test/inferred_negation.rs b/zia/src/context_search_test/inferred_negation.rs index 2fffb210..f9c6dd1b 100644 --- a/zia/src/context_search_test/inferred_negation.rs +++ b/zia/src/context_search_test/inferred_negation.rs @@ -2,11 +2,8 @@ use crate::{ concepts::{Concept, ConcreteConceptType, SpecificPart}, context_delta::NestedDelta, context_search::ContextReferences, - mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + mock_snap_shot::MockSnapShot, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -56,13 +53,12 @@ fn labels() -> HashMap { #[test] fn inferred_negation() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variable_syntax = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variable_syntax, }); diff --git a/zia/src/context_search_test/nested_composition_rule.rs b/zia/src/context_search_test/nested_composition_rule.rs index 66aa64a9..2d153faa 100644 --- a/zia/src/context_search_test/nested_composition_rule.rs +++ b/zia/src/context_search_test/nested_composition_rule.rs @@ -4,11 +4,8 @@ use crate::{ context_delta::NestedDelta, context_search::ContextReferences, context_search_test::ReductionReason, - mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + mock_snap_shot::MockSnapShot, + multi_threaded::{MTContextCache, MTContextSearch}, }; use assert_matches::assert_matches; use maplit::{hashmap, hashset}; @@ -57,13 +54,12 @@ fn labels() -> HashMap { #[test] fn basic_rule() { let snapshot = MockSnapShot::new_test_case(&concepts(), &labels()); - let delta = - NestedDelta::<_, SharedDirectConceptDelta, _, _>::default(); + let delta = NestedDelta::<_, _>::default(); let cache = MTContextCache::default(); let bound_variable_syntax = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &snapshot, - delta: SharedContextDelta(delta.into()), + delta: delta.into(), cache: &cache, bound_variable_syntax: &bound_variable_syntax, }); diff --git a/zia/src/context_search_test/not.rs b/zia/src/context_search_test/not.rs index 365da3f8..200bdcf5 100644 --- a/zia/src/context_search_test/not.rs +++ b/zia/src/context_search_test/not.rs @@ -2,11 +2,8 @@ use crate::{ concepts::{Concept, ConcreteConceptType, SpecificPart}, context_delta::NestedDelta, context_search::ContextReferences, - mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - MTContextCache, MTContextSearch, SharedContextDelta, - SharedDirectConceptDelta, - }, + mock_snap_shot::MockSnapShot, + multi_threaded::{MTContextCache, MTContextSearch}, }; use maplit::{hashmap, hashset}; use std::collections::HashMap; @@ -74,13 +71,12 @@ fn labels() -> HashMap { #[test] fn not() { let context_cache = MTContextCache::default(); - let context_delta = - NestedDelta::<_, SharedDirectConceptDelta, _, _>::default(); + let context_delta = NestedDelta::<_, _>::default(); let context_snap_shot = MockSnapShot::new_test_case(&concepts(), &labels()); let bound_variable_syntax = hashset! {}; let context_search = MTContextSearch::from(ContextReferences { snap_shot: &context_snap_shot, - delta: SharedContextDelta(context_delta.into()), + delta: context_delta.into(), cache: &context_cache, bound_variable_syntax: &bound_variable_syntax, }); diff --git a/zia/src/context_snap_shot/concept.rs b/zia/src/context_snap_shot/concept.rs index 506fcfa0..f3596e3c 100644 --- a/zia/src/context_snap_shot/concept.rs +++ b/zia/src/context_snap_shot/concept.rs @@ -67,6 +67,7 @@ impl ConceptTrait for Mixed<'_> { = Box + 'b> where Self: 'b; + type OwnedIdPairIterator = Box>; fn id(&self) -> Self::Id { match self { @@ -325,4 +326,33 @@ impl ConceptTrait for Mixed<'_> { Self::Uncommitted(c) => c.get_concrete_concept_type(), } } + + fn into_iter_hand_of(self, hand: Hand) -> Self::OwnedIdPairIterator { + match self { + Self::PreviouslyCommitted { + original_concept, + changes, + .. + } => Box::new( + original_concept + .iter_hand_of(hand) + .filter_map(move |(o, c)| { + let o = o.into(); + match match hand { + Hand::Left => &changes.lefthand_of, + Hand::Right => &changes.righthand_of, + } + .get(&o) + { + None => Some((o, c.into())), + Some(None) => None, + Some(Some(c)) => Some((o, *c)), + } + }) + .collect::>() + .into_iter(), + ), + Self::Uncommitted(c) => Box::new(c.into_iter_hand_of(hand)), + } + } } diff --git a/zia/src/context_snap_shot/mod.rs b/zia/src/context_snap_shot/mod.rs index 9577551f..ef8ea580 100644 --- a/zia/src/context_snap_shot/mod.rs +++ b/zia/src/context_snap_shot/mod.rs @@ -27,7 +27,7 @@ use crate::{ context_delta, context_delta::{ Composition, ConceptDelta, DirectConceptDelta, NestedDelta, - NewConceptDelta, NewDirectConceptDelta, SharedDelta, ValueChange, + NewConceptDelta, NewDirectConceptDelta, ValueChange, }, delta::Apply, nester::SharedReference, @@ -248,17 +248,9 @@ impl ContextSnapShot { self.string_map.remove(string).expect("No string to remove!"); } - fn get_string_concept< - SDCD: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta< - NestedDelta = NestedDelta, - >, - >( + fn get_string_concept( &self, - delta: &NestedDelta, + delta: &NestedDelta, s: &str, ) -> Option { delta.get_string(s).map_or_else( @@ -292,15 +284,9 @@ impl ContextSnapShot { ) } - fn get_labellee< - SDCD: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta>, - >( + fn get_labellee( &self, - delta: &NestedDelta, + delta: &NestedDelta, c: ConceptId, ) -> Option { let concept = self.read_concept(delta, c); @@ -326,13 +312,7 @@ impl ContextSnapShot { } } -impl SnapShotReader for ContextSnapShot -where - SDCD: Clone - + AsRef> - + From> - + Debug, -{ +impl SnapShotReader for ContextSnapShot { type CommittedConceptId = Committed; type ConceptId = ConceptId; type MixedConcept<'a> @@ -340,11 +320,9 @@ where where SR: 'a; - fn concept_from_label< - D: SharedDelta>, - >( + fn concept_from_label( &self, - delta: &NestedDelta, + delta: &NestedDelta, s: &str, ) -> Option { self.get_string_concept(delta, s) @@ -359,11 +337,9 @@ where } } - fn get_label< - D: SharedDelta>, - >( + fn get_label( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> Option { self.get_concept_of_label(delta, concept).map_or_else( @@ -379,13 +355,9 @@ where ) } - fn concrete_concept_id< - D: SharedDelta< - NestedDelta = NestedDelta, - >, - >( + fn concrete_concept_id( &self, - delta: &NestedDelta, + delta: &NestedDelta, cc: ConcreteConceptType, ) -> Option { let mut id = None; @@ -415,23 +387,12 @@ where } } -impl Apply for ContextSnapShot +impl Apply for ContextSnapShot where - SDCD: Clone - + AsRef> - + From> - + Debug, Uncommitted: TryFrom, { #[allow(clippy::too_many_lines)] - fn apply< - D: SharedDelta< - NestedDelta = NestedDelta, - >, - >( - &mut self, - delta: NestedDelta, - ) { + fn apply(&mut self, delta: NestedDelta) { debug_assert!(self.previously_uncommitted_concepts.is_empty()); for (concept_id, concept_delta) in delta.concepts_to_apply_in_order() { match concept_delta.as_ref() { diff --git a/zia/src/context_test/mod.rs b/zia/src/context_test/mod.rs index 4c45bdec..f546f55b 100644 --- a/zia/src/context_test/mod.rs +++ b/zia/src/context_test/mod.rs @@ -4,17 +4,9 @@ mod infered_precedence; use crate::{ context::Context as GenericContext, mock_snap_shot::{ConceptId, MockSnapShot}, - multi_threaded::{ - ArcFamily, MTSyntaxTree, SharedContextDelta, SharedDirectConceptDelta, - }, + multi_threaded::{ArcFamily, MTSyntaxTree}, }; -pub type Context = GenericContext< - MockSnapShot, - SharedDirectConceptDelta, - SharedContextDelta, - ConceptId, - ArcFamily, ->; +pub type Context = GenericContext; type Syntax = MTSyntaxTree; diff --git a/zia/src/context_updater.rs b/zia/src/context_updater.rs index 667a1fb0..9a626e4f 100644 --- a/zia/src/context_updater.rs +++ b/zia/src/context_updater.rs @@ -5,7 +5,7 @@ use crate::{ context_cache::GenericCache, context_delta::{ Composition, DirectConceptDelta, NestedDelta, NewConceptDelta, - SharedDelta, ValueAndTypeChange, ValueChange, + ValueAndTypeChange, ValueChange, }, errors::ZiaResult, nester::SharedReference, @@ -14,35 +14,13 @@ use crate::{ ZiaError, }; -use std::{fmt::Debug, marker::PhantomData}; - -pub struct ContextUpdater< - 'a, - S: Reader, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta>, - SR: SharedReference, -> { +pub struct ContextUpdater<'a, S: Reader, SR: SharedReference> { pub cache: &'a mut GenericCache, - pub delta: &'a mut NestedDelta, + pub delta: &'a mut NestedDelta, pub snap_shot: &'a S, - pub phantom: PhantomData, - pub phantom2: PhantomData, } -impl< - S: Reader, - SDCD: Clone - + AsRef> - + From> - + Debug, - D: SharedDelta>, - SR: SharedReference, - > ContextUpdater<'_, S, SDCD, D, SR> -{ +impl, SR: SharedReference> ContextUpdater<'_, S, SR> { pub fn redefine_composition( &mut self, concept: &S::ConceptId, diff --git a/zia/src/delta.rs b/zia/src/delta.rs index 2161f336..14006911 100644 --- a/zia/src/delta.rs +++ b/zia/src/delta.rs @@ -1,9 +1,6 @@ use crate::{ - context_delta::{DirectConceptDelta, NestedDelta, SharedDelta}, - nester::SharedReference, - snap_shot::Reader, + context_delta::NestedDelta, nester::SharedReference, snap_shot::Reader, }; -use std::fmt::Debug; // Library for the Zia programming language. // Copyright (C) 2018 to 2019 Charles Johnson // @@ -20,17 +17,6 @@ use std::fmt::Debug; // You should have received a copy of the GNU General Public License // along with this program. If not, see . -pub trait Apply: Reader -where - SDCD: Clone - + AsRef> - + From> - + Debug, -{ - fn apply< - D: SharedDelta>, - >( - &mut self, - _: NestedDelta, - ); +pub trait Apply: Reader { + fn apply(&mut self, _: NestedDelta); } diff --git a/zia/src/mixed_concept.rs b/zia/src/mixed_concept.rs index 8efbb824..bb3899d7 100644 --- a/zia/src/mixed_concept.rs +++ b/zia/src/mixed_concept.rs @@ -3,7 +3,10 @@ use std::{ hash::Hash, }; -pub trait ConceptId: Clone + Copy + Debug + Display + Eq + Hash {} +pub trait ConceptId: + Clone + Copy + Debug + Display + Eq + Hash + 'static +{ +} pub trait MixedConcept: ConceptId { fn uncommitted(id: usize) -> Self; } diff --git a/zia/src/mock_snap_shot.rs b/zia/src/mock_snap_shot.rs index 53054e37..74c0cf91 100644 --- a/zia/src/mock_snap_shot.rs +++ b/zia/src/mock_snap_shot.rs @@ -1,8 +1,6 @@ use crate::{ concepts::{Concept, ConceptTrait, ConcreteConceptType}, - context_delta::{ - DirectConceptDelta, NestedDelta, SharedDelta, ValueChange, - }, + context_delta::{NestedDelta, ValueChange}, context_search_test::check_order, delta::Apply, mixed_concept::MixedConcept, @@ -14,7 +12,6 @@ use std::{ collections::HashMap, convert::TryFrom, fmt::{Debug, Display}, - sync::Arc, }; #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)] @@ -91,28 +88,10 @@ impl MockSnapShot { } } -impl Apply>, ArcFamily> for MockSnapShot { - fn apply< - D: SharedDelta< - NestedDelta = NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, - >, - >( - &mut self, - _: NestedDelta< - ConceptId, - Arc>, - D, - ArcFamily, - >, - ) { - } +impl Apply for MockSnapShot { + fn apply(&mut self, _: NestedDelta) {} } -impl Reader>, ArcFamily> for MockSnapShot { +impl Reader for MockSnapShot { type CommittedConceptId = usize; type ConceptId = ConceptId; type MixedConcept<'a> = Concept; @@ -129,23 +108,9 @@ impl Reader>, ArcFamily> for MockSnapShot { } } - fn get_label< - D: SharedDelta< - NestedDelta = NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, - >, - >( + fn get_label( &self, - delta: &NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, + delta: &NestedDelta, concept_id: Self::ConceptId, ) -> Option { let mut iter = delta.iter_string(); @@ -157,23 +122,9 @@ impl Reader>, ArcFamily> for MockSnapShot { self.concept_labels.get_by_left(&concept_id).map(|s| (*s).to_string()) } - fn concept_from_label< - D: SharedDelta< - NestedDelta = NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, - >, - >( + fn concept_from_label( &self, - delta: &NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, + delta: &NestedDelta, s: &str, ) -> Option { if let Some(ValueChange::Create(concept_id)) = delta.get_string(s) { @@ -182,45 +133,17 @@ impl Reader>, ArcFamily> for MockSnapShot { self.concept_labels.get_by_right(&s).copied() } - fn concrete_concept_id< - D: SharedDelta< - NestedDelta = NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, - >, - >( + fn concrete_concept_id( &self, - _: &NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, + _: &NestedDelta, cc: ConcreteConceptType, ) -> Option { self.concrete_concepts.get_by_right(&cc).copied() } - fn concrete_concept_type< - D: SharedDelta< - NestedDelta = NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, - >, - >( + fn concrete_concept_type( &self, - _: &NestedDelta< - Self::ConceptId, - Arc>, - D, - ArcFamily, - >, + _: &NestedDelta, concept_id: Self::ConceptId, ) -> Option { self.concrete_concepts.get_by_left(&concept_id).copied() diff --git a/zia/src/multi_threaded.rs b/zia/src/multi_threaded.rs index 29bcaa24..af83301e 100644 --- a/zia/src/multi_threaded.rs +++ b/zia/src/multi_threaded.rs @@ -2,10 +2,8 @@ use crate::{ ast::GenericSyntaxTree, context::Context as GenericContext, context_cache::GenericCache, - context_delta::{DirectConceptDelta, NestedDelta, SharedDelta}, context_search::ContextSearch, context_snap_shot::{ConceptId as ContextConceptId, ContextSnapShot}, - mixed_concept::ConceptId, nester::SharedReference, reduction_reason::ReductionReason, variable_mask_list::VariableMaskList, @@ -33,84 +31,17 @@ pub type MTContextCache = GenericCache; pub type MTVariableMaskList = VariableMaskList; pub type MTReductionReason = ReductionReason; -pub type Context = GenericContext< - ContextSnapShot, - SharedDirectConceptDelta, - SharedContextDelta, - ContextConceptId, - ArcFamily, ->; +pub type Context = + GenericContext, ContextConceptId, ArcFamily>; -pub type MTContextSearch<'s, 'v, S, CCI> = ContextSearch< - 's, - 'v, - S, - SharedDirectConceptDelta, - SharedContextDelta, - CCI, - ArcFamily, ->; +pub type MTContextSearch<'s, 'v, S, CCI> = + ContextSearch<'s, 'v, S, CCI, ArcFamily>; // Saves having to construct a new `Context` each time. lazy_static! { - pub static ref NEW_CONTEXT: Context = Context::new().unwrap(); + pub static ref NEW_CONTEXT: Context = Context::new(); } -type MultiThreadedContextDelta = NestedDelta< - CCI, - SharedDirectConceptDelta, - SharedContextDelta, - ArcFamily, ->; - -#[derive(Debug)] -pub struct SharedContextDelta( - pub Arc>, -); - -impl Clone for SharedContextDelta { - fn clone(&self) -> Self { - Self(self.0.clone()) - } -} - -impl Default for SharedContextDelta { - fn default() -> Self { - Self(MultiThreadedContextDelta::default().into()) - } -} - -impl SharedDelta for SharedContextDelta { - type NestedDelta = MultiThreadedContextDelta; - - fn get_mut(&mut self) -> Option<&mut Self::NestedDelta> { - Arc::get_mut(&mut self.0) - } - - fn from_nested(nested: Self::NestedDelta) -> Self { - Self(nested.into()) - } - - fn into_nested(self) -> crate::errors::ZiaResult { - Arc::try_unwrap(self.0) - .map_err(|_| crate::ZiaError::MultiplePointersToDelta) - } - - fn strong_count(&self) -> usize { - Arc::strong_count(&self.0) - } -} - -impl AsRef> - for SharedContextDelta -{ - fn as_ref(&self) -> &MultiThreadedContextDelta { - self.0.as_ref() - } -} - -pub type SharedDirectConceptDelta = Arc>; - #[cfg(test)] mod tests { use crate::{nester::NestedSyntaxTree, ConceptKind}; @@ -119,7 +50,7 @@ mod tests { #[test] fn precendence_test() { - let ctx = Context::new().unwrap(); + let ctx = Context::new(); let lexeme = ctx.lex("(a b) c"); let nested_syntax = Context::nest(lexeme).unwrap(); assert_eq!( diff --git a/zia/src/reduction_reason.rs b/zia/src/reduction_reason.rs index b76a7edb..bcb3f619 100644 --- a/zia/src/reduction_reason.rs +++ b/zia/src/reduction_reason.rs @@ -149,7 +149,7 @@ impl Debug for ReductionReason { } } } -// TODO: implement more efficient way of comparing HashMaps with SharedSyntax values +/// Use `compare_syntax_maps` for comparison pub fn convert_to_syntax_keys< K: Eq + Hash + Clone, CI: ConceptId, @@ -160,16 +160,44 @@ pub fn convert_to_syntax_keys< h.iter().map(|(k, v)| (k.clone(), v.key())).collect() } -type PartialReductionReasonKeys = - HashMap, (SyntaxKey, ReductionReason)>; +pub fn compare_syntax_maps< + K: Eq + Hash + Clone, + CI: ConceptId, + SR: SharedReference, +>( + h1: &HashMap>, + h2: &HashMap>, +) -> bool { + if h2.len() != h1.len() { + return false; + } + for (k1, s1) in h1 { + match h2.get(k1) { + None => return false, + Some(s2) if s2.as_ref() != s1.as_ref() => return false, + _ => continue, + } + } + true +} -// TODO: implement more efficient way of comparing PartialReductionReasons -fn collect_to_syntax_keys( - h: &PartialReductionReasons, -) -> PartialReductionReasonKeys { - h.iter() - .map(|(k, (v1, v2))| (k.clone(), (v1.key(), v2.clone()))) - .collect::>() +fn compare( + h1: &PartialReductionReasons, + h2: &PartialReductionReasons, +) -> bool { + if h2.len() != h1.len() { + return false; + }; + for (k1, (s1, r1)) in h1 { + match h2.get(k1) { + None => return false, + Some((s2, r2)) if s2.as_ref() != s1.as_ref() || r2 != r1 => { + return false + }, + _ => continue, + } + } + true } impl PartialEq for ReductionReason { fn eq(&self, other: &Self) -> bool { @@ -184,7 +212,7 @@ impl PartialEq for ReductionReason { reason: r1, } => { matches!(other, Self::Rule{generalisation: g2, variable_mask: vm2, - reason:r2} if g1.key() == g2.key() && convert_to_syntax_keys::(vm1) == convert_to_syntax_keys::(vm2) && r1.as_ref() == r2.as_ref()) + reason:r2} if g1.key() == g2.key() && compare_syntax_maps::(vm1, vm2) && r1.as_ref() == r2.as_ref()) }, Self::Inference { implication: i1, @@ -196,13 +224,13 @@ impl PartialEq for ReductionReason { operator: o1, } => matches!(other, Self::Default { operator: o2 } if o1 == o2), Self::Partial(p1) => { - matches!(other, Self::Partial(p2) if collect_to_syntax_keys(p1) == collect_to_syntax_keys(p2)) + matches!(other, Self::Partial(p2) if compare(p1, p2)) }, Self::Existence { substitutions: s1, generalisation: g1, } => { - matches!(other, Self::Existence { substitutions: s2, generalisation: g2 } if convert_to_syntax_keys::, CI, SR>(s1)== convert_to_syntax_keys::, CI, SR>(s2) && g1.key() == g2.key()) + matches!(other, Self::Existence { substitutions: s2, generalisation: g2 } if compare_syntax_maps::, CI, SR>(s1, s2) && g1.key() == g2.key()) }, Self::Recursive { syntax: s1, diff --git a/zia/src/single_threaded.rs b/zia/src/single_threaded.rs index 9e6a189c..ae0b9972 100644 --- a/zia/src/single_threaded.rs +++ b/zia/src/single_threaded.rs @@ -1,8 +1,6 @@ use crate::{ context::Context as GenericContext, - context_delta::{DirectConceptDelta, NestedDelta, SharedDelta}, context_snap_shot::{ConceptId as ContextConceptId, ContextSnapShot}, - errors::ZiaResult, nester::SharedReference, }; use std::{fmt::Debug, rc::Rc}; @@ -21,49 +19,5 @@ impl SharedReference for RcFamily { } } -pub type Context = GenericContext< - ContextSnapShot, - SharedDirectConceptDelta, - SharedContextDelta, - ContextConceptId, - RcFamily, ->; - -type SingleThreadedContextDelta = NestedDelta< - ContextConceptId, - SharedDirectConceptDelta, - SharedContextDelta, - RcFamily, ->; - -#[derive(Clone, Default, Debug)] -pub struct SharedContextDelta(Rc); - -impl SharedDelta for SharedContextDelta { - type NestedDelta = SingleThreadedContextDelta; - - fn get_mut(&mut self) -> Option<&mut Self::NestedDelta> { - Rc::get_mut(&mut self.0) - } - - fn from_nested(nested: Self::NestedDelta) -> Self { - Self(nested.into()) - } - - fn into_nested(self) -> ZiaResult { - Rc::try_unwrap(self.0) - .map_err(|_| crate::ZiaError::MultiplePointersToDelta) - } - - fn strong_count(&self) -> usize { - Rc::strong_count(&self.0) - } -} - -impl AsRef for SharedContextDelta { - fn as_ref(&self) -> &SingleThreadedContextDelta { - self.0.as_ref() - } -} - -type SharedDirectConceptDelta = Rc>; +pub type Context = + GenericContext, ContextConceptId, RcFamily>; diff --git a/zia/src/snap_shot.rs b/zia/src/snap_shot.rs index 842abad5..a4db841e 100644 --- a/zia/src/snap_shot.rs +++ b/zia/src/snap_shot.rs @@ -3,7 +3,7 @@ use crate::{ concepts::{ConceptTrait, ConcreteConceptType, Hand}, context_delta::{ Composition, ConceptDelta, DirectConceptDelta, NestedDelta, - NewDirectConceptDelta, SharedDelta, ValueChange, + NewDirectConceptDelta, ValueChange, }, errors::{ZiaError, ZiaResult}, mixed_concept::MixedConcept, @@ -15,12 +15,8 @@ use std::{ hash::Hash, }; -pub trait Reader +pub trait Reader where - SDCD: Clone - + AsRef> - + From> - + Debug, Self::CommittedConceptId: TryFrom, Self::ConceptId: From, { @@ -39,12 +35,9 @@ where concept_id: Self::ConceptId, ) -> Option>; #[allow(clippy::too_many_lines)] - fn maybe_read_concept< - 'a, - D: SharedDelta>, - >( + fn maybe_read_concept<'a>( &'a self, - delta: &NestedDelta, + delta: &NestedDelta, id: Self::ConceptId, ) -> Option> { delta.get_concept(&id).and_then(|cds| { @@ -155,12 +148,9 @@ where concept }) } - fn read_concept< - 'a, - D: SharedDelta>, - >( + fn read_concept<'a>( &'a self, - delta: &NestedDelta, + delta: &NestedDelta, id: Self::ConceptId, ) -> Self::MixedConcept<'a> { self.maybe_read_concept(delta, id).unwrap_or_else(|| { @@ -168,12 +158,9 @@ where .unwrap_or_else(|| panic!("No concept with id = {id}")) }) } - fn concepts_from_composition< - 'a, - D: SharedDelta>, - >( + fn concepts_from_composition<'a>( &'a self, - delta: &NestedDelta, + delta: &NestedDelta, comp: Composition, ) -> [Self::MixedConcept<'a>; 2] { [ @@ -181,18 +168,14 @@ where self.read_concept(delta, comp.right_id), ] } - fn get_label< - D: SharedDelta>, - >( + fn get_label( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept_id: Self::ConceptId, ) -> Option; - fn ast_from_symbol< - D: SharedDelta>, - >( + fn ast_from_symbol( &self, - delta: &NestedDelta, + delta: &NestedDelta, s: &str, ) -> GenericSyntaxTree where @@ -206,11 +189,9 @@ where }, ) } - fn bind_concept_to_syntax< - D: SharedDelta>, - >( + fn bind_concept_to_syntax( &self, - delta: &NestedDelta, + delta: &NestedDelta, syntax: GenericSyntaxTree, concept: Self::ConceptId, ) -> GenericSyntaxTree { @@ -242,18 +223,14 @@ where ) } } - fn concept_from_label< - D: SharedDelta>, - >( + fn concept_from_label( &self, - delta: &NestedDelta, + delta: &NestedDelta, s: &str, ) -> Option; - fn get_reduction_of_composition< - D: SharedDelta>, - >( + fn get_reduction_of_composition( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> Self::ConceptId { self.read_concept(delta, concept) @@ -270,11 +247,9 @@ where }) .unwrap_or(concept) } - fn is_disconnected< - D: SharedDelta>, - >( + fn is_disconnected( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> bool { self.read_concept(delta, concept).get_reduction().is_none() @@ -291,11 +266,9 @@ where .next() .is_none() } - fn righthand_of_without_label_is_empty< - D: SharedDelta>, - >( + fn righthand_of_without_label_is_empty( &self, - delta: &NestedDelta, + delta: &NestedDelta, con: Self::ConceptId, ) -> bool { self.concrete_concept_id(delta, ConcreteConceptType::Label) @@ -305,22 +278,18 @@ where }) .is_none() } - fn get_normal_form< - D: SharedDelta>, - >( + fn get_normal_form( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> Option { self.read_concept(delta, concept) .get_reduction() .map(|n| self.get_normal_form(delta, n).unwrap_or(n)) } - fn get_concept_of_label< - D: SharedDelta>, - >( + fn get_concept_of_label( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> Option { let label_concept_id = @@ -329,11 +298,9 @@ where self.read_concept(delta, concept) .find_as_hand_in_composition_with(label_concept_id, Hand::Right) } - fn contains< - D: SharedDelta>, - >( + fn contains( &self, - delta: &NestedDelta, + delta: &NestedDelta, outer: Self::ConceptId, inner: Self::ConceptId, ) -> bool { @@ -348,11 +315,9 @@ where false } } - fn check_reductions< - D: SharedDelta>, - >( + fn check_reductions( &self, - delta: &NestedDelta, + delta: &NestedDelta, outer_concept: Self::ConceptId, inner_concept: Self::ConceptId, ) -> ZiaResult<()> { @@ -368,12 +333,9 @@ where }, ) } - fn get_reduction_or_reduction_of_composition< - 'a, - D: SharedDelta>, - >( + fn get_reduction_or_reduction_of_composition<'a>( &'a self, - delta: &NestedDelta, + delta: &NestedDelta, concept: Self::ConceptId, ) -> Self::MixedConcept<'a> { self.read_concept( @@ -383,29 +345,23 @@ where ), ) } - fn concrete_concept_id< - D: SharedDelta>, - >( + fn concrete_concept_id( &self, - delta: &NestedDelta, + delta: &NestedDelta, cc: ConcreteConceptType, ) -> Option; - fn maybe_concrete_concept_type< - D: SharedDelta>, - >( + fn maybe_concrete_concept_type( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept_id: Self::ConceptId, ) -> Option { self.maybe_read_concept(delta, concept_id) .and_then(|c| c.get_concrete_concept_type()) } - fn concrete_concept_type< - D: SharedDelta>, - >( + fn concrete_concept_type( &self, - delta: &NestedDelta, + delta: &NestedDelta, concept_id: Self::ConceptId, ) -> Option { self.read_concept(delta, concept_id).get_concrete_concept_type() diff --git a/zia/src/variable_mask_list.rs b/zia/src/variable_mask_list.rs index cace75bb..47adc19a 100644 --- a/zia/src/variable_mask_list.rs +++ b/zia/src/variable_mask_list.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, fmt::Debug}; use crate::{ context_cache::SharedSyntax, mixed_concept::ConceptId, - nester::SharedReference, reduction_reason::convert_to_syntax_keys, + nester::SharedReference, reduction_reason::compare_syntax_maps, }; #[derive(Clone)] @@ -16,8 +16,7 @@ impl PartialEq for VariableMaskList { fn eq(&self, other: &Self) -> bool { - convert_to_syntax_keys::(&self.head) - == convert_to_syntax_keys::(&other.head) + compare_syntax_maps::(&self.head, &other.head) && self.tail.as_ref().map(std::convert::AsRef::as_ref) == other.tail.as_ref().map(std::convert::AsRef::as_ref) } @@ -64,8 +63,7 @@ impl VariableMaskList { } pub fn contains(&self, node: &VariableMask) -> bool { - convert_to_syntax_keys::(&self.head) - == convert_to_syntax_keys::(node) + compare_syntax_maps::(&self.head, node) || self.tail.as_ref().is_some_and(|vml| vml.as_ref().contains(node)) }