forked from Orchid/orchid
transfer commit
This commit is contained in:
18
.editorconfig
Normal file
18
.editorconfig
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# EditorConfig is awesome: https://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
# Set default charset
|
||||||
|
[*.{rs,md,toml,orc,tex,bib}]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[Makefile]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
indent_styl = tab
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
mod foreign;
|
mod normalize;
|
||||||
// mod normalize;
|
|
||||||
mod partial_hash;
|
mod partial_hash;
|
||||||
mod reduction_tree;
|
mod reduction_tree;
|
||||||
mod apply_lambda;
|
mod apply_lambda;
|
||||||
mod syntax_eq;
|
mod syntax_eq;
|
||||||
pub use foreign::ExternFn;
|
|
||||||
pub use foreign::Atom;
|
|
||||||
@@ -95,3 +95,8 @@ fn direct_reductions(ex: Mrc<Expr>) -> impl Iterator<Item = Mrc<Expr>> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
*/
|
||||||
@@ -64,6 +64,12 @@ impl Context {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn unify_clauses(&mut self,
|
||||||
|
left: &Mrc<[Clause]>, right: &Mrc<[Clause]>, lambdas: LambdaMap
|
||||||
|
) -> Result<Product2<Clause>, UnifError> {
|
||||||
|
if left.len() != right.len() {return Err(UnifError::Conflict)}
|
||||||
|
}
|
||||||
|
|
||||||
fn unify_clause(&mut self,
|
fn unify_clause(&mut self,
|
||||||
left: &Clause, right: &Clause, lambdas: LambdaMap
|
left: &Clause, right: &Clause, lambdas: LambdaMap
|
||||||
) -> Result<Product2<Clause>, UnifError> {
|
) -> Result<Product2<Clause>, UnifError> {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
use std::env::current_dir;
|
use std::env::current_dir;
|
||||||
|
|
||||||
// mod executor;
|
mod executor;
|
||||||
mod parse;
|
mod parse;
|
||||||
mod project;
|
mod project;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|||||||
@@ -49,9 +49,9 @@ pub fn exprv(exprv: &[ast::Expr]) -> Result<typed::Expr, Error> {
|
|||||||
const NAMES_INLINE_COUNT:usize = 3;
|
const NAMES_INLINE_COUNT:usize = 3;
|
||||||
|
|
||||||
/// Recursive state of [exprv]
|
/// Recursive state of [exprv]
|
||||||
fn exprv_rec(
|
fn exprv_rec<'a>(
|
||||||
v: &[ast::Expr],
|
v: &'a [ast::Expr],
|
||||||
names: ProtoMap<&str, (u64, bool), NAMES_INLINE_COUNT>,
|
names: ProtoMap<&'a str, (u64, bool), NAMES_INLINE_COUNT>,
|
||||||
explicits: Option<&Stackframe<Mrc<typed::Expr>>>,
|
explicits: Option<&Stackframe<Mrc<typed::Expr>>>,
|
||||||
) -> Result<(typed::Expr, usize), Error> {
|
) -> Result<(typed::Expr, usize), Error> {
|
||||||
let (last, rest) = v.split_last().ok_or(Error::EmptyS)?;
|
let (last, rest) = v.split_last().ok_or(Error::EmptyS)?;
|
||||||
@@ -61,12 +61,12 @@ fn exprv_rec(
|
|||||||
"It is assumed that Explicit nodes can never have type annotations as the \
|
"It is assumed that Explicit nodes can never have type annotations as the \
|
||||||
wrapped expression node matches all trailing colons."
|
wrapped expression node matches all trailing colons."
|
||||||
);
|
);
|
||||||
let (x, _) = expr_rec(inner.as_ref(), names, None)?;
|
let (x, _) = expr_rec(inner.as_ref(), names.clone(), None)?;
|
||||||
let new_explicits = Some(&Stackframe::opush(explicits, Mrc::new(x)));
|
let new_explicits = Stackframe::opush(explicits, Mrc::new(x));
|
||||||
let (body, used_expls) = exprv_rec(rest, names, new_explicits)?;
|
let (body, used_expls) = exprv_rec(rest, names, Some(&new_explicits))?;
|
||||||
Ok((body, used_expls.saturating_sub(1)))
|
Ok((body, used_expls.saturating_sub(1)))
|
||||||
} else {
|
} else {
|
||||||
let (f, f_used_expls) = exprv_rec(rest, names, explicits)?;
|
let (f, f_used_expls) = exprv_rec(rest, names.clone(), explicits)?;
|
||||||
let x_explicits = Stackframe::opop(explicits, f_used_expls);
|
let x_explicits = Stackframe::opop(explicits, f_used_expls);
|
||||||
let (x, x_used_expls) = expr_rec(last, names, x_explicits)?;
|
let (x, x_used_expls) = expr_rec(last, names, x_explicits)?;
|
||||||
Ok((typed::Expr(
|
Ok((typed::Expr(
|
||||||
@@ -77,13 +77,13 @@ fn exprv_rec(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Recursive state of [expr]
|
/// Recursive state of [expr]
|
||||||
fn expr_rec(
|
fn expr_rec<'a>(
|
||||||
ast::Expr(val, typ): &ast::Expr,
|
ast::Expr(val, typ): &'a ast::Expr,
|
||||||
names: ProtoMap<&str, (u64, bool), NAMES_INLINE_COUNT>,
|
names: ProtoMap<&'a str, (u64, bool), NAMES_INLINE_COUNT>,
|
||||||
explicits: Option<&Stackframe<Mrc<typed::Expr>>> // known explicit values
|
explicits: Option<&Stackframe<Mrc<typed::Expr>>> // known explicit values
|
||||||
) -> Result<(typed::Expr, usize), Error> { // (output, used_explicits)
|
) -> Result<(typed::Expr, usize), Error> { // (output, used_explicits)
|
||||||
let typ: Vec<typed::Clause> = typ.iter()
|
let typ: Vec<typed::Clause> = typ.iter()
|
||||||
.map(|c| Ok(clause_rec(c, names, None)?.0))
|
.map(|c| Ok(clause_rec(c, names.clone(), None)?.0))
|
||||||
.collect::<Result<_, _>>()?;
|
.collect::<Result<_, _>>()?;
|
||||||
if let ast::Clause::S(paren, body) = val {
|
if let ast::Clause::S(paren, body) = val {
|
||||||
if *paren != '(' {return Err(Error::BadGroup(*paren))}
|
if *paren != '(' {return Err(Error::BadGroup(*paren))}
|
||||||
@@ -101,9 +101,9 @@ fn expr_rec(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Recursive state of [clause]
|
/// Recursive state of [clause]
|
||||||
fn clause_rec(
|
fn clause_rec<'a>(
|
||||||
cls: &ast::Clause,
|
cls: &'a ast::Clause,
|
||||||
names: ProtoMap<&str, (u64, bool), NAMES_INLINE_COUNT>,
|
mut names: ProtoMap<&'a str, (u64, bool), NAMES_INLINE_COUNT>,
|
||||||
mut explicits: Option<&Stackframe<Mrc<typed::Expr>>>
|
mut explicits: Option<&Stackframe<Mrc<typed::Expr>>>
|
||||||
) -> Result<(typed::Clause, usize), Error> {
|
) -> Result<(typed::Clause, usize), Error> {
|
||||||
match cls { // (\t:(@T. Pair T T). t \left.\right. left) @number -- this will fail
|
match cls { // (\t:(@T. Pair T T). t \left.\right. left) @number -- this will fail
|
||||||
@@ -121,7 +121,7 @@ fn clause_rec(
|
|||||||
explicits = rest_explicits;
|
explicits = rest_explicits;
|
||||||
// Convert the type
|
// Convert the type
|
||||||
let typ = if t.len() == 0 {mrc_empty_slice()} else {
|
let typ = if t.len() == 0 {mrc_empty_slice()} else {
|
||||||
let (typed::Expr(c, t), _) = exprv_rec(t.as_ref(), names, None)?;
|
let (typed::Expr(c, t), _) = exprv_rec(t.as_ref(), names.clone(), None)?;
|
||||||
if t.len() > 0 {return Err(Error::ExplicitBottomKind)}
|
if t.len() > 0 {return Err(Error::ExplicitBottomKind)}
|
||||||
else {one_mrc_slice(c)}
|
else {one_mrc_slice(c)}
|
||||||
};
|
};
|
||||||
@@ -143,7 +143,7 @@ fn clause_rec(
|
|||||||
let id = get_name();
|
let id = get_name();
|
||||||
// Convert the type
|
// Convert the type
|
||||||
let typ = if t.len() == 0 {mrc_empty_slice()} else {
|
let typ = if t.len() == 0 {mrc_empty_slice()} else {
|
||||||
let (typed::Expr(c, t), _) = exprv_rec(t.as_ref(), names, None)?;
|
let (typed::Expr(c, t), _) = exprv_rec(t.as_ref(), names.clone(), None)?;
|
||||||
if t.len() > 0 {return Err(Error::ExplicitBottomKind)}
|
if t.len() > 0 {return Err(Error::ExplicitBottomKind)}
|
||||||
else {one_mrc_slice(c)}
|
else {one_mrc_slice(c)}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -137,3 +137,5 @@ impl TryFrom<&ast::Clause> for Clause {
|
|||||||
ast_to_typed::clause(value)
|
ast_to_typed::clause(value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn count_references(id: u64, clause: &Clause)
|
||||||
@@ -25,7 +25,7 @@ pub trait Task {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_to_completion(&mut self) -> Self::Result {
|
fn run_to_completion(&mut self) -> Self::Result {
|
||||||
loop { if let TaskState::Complete(r) = self.run_once() {return r} }
|
loop { if let TaskState::Complete(r) = self.run_n_times(u64::MAX) {return r} }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boxed<'a>(self) -> TaskBox<'a, Self::Result> where Self: 'a + Sized { Box::new(self) }
|
fn boxed<'a>(self) -> TaskBox<'a, Self::Result> where Self: 'a + Sized { Box::new(self) }
|
||||||
|
|||||||
@@ -26,42 +26,65 @@ impl<T: Task, U: Task> TaskPair<T, U> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Task, U: Task> Task for TaskPair<T, U> {
|
/// The state machine logic, abstracted from the subtask handling system
|
||||||
type Result = (T::Result, U::Result);
|
macro_rules! main_logic {
|
||||||
|
($self:ident, $task:ident, $task_runner:expr) => {{
|
||||||
fn run_once(&mut self) -> TaskState<Self::Result> {
|
let TaskPair{ state, tally, l_nice, r_nice } = $self;
|
||||||
let TaskPair{ state, tally, l_nice, r_nice } = self;
|
|
||||||
let ret = process(state, |s| match s {
|
let ret = process(state, |s| match s {
|
||||||
TaskPairState::Empty => panic!("Generator completed and empty"),
|
TaskPairState::Empty => panic!("Generator completed and empty"),
|
||||||
TaskPairState::Left(mut l_task, r_res) => {
|
TaskPairState::Left(mut $task, r_res) => {
|
||||||
match l_task.run_once() {
|
match $task_runner {
|
||||||
TaskState::Complete(r) => (TaskPairState::Empty, TaskState::Complete((r, r_res))),
|
TaskState::Complete(r) => (TaskPairState::Empty, TaskState::Complete((r, r_res))),
|
||||||
TaskState::Yield => (TaskPairState::Left(l_task, r_res), TaskState::Yield),
|
TaskState::Yield => (TaskPairState::Left($task, r_res), TaskState::Yield),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TaskPairState::Right(l_res, mut r_task) => {
|
TaskPairState::Right(l_res, mut $task) => {
|
||||||
match r_task.run_once() {
|
match $task_runner {
|
||||||
TaskState::Complete(r) => (TaskPairState::Empty, TaskState::Complete((l_res, r))),
|
TaskState::Complete(r) => (TaskPairState::Empty, TaskState::Complete((l_res, r))),
|
||||||
TaskState::Yield => (TaskPairState::Right(l_res, r_task), TaskState::Yield),
|
TaskState::Yield => (TaskPairState::Right(l_res, $task), TaskState::Yield),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TaskPairState::Both(mut l_task, mut r_task) => {
|
TaskPairState::Both(l_task, r_task) => {
|
||||||
let state = if 0 <= *tally {
|
let state = if 0 <= *tally {
|
||||||
*tally -= *l_nice as Priority;
|
*tally -= *l_nice as Priority;
|
||||||
match l_task.run_once() {
|
let mut $task = l_task;
|
||||||
|
match $task_runner {
|
||||||
TaskState::Complete(r) => TaskPairState::Right(r, r_task),
|
TaskState::Complete(r) => TaskPairState::Right(r, r_task),
|
||||||
TaskState::Yield => TaskPairState::Both(l_task, r_task),
|
TaskState::Yield => TaskPairState::Both($task, r_task),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*tally += *r_nice as Priority;
|
*tally += *r_nice as Priority;
|
||||||
match r_task.run_once() {
|
let mut $task = r_task;
|
||||||
|
match $task_runner {
|
||||||
TaskState::Complete(r) => TaskPairState::Left(l_task, r),
|
TaskState::Complete(r) => TaskPairState::Left(l_task, r),
|
||||||
TaskState::Yield => TaskPairState::Both(l_task, r_task),
|
TaskState::Yield => TaskPairState::Both(l_task, $task),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
(state, TaskState::Yield)
|
(state, TaskState::Yield)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ret
|
ret
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Task, U: Task> Task for TaskPair<T, U> {
|
||||||
|
type Result = (T::Result, U::Result);
|
||||||
|
|
||||||
|
fn run_n_times(&mut self, mut count: u64) -> TaskState<Self::Result> {
|
||||||
|
loop {
|
||||||
|
if count == 0 {return TaskState::Yield}
|
||||||
|
match self.state {
|
||||||
|
TaskPairState::Left(..) | TaskPairState::Right(..) => {
|
||||||
|
return main_logic!(self, task, task.run_n_times(count));
|
||||||
|
}
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
if let r@TaskState::Complete(_) = self.run_once() {return r}
|
||||||
|
count -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_once(&mut self) -> TaskState<Self::Result> {
|
||||||
|
main_logic!(self, task, task.run_once())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::iter;
|
use std::{iter, mem};
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
|
||||||
@@ -36,8 +36,9 @@ impl<T: Task> TaskVec<T> {
|
|||||||
if self.task_heap.len() <= i {None}
|
if self.task_heap.len() <= i {None}
|
||||||
else {self.task_heap[i].as_mut()}
|
else {self.task_heap[i].as_mut()}
|
||||||
}
|
}
|
||||||
|
/// Returns the tally of the given record. Empty records always sink to the bottom
|
||||||
fn tally(&self, i: usize) -> Nice {
|
fn tally(&self, i: usize) -> Nice {
|
||||||
self.task_heap[i].as_ref().map(|e| e.tally).unwrap_or(0)
|
self.task_heap[i].as_ref().map(|e| e.tally).unwrap_or(Nice::MAX)
|
||||||
}
|
}
|
||||||
fn swap(&mut self, a: usize, b: usize) {
|
fn swap(&mut self, a: usize, b: usize) {
|
||||||
self.task_heap.swap(a, b);
|
self.task_heap.swap(a, b);
|
||||||
@@ -49,7 +50,7 @@ impl<T: Task> TaskVec<T> {
|
|||||||
fn normalize(&mut self) {
|
fn normalize(&mut self) {
|
||||||
let shrink_count = self.task_heap.iter().rev().take_while(|e| e.is_none()).count();
|
let shrink_count = self.task_heap.iter().rev().take_while(|e| e.is_none()).count();
|
||||||
let new_len = self.task_heap.len() - shrink_count;
|
let new_len = self.task_heap.len() - shrink_count;
|
||||||
self.task_heap.splice(0..new_len, iter::empty());
|
self.task_heap.splice(new_len.., iter::empty());
|
||||||
let head = self.entry_mut(0);
|
let head = self.entry_mut(0);
|
||||||
let offset = if let Some(e) = head {
|
let offset = if let Some(e) = head {
|
||||||
let offset = e.tally - 1;
|
let offset = e.tally - 1;
|
||||||
@@ -86,10 +87,43 @@ impl<T: Task> TaskVec<T> {
|
|||||||
self.swap(i, mchi);
|
self.swap(i, mchi);
|
||||||
self.sink(mchi);
|
self.sink(mchi);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn take_results(&mut self) -> Vec<T::Result> {
|
||||||
|
let mut swap = Vec::new();
|
||||||
|
mem::swap(&mut self.results, &mut swap);
|
||||||
|
return swap.into_iter().collect::<Option<_>>()
|
||||||
|
.expect("Results not full but the heap is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn one_left(&mut self) -> bool {
|
||||||
|
self.entry(0).is_some() && self.entry(1).is_none() && self.entry(2).is_none()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Task> Task for TaskVec<T> {
|
impl<T: Task> Task for TaskVec<T> {
|
||||||
|
type Result = Vec<T::Result>;
|
||||||
|
|
||||||
|
fn run_n_times(&mut self, mut count: u64) -> TaskState<Self::Result> {
|
||||||
|
loop {
|
||||||
|
if count == 0 {return TaskState::Yield}
|
||||||
|
if self.one_left() {
|
||||||
|
let head = &mut self.task_heap[0];
|
||||||
|
let head_entry = head.as_mut().expect("one_left faulty");
|
||||||
|
return match head_entry.task.run_n_times(count) {
|
||||||
|
TaskState::Yield => TaskState::Yield,
|
||||||
|
TaskState::Complete(r) => {
|
||||||
|
self.results[head_entry.position] = Some(r);
|
||||||
|
*head = None;
|
||||||
|
return TaskState::Complete(self.take_results());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let r@TaskState::Complete(_) = self.run_once() {return r}
|
||||||
|
count -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn run_once(&mut self) -> super::TaskState<Self::Result> {
|
fn run_once(&mut self) -> super::TaskState<Self::Result> {
|
||||||
|
self.normalize();
|
||||||
let head = &mut self.task_heap[0];
|
let head = &mut self.task_heap[0];
|
||||||
let head_entry = head.as_mut().expect("All completed, cannot run further");
|
let head_entry = head.as_mut().expect("All completed, cannot run further");
|
||||||
head_entry.tally += head_entry.nice;
|
head_entry.tally += head_entry.nice;
|
||||||
@@ -98,9 +132,13 @@ impl<T: Task> Task for TaskVec<T> {
|
|||||||
self.results[head_entry.position] = Some(r);
|
self.results[head_entry.position] = Some(r);
|
||||||
*head = None;
|
*head = None;
|
||||||
self.sink(0);
|
self.sink(0);
|
||||||
if self.entry(0).is_some() {
|
if self.entry(0).is_some() { return TaskState::Yield }
|
||||||
|
TaskState::Complete(self.take_results())
|
||||||
}
|
}
|
||||||
|
TaskState::Yield => {
|
||||||
|
head_entry.tally += head_entry.nice;
|
||||||
|
self.sink(0);
|
||||||
|
TaskState::Yield
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user