#[macro_use]
extern crate slog;
extern crate slog_term;
mod adding;
mod ast;
mod concepts;
mod constants;
mod context;
mod delta;
mod errors;
mod logging;
mod reading;
mod removing;
mod translating;
mod writing;
pub use adding::ContextMaker;
use adding::{ConceptMaker, Container, ExecuteReduction, FindOrInsertDefinition, Labeller};
pub use ast::SyntaxTree;
use concepts::{AbstractPart, CommonPart, Concept};
use constants::{DEFINE, LABEL, LET, REDUCTION};
use context::Context as GenericContext;
pub use errors::ZiaError;
use errors::ZiaResult;
use logging::Logger;
use reading::{
DisplayJoint, FindWhatReducesToIt, GetDefinition, GetDefinitionOf, GetLabel, GetReduction,
MaybeConcept, MaybeString, MightExpand, Pair, SyntaxReader,
};
use removing::DefinitionDeleter;
use std::fmt::Debug;
use std::rc::Rc;
use translating::SyntaxConverter;
use writing::{
MakeReduceFrom, NoLongerReducesFrom, RemoveAsDefinitionOf, RemoveDefinition, RemoveReduction,
SetAsDefinitionOf, SetDefinition, SetReduction,
};
pub type Context = GenericContext<Concept>;
pub trait Execute<T>
where
Self: Call<T> + SyntaxConverter<T> + Logger,
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ GetDefinition
+ MaybeString
+ GetDefinitionOf
+ GetReduction
+ FindWhatReducesToIt
+ Debug,
Self::S: Container
+ Pair<Self::S>
+ Debug
+ Clone
+ From<(String, Option<usize>)>
+ DisplayJoint
+ PartialEq<Self::S>,
{
fn execute(&mut self, command: &str) -> String {
info!(self.logger(), "execute({})", command);
let ast = match self.ast_from_expression(command) {
Ok(a) => a,
Err(e) => return e.to_string(),
};
match self.call(&ast) {
Ok(s) => s,
Err(e) => e.to_string(),
}
}
}
impl<S, T> Execute<T> for S
where
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ GetDefinition
+ MaybeString
+ GetDefinitionOf
+ GetReduction
+ FindWhatReducesToIt
+ Debug,
S: Call<T> + SyntaxConverter<T> + Logger,
S::S: Container
+ Pair<S::S>
+ Clone
+ From<(String, Option<usize>)>
+ DisplayJoint
+ Debug
+ PartialEq<Self::S>,
{
}
impl FindOrInsertDefinition<Concept> for Context {
type A = AbstractPart;
}
impl Labeller<Concept> for Context {
type C = CommonPart;
}
impl ConceptMaker<Concept> for Context {
type S = SyntaxTree;
}
pub trait Call<T>
where
Self: Definer<T> + ExecuteReduction<T> + SyntaxReader<T> + Logger,
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ FindWhatReducesToIt
+ GetReduction
+ GetDefinition
+ GetDefinitionOf
+ MaybeString
+ Debug,
Self::S: Container
+ Pair<Self::S>
+ Clone
+ From<(String, Option<usize>)>
+ DisplayJoint
+ PartialEq<Self::S>
+ Debug,
{
fn call(&mut self, ast: &Rc<Self::S>) -> ZiaResult<String> {
info!(self.logger(), "call({})", ast.display_joint());
if let Some(c) = ast.get_concept() {
if let Some(s) = self.read_concept(&[], c).get_string() {
return Ok(s);
}
}
match ast.get_expansion() {
Some((ref left, ref right)) => {
let result = self.call_pair(left, right);
match result {
Err(ZiaError::CannotReduceFurther) => {
let result = self.try_reducing_then_call(ast);
match result {
Err(ZiaError::CannotReduceFurther) => Ok(self.contract_pair(left, right).to_string()),
_ => result,
}
}
_ => result,
}
},
None => {
let result = self.try_reducing_then_call(ast);
match result {
Err(ZiaError::CannotReduceFurther) => (),
_ => return result,
};
let result = self.try_expanding_then_call(ast);
match result {
Err(ZiaError::CannotExpandFurther) => Ok(ast.to_string()),
_ => result,
}
},
}
}
fn call_pair(&mut self, left: &Rc<Self::S>, right: &Rc<Self::S>) -> ZiaResult<String> {
info!(
self.logger(),
"call_pair({}, {})",
left.display_joint(),
right.display_joint()
);
if let Some(lc) = left.get_concept() {
if lc == LET {
if let Some((ref rightleft, ref rightright)) = right.get_expansion() {
return self.call_as_righthand(rightleft, rightright);
}
} else if lc == LABEL {
info!(self.logger(), "lefthand side is LABEL");
if let Some(rc) = right.get_concept() {
info!(self.logger(), "righthand side is concept number {}", rc);
if let Some(s) = self.get_label(rc) {
return Ok("'".to_string() + &s + "'");
}
}
return Ok("'".to_string() + &right.to_string() + "'");
}
}
match right.get_concept() {
Some(c) => match c {
REDUCTION => self.try_reducing_then_call(&left),
_ => self.reduce_and_call_pair(left, right),
},
None => self.reduce_and_call_pair(left, right),
}
}
fn reduce_and_call_pair(&mut self, left: &Rc<Self::S>, right: &Rc<Self::S>) -> ZiaResult<String> {
match (self.reduce(left), self.reduce(right)) {
(None, None) => Err(ZiaError::CannotReduceFurther),
(Some(rl), None) => self.call_pair(&rl, right),
(None, Some(rr)) => self.call_pair(left, &rr),
(Some(rl), Some(rr)) => self.call_pair(&rl, &rr),
}
}
fn reduce_label_of(&self, ast: &Rc<Self::S>) -> ZiaResult<String> {
if let Some((left, right)) = ast.get_expansion() {
if let Some(concept) = right.get_concept() {
if concept == REDUCTION {
return self.reduce_label_of(&match self.reduce(&left) {
None => left,
Some(reduction) => reduction,
});
}
if concept == DEFINE {
return Ok(self.expand(&left).to_string());
}
}
}
Ok(ast.to_string())
}
fn try_expanding_then_call(&mut self, ast: &Rc<Self::S>) -> ZiaResult<String> {
info!(
self.logger(),
"try_expanding_then_call({})",
ast.display_joint()
);
let expansion = &self.expand(ast);
if expansion != ast {
self.call(expansion)
} else {
Err(ZiaError::CannotExpandFurther)
}
}
fn try_reducing_then_call(&mut self, ast: &Rc<Self::S>) -> ZiaResult<String> {
info!(
self.logger(),
"try_reducing_then_call({})",
ast.display_joint()
);
let normal_form = &self.recursively_reduce(ast);
if normal_form != ast {
self.call(normal_form)
} else {
Err(ZiaError::CannotReduceFurther)
}
}
fn call_as_righthand(&mut self, left: &Self::S, right: &Self::S) -> ZiaResult<String> {
info!(
self.logger(),
"call_as_righthand({}, {})",
left.display_joint(),
right.display_joint()
);
match right.get_expansion() {
Some((ref rightleft, ref rightright)) => {
self.match_righthand_pair(left, rightleft, rightright)
}
None => Err(ZiaError::CannotExpandFurther),
}
}
fn match_righthand_pair(
&mut self,
left: &Self::S,
rightleft: &Self::S,
rightright: &Self::S,
) -> ZiaResult<String> {
info!(
self.logger(),
"match_righthand_pair({}, {}, {})",
left.display_joint(),
rightleft.display_joint(),
rightright.display_joint()
);
match rightleft.get_concept() {
Some(c) => match c {
REDUCTION => self.execute_reduction(left, rightright),
DEFINE => self.execute_definition(left, rightright),
_ => {
let rightleft_reduction = self.read_concept(&[], c).get_reduction();
if let Some(r) = rightleft_reduction {
let ast = self.to_ast::<Self::S>(r);
self.match_righthand_pair(left, &ast, rightright)
} else {
info!(
self.logger(),
"match_righthand_pair({}, {}, {}) -> Err(ZiaError::NotAProgram)",
left.display_joint(),
rightleft.display_joint(),
rightright.display_joint()
);
Err(ZiaError::CannotReduceFurther)
}
}
},
None => {
info!(
self.logger(),
"match_righthand_pair({}, {}, {}) -> Err(ZiaError::NotAProgram)",
left.display_joint(),
rightleft.display_joint(),
rightright.display_joint()
);
Err(ZiaError::UnusedSymbol)
}
}
}
}
impl<S, T> Call<T> for S
where
S: Definer<T> + ExecuteReduction<T> + SyntaxReader<T> + Logger,
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ FindWhatReducesToIt
+ GetReduction
+ GetDefinition
+ GetDefinitionOf
+ MaybeString
+ Debug,
S::S: Container
+ Pair<S::S>
+ Clone
+ Debug
+ From<(String, Option<usize>)>
+ DisplayJoint
+ PartialEq<Self::S>,
{
}
pub trait Definer<T>
where
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ FindWhatReducesToIt
+ GetReduction
+ GetDefinition
+ GetDefinitionOf
+ MaybeString
+ Debug,
Self: GetLabel<T> + ConceptMaker<T> + DefinitionDeleter<T>,
Self::S: Pair<Self::S> + Container,
{
fn execute_definition(&mut self, new: &Self::S, old: &Self::S) -> ZiaResult<String> {
info!(self.logger(), "execute_definition({}, {})", new, old);
if old.contains(new) {
Err(ZiaError::InfiniteDefinition)
} else {
try!(self.define(new, old));
Ok("".to_string())
}
}
fn define(&mut self, new: &Self::S, old: &Self::S) -> ZiaResult<()> {
if new.get_expansion().is_some() {
Err(ZiaError::BadDefinition)
} else {
match (new.get_concept(), old.get_concept(), old.get_expansion()) {
(_, None, None) => Err(ZiaError::RedundantRefactor),
(None, Some(b), None) => self.relabel(b, &new.to_string()),
(None, Some(b), Some(_)) => {
if self.get_label(b).is_none() {
self.label(b, &new.to_string())
} else {
self.relabel(b, &new.to_string())
}
}
(None, None, Some((ref left, ref right))) => {
try!(self.define_new_syntax(new.to_string(), left, right));
Ok(())
}
(Some(a), Some(b), None) => {
if a == b {
self.cleanly_delete_definition(a)
} else {
Err(ZiaError::DefinitionCollision)
}
}
(Some(a), Some(b), Some(_)) => {
if a == b {
Err(ZiaError::RedundantDefinition)
} else {
Err(ZiaError::DefinitionCollision)
}
}
(Some(a), None, Some((ref left, ref right))) => self.redefine(a, left, right),
}
}
}
fn redefine(&mut self, concept: usize, left: &Self::S, right: &Self::S) -> ZiaResult<()> {
if let Some((left_concept, right_concept)) =
self.read_concept(&[], concept).get_definition()
{
try!(self.relabel(left_concept, &left.to_string()));
self.relabel(right_concept, &right.to_string())
} else {
let left_concept = try!(self.concept_from_ast(left));
let right_concept = try!(self.concept_from_ast(right));
try!(self.insert_definition(concept, left_concept, right_concept));
Ok(())
}
}
fn relabel(&mut self, concept: usize, new_label: &str) -> ZiaResult<()> {
try!(self.unlabel(concept));
self.label(concept, new_label)
}
fn define_new_syntax(
&mut self,
syntax: String,
left: &Rc<Self::S>,
right: &Rc<Self::S>,
) -> ZiaResult<usize> {
let definition_concept =
if let (Some(l), Some(r)) = (left.get_concept(), right.get_concept()) {
self.find_definition(l, r)
} else {
None
};
let new_syntax_tree = Self::S::from_pair((syntax, definition_concept), left, right);
self.concept_from_ast(&new_syntax_tree)
}
}
impl<S, T> Definer<T> for S
where
T: From<String>
+ From<Self::C>
+ From<Self::A>
+ RemoveDefinition
+ RemoveAsDefinitionOf
+ SetReduction
+ MakeReduceFrom
+ RemoveReduction
+ NoLongerReducesFrom
+ SetDefinition
+ SetAsDefinitionOf
+ FindWhatReducesToIt
+ GetReduction
+ GetDefinition
+ GetDefinitionOf
+ MaybeString
+ Debug,
S: ConceptMaker<T> + GetLabel<T> + DefinitionDeleter<T>,
S::S: Pair<S::S> + Container,
{
}