Change in priorities

This commit is contained in:
2023-02-23 14:28:07 +00:00
parent d75add5ea3
commit ca23edabe4
7 changed files with 217 additions and 58 deletions

View File

@@ -1,53 +1,58 @@
use itertools::Itertools;
use mappable_rc::Mrc;
use crate::utils::{collect_to_mrc, to_mrc_slice};
use super::super::representations::typed::{Clause, Expr};
use crate::representations::typed::{Clause, Expr};
pub fn apply_lambda(id: u64, value: Mrc<Expr>, body: Mrc<Expr>) -> Mrc<Expr> {
apply_lambda_expr_rec(id, value, Mrc::clone(&body))
.unwrap_or(body)
#[derive(Clone)]
struct Application<'a> {
id: u64,
value: &'a Expr,
types: bool
}
// pub fn apply_lambda(app: Application, body: Expr) -> Expr {
// apply_lambda_expr_rec(id, value, body)
// .unwrap_or(body)
// }
fn apply_lambda_expr_rec(
id: u64, value: Mrc<Expr>, expr: Mrc<Expr>
) -> Option<Mrc<Expr>> {
let Expr(clause, typ) = expr.as_ref();
app@Application{ id, types, value }: Application, expr: &Expr
) -> Option<Expr> {
let Expr(clause, typ) = expr;
match clause {
Clause::LambdaArg(arg_id) | Clause::AutoArg(arg_id) if *arg_id == id => {
let full_typ = collect_to_mrc(
let full_typ =
value.1.iter()
.chain(typ.iter())
.cloned()
);
Some(Mrc::new(Expr(value.0.to_owned(), full_typ)))
.cloned().collect_vec();
Some(Expr(value.0.to_owned(), full_typ))
}
cl => {
apply_lambda_clause_rec(id, value, cl.clone())
.map(|c| Mrc::new(Expr(c, Mrc::clone(typ))))
let new_cl = apply_lambda_clause_rec(app, cl);
let new_typ = if !types {None} else {
typ.
}
}
}
}
fn apply_lambda_clause_rec(
id: u64, value: Mrc<Expr>, clause: Clause
app: Application, clause: &Clause
) -> Option<Clause> {
match clause {
// Only element actually manipulated
Clause::LambdaArg(_) | Clause::AutoArg(_) => Some(clause),
Clause::LambdaArg(_) | Clause::AutoArg(_) => None,
// Traverse, yield Some if either had changed.
Clause::Apply(f, x) => {
let new_f = apply_lambda_expr_rec(
id, Mrc::clone(&value), Mrc::clone(&f)
);
let new_x = apply_lambda_expr_rec(
id, value, Mrc::clone(&x)
);
let new_f = apply_lambda_expr_rec(app, f.as_ref());
let new_x = apply_lambda_expr_rec(app, x.as_ref());
match (new_f, new_x) { // Mind the shadows
(None, None) => None,
(None, Some(x)) => Some(Clause::Apply(f, x)),
(Some(f), None) => Some(Clause::Apply(f, x)),
(Some(f), Some(x)) => Some(Clause::Apply(f, x))
(None, Some(x)) => Some(Clause::Apply(f.clone(), Box::new(x))),
(Some(f), None) => Some(Clause::Apply(Box::new(f), x.clone())),
(Some(f), Some(x)) => Some(Clause::Apply(Box::new(f), Box::new(x)))
}
},
Clause::Lambda(own_id, t, b) => apply_lambda__traverse_param(id, value, own_id, t, b, Clause::Lambda),

View File

@@ -2,4 +2,5 @@ mod normalize;
mod partial_hash;
mod reduction_tree;
mod apply_lambda;
pub use apply_lambda::apply_lambda;
mod syntax_eq;

View File

@@ -1,28 +1,30 @@
use mappable_rc::Mrc;
use crate::executor::apply_lambda;
use crate::foreign::{Atom, ExternFn};
use crate::utils::{to_mrc_slice, one_mrc_slice};
use crate::utils::string_from_charset;
use super::{Literal, ast_to_typed};
use super::get_name::get_name;
use super::{Literal, ast_to_typed, get_name};
use super::ast;
use std::fmt::{Debug, Write};
/// Indicates whether either side needs to be wrapped. Syntax whose end is ambiguous on that side
/// must use parentheses, or forward the flag
#[derive(PartialEq, Eq)]
#[derive(PartialEq, Eq, Clone, Copy)]
struct Wrap(bool, bool);
#[derive(PartialEq, Eq, Hash)]
pub struct Expr(pub Clause, pub Mrc<[Clause]>);
#[derive(PartialEq, Eq, Hash, Clone)]
pub struct Expr(pub Clause, pub Vec<Clause>);
impl Expr {
fn deep_fmt(&self, f: &mut std::fmt::Formatter<'_>, tr: Wrap) -> std::fmt::Result {
let Expr(val, typ) = self;
if typ.len() > 0 {
val.deep_fmt(f, Wrap(true, true))?;
for typ in typ.as_ref() {
for typterm in typ {
f.write_char(':')?;
typ.deep_fmt(f, Wrap(true, true))?;
typterm.deep_fmt(f, Wrap(true, true))?;
}
} else {
val.deep_fmt(f, tr)?;
@@ -31,12 +33,6 @@ impl Expr {
}
}
impl Clone for Expr {
fn clone(&self) -> Self {
Self(self.0.clone(), Mrc::clone(&self.1))
}
}
impl Debug for Expr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.deep_fmt(f, Wrap(false, false))
@@ -46,9 +42,9 @@ impl Debug for Expr {
#[derive(PartialEq, Eq, Hash)]
pub enum Clause {
Literal(Literal),
Apply(Mrc<Expr>, Mrc<Expr>),
Lambda(u64, Mrc<[Clause]>, Mrc<Expr>),
Auto(u64, Mrc<[Clause]>, Mrc<Expr>),
Apply(Box<Expr>, Box<Expr>),
Lambda(u64, Box<[Clause]>, Box<Expr>),
Auto(u64, Box<[Clause]>, Box<Expr>),
LambdaArg(u64), AutoArg(u64),
ExternFn(ExternFn),
Atom(Atom)
@@ -58,7 +54,7 @@ const ARGNAME_CHARSET: &str = "abcdefghijklmnopqrstuvwxyz";
fn parametric_fmt(
f: &mut std::fmt::Formatter<'_>,
prefix: &str, argtyp: Mrc<[Clause]>, body: Mrc<Expr>, uid: u64, wrap_right: bool
prefix: &str, argtyp: &[Clause], body: &Expr, uid: u64, wrap_right: bool
) -> std::fmt::Result {
if wrap_right { f.write_char('(')?; }
f.write_str(prefix)?;
@@ -80,12 +76,8 @@ impl Clause {
Self::Literal(arg0) => write!(f, "{arg0:?}"),
Self::ExternFn(nc) => write!(f, "{nc:?}"),
Self::Atom(a) => write!(f, "{a:?}"),
Self::Lambda(uid, argtyp, body) => parametric_fmt(f,
"\\", Mrc::clone(argtyp), Mrc::clone(body), *uid, wr
),
Self::Auto(uid, argtyp, body) => parametric_fmt(f,
"@", Mrc::clone(argtyp), Mrc::clone(body), *uid, wr
),
Self::Lambda(uid, argtyp, body) => parametric_fmt(f, "\\", argtyp, body, *uid, wr),
Self::Auto(uid, argtyp, body) => parametric_fmt(f, "@", argtyp, body, *uid, wr),
Self::LambdaArg(uid) | Self::AutoArg(uid) => f.write_str(&
string_from_charset(*uid, ARGNAME_CHARSET)
),
@@ -99,19 +91,27 @@ impl Clause {
}
}
}
pub fn wrap(self) -> Mrc<Expr> { Mrc::new(Expr(self, to_mrc_slice(vec![]))) }
pub fn wrap_t(self, t: Clause) -> Mrc<Expr> { Mrc::new(Expr(self, one_mrc_slice(t))) }
pub fn wrap(self) -> Box<Expr> { Box::new(Expr(self, vec![])) }
pub fn wrap_t(self, t: Clause) -> Box<Expr> { Box::new(Expr(self, vec![t])) }
}
impl Clone for Clause {
fn clone(&self) -> Self {
match self {
Clause::Auto(uid,t, b) => Clause::Auto(*uid, Mrc::clone(t), Mrc::clone(b)),
Clause::Lambda(uid, t, b) => Clause::Lambda(*uid, Mrc::clone(t), Mrc::clone(b)),
Clause::Auto(uid, t, b) => {
let new_id = get_name();
let new_body = apply_lambda(*uid, Clause::AutoArg(new_id).wrap(), b.clone());
Clause::Auto(new_id, t.clone(), new_body)
},
Clause::Lambda(uid, t, b) => {
let new_id = get_name();
let new_body = apply_lambda(*uid, Clause::LambdaArg(new_id).wrap(), b.clone());
Clause::Lambda(new_id, t.clone(), new_body)
},
Clause::Literal(l) => Clause::Literal(l.clone()),
Clause::ExternFn(nc) => Clause::ExternFn(nc.clone()),
Clause::Atom(a) => Clause::Atom(a.clone()),
Clause::Apply(f, x) => Clause::Apply(Mrc::clone(f), Mrc::clone(x)),
Clause::Apply(f, x) => Clause::Apply(Box::clone(&f), x.clone()),
Clause::LambdaArg(id) => Clause::LambdaArg(*id),
Clause::AutoArg(id) => Clause::AutoArg(*id)
}
@@ -138,4 +138,26 @@ impl TryFrom<&ast::Clause> for Clause {
}
}
pub fn count_references(id: u64, clause: &Clause)
pub fn is_used_clause(id: u64, is_auto: bool, clause: &Clause) -> bool {
match clause {
Clause::Atom(_) | Clause::ExternFn(_) | Clause::Literal(_) => false,
Clause::AutoArg(x) => is_auto && *x == id,
Clause::LambdaArg(x) => !is_auto && *x == id,
Clause::Apply(f, x) => is_used_expr(id, is_auto, &f) || is_used_expr(id, is_auto, &x),
Clause::Auto(n, t, b) => {
assert!(*n != id, "Shadowing should have been eliminated");
if is_auto && t.iter().any(|c| is_used_clause(id, is_auto, c)) {return true};
is_used_expr(id, is_auto, b)
}
Clause::Lambda(n, t, b) => {
assert!(*n != id, "Shadowing should have been eliminated");
if is_auto && t.iter().any(|c| is_used_clause(id, is_auto, c)) {return true};
is_used_expr(id, is_auto, b)
}
}
}
pub fn is_used_expr(id: u64, is_auto: bool, Expr(val, typ): &Expr) -> bool {
if is_auto && typ.iter().any(|c| is_used_clause(id, is_auto, c)) {return true};
is_used_clause(id, is_auto, val)
}