TypeTerm: type-ladder arguments, variables & char-literals

This commit is contained in:
Michael Sippel 2023-03-02 03:43:38 +01:00
parent f1eedad3fe
commit 17b58e6bca
Signed by: senvas
GPG key ID: 060F22F65102F95C
9 changed files with 224 additions and 128 deletions

View file

@ -116,7 +116,7 @@ impl DigitEditor {
TypeTerm::Type { TypeTerm::Type {
id: self.ctx.read().unwrap().get_typeid("Digit").unwrap(), id: self.ctx.read().unwrap().get_typeid("Digit").unwrap(),
args: vec![ args: vec![
TypeTerm::Num(self.radix as i64) TypeTerm::Num(self.radix as i64).into()
] ]
} }
} }
@ -145,7 +145,7 @@ impl PosIntEditor {
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("Digit").unwrap(), id: ctx.read().unwrap().get_typeid("Digit").unwrap(),
args: vec![ args: vec![
TypeTerm::Num(radix as i64) TypeTerm::Num(radix as i64).into()
] ]
}, },
None, None,
@ -169,11 +169,11 @@ impl PosIntEditor {
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("PosInt").unwrap(), id: ctx.read().unwrap().get_typeid("PosInt").unwrap(),
args: vec![ args: vec![
TypeTerm::Num(radix as i64), TypeTerm::Num(radix as i64).into(),
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("BigEndian").unwrap(), id: ctx.read().unwrap().get_typeid("BigEndian").unwrap(),
args: vec![] args: vec![]
} }.into()
] ]
} }
)); ));

View file

@ -125,7 +125,7 @@ impl ListEditor {
pub fn get_seq_type(&self) -> TypeTerm { pub fn get_seq_type(&self) -> TypeTerm {
TypeTerm::Type { TypeTerm::Type {
id: self.ctx.read().unwrap().get_typeid("List").unwrap(), id: self.ctx.read().unwrap().get_typeid("List").unwrap(),
args: vec![ self.get_item_type() ] args: vec![ self.get_item_type().into() ]
} }
} }

View file

@ -1,6 +1,6 @@
use { use {
crate::{ crate::{
type_system::{TypeDict, TypeTerm, TypeID, ReprTree}, type_system::{TypeDict, TypeTerm, TypeID, ReprTree, TypeLadder},
tree::NestedNode tree::NestedNode
}, },
std::{ std::{
@ -11,8 +11,6 @@ use {
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeLadder(Vec<TypeTerm>);
#[derive(Clone, Copy, Hash, PartialEq, Eq)] #[derive(Clone, Copy, Hash, PartialEq, Eq)]
pub enum MorphismMode { pub enum MorphismMode {
/// Isomorphism /// Isomorphism
@ -50,12 +48,12 @@ impl From<MorphismType> for MorphismTypePattern {
fn from(value: MorphismType) -> MorphismTypePattern { fn from(value: MorphismType) -> MorphismTypePattern {
MorphismTypePattern { MorphismTypePattern {
src_tyid: match value.src_type { src_tyid: match value.src_type {
Some(TypeTerm::Type { id, args: _ }) => Some(id), Some(TypeTerm::Type { id, args: _ }) => Some(TypeID::Fun(id)),
_ => None, _ => None,
}, },
dst_tyid: match value.dst_type { dst_tyid: match value.dst_type {
TypeTerm::Type { id, args: _ } => id, TypeTerm::Type { id, args: _ } => TypeID::Fun(id),
_ => unreachable!() _ => unreachable!()
} }
} }
@ -66,7 +64,7 @@ impl From<MorphismType> for MorphismTypePattern {
pub struct Context { pub struct Context {
/// assigns a name to every type /// assigns a name to every type
type_dict: Arc<RwLock<TypeDict>>, pub type_dict: Arc<RwLock<TypeDict>>,
/// named vertices of the graph /// named vertices of the graph
nodes: HashMap< String, NestedNode >, nodes: HashMap< String, NestedNode >,
@ -135,7 +133,7 @@ impl Context {
pub fn is_list_type(&self, t: &TypeTerm) -> bool { pub fn is_list_type(&self, t: &TypeTerm) -> bool {
match t { match t {
TypeTerm::Type { id, args: _ } => { TypeTerm::Type { id, args: _ } => {
self.list_types.contains(id) self.list_types.contains(&TypeID::Fun(*id))
} }
_ => false _ => false
} }
@ -145,6 +143,20 @@ impl Context {
self.type_dict.read().unwrap().get_typeid(&tn.into()) self.type_dict.read().unwrap().get_typeid(&tn.into())
} }
pub fn get_fun_typeid(&self, tn: &str) -> Option<u64> {
match self.get_typeid(tn) {
Some(TypeID::Fun(x)) => Some(x),
_ => None
}
}
pub fn get_var_typeid(&self, tn: &str) -> Option<u64> {
match self.get_typeid(tn) {
Some(TypeID::Var(x)) => Some(x),
_ => None
}
}
pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> { pub fn type_term_from_str(&self, tn: &str) -> Option<TypeTerm> {
self.type_dict.read().unwrap().type_term_from_str(&tn) self.type_dict.read().unwrap().type_term_from_str(&tn)
} }

View file

@ -0,0 +1,71 @@
use {
crate::{
utils::Bimap,
type_system::{TypeTerm, TypeLadder}
}
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
pub enum TypeID {
Fun(u64),
Var(u64)
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeDict {
typenames: Bimap<String, TypeID>,
type_lit_counter: u64,
type_var_counter: u64,
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl TypeDict {
pub fn new() -> Self {
TypeDict {
typenames: Bimap::new(),
type_lit_counter: 0,
type_var_counter: 0,
}
}
pub fn add_varname(&mut self, tn: String) -> TypeID {
let tyid = TypeID::Var(self.type_var_counter);
self.type_var_counter += 1;
self.typenames.insert(tn, tyid.clone());
tyid
}
pub fn add_typename(&mut self, tn: String) -> TypeID {
let tyid = TypeID::Fun(self.type_lit_counter);
self.type_lit_counter += 1;
self.typenames.insert(tn, tyid.clone());
tyid
}
pub fn get_typename(&self, tid: &TypeID) -> Option<String> {
self.typenames.my.get(tid).cloned()
}
pub fn get_typeid(&self, tn: &String) -> Option<TypeID> {
self.typenames..get(tn).cloned()
}
pub fn type_term_from_str(&self, typename: &str) -> Option<TypeTerm> {
TypeTerm::from_str(typename, &self.typenames.)
}
pub fn type_term_to_str(&self, term: &TypeTerm) -> String {
term.to_str(&self.typenames.my)
}
pub fn type_ladder_to_str(&self, ladder: &TypeLadder) -> String {
ladder.to_str1(&self.typenames.my)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -0,0 +1,71 @@
use {
crate::type_system::{TypeTerm, TypeID},
std::collections::HashMap
};
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone, Eq, PartialEq, Hash, Debug)]
pub struct TypeLadder(pub Vec<TypeTerm>);
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl From<Vec<TypeTerm>> for TypeLadder {
fn from(l: Vec<TypeTerm>) -> Self {
TypeLadder(l)
}
}
impl From<TypeTerm> for TypeLadder {
fn from(l: TypeTerm) -> Self {
TypeLadder(vec![ l ])
}
}
impl TypeLadder {
/// if compatible, returns the number of descents neccesary
pub fn is_compatible_with(&self, other: &TypeLadder) -> Option<usize> {
if let Some(other_top_type) = other.0.first() {
for (i, t) in self.0.iter().enumerate() {
if t == other_top_type {
return Some(i);
}
}
None
} else {
None
}
}
pub fn is_matching_repr(&self, other: &TypeLadder) -> Result<usize, Option<(usize, usize)>> {
if let Some(start) = self.is_compatible_with(other) {
for (i, (t1, t2)) in self.0.iter().skip(start).zip(other.0.iter()).enumerate() {
if t1 != t2 {
return Err(Some((start, i)));
}
}
Ok(start)
} else {
Err(None)
}
}
pub fn to_str1(&self, names: &HashMap<TypeID, String>) -> String {
let mut s = String::new();
let mut first = true;
for t in self.0.iter() {
if !first {
s = s + "~";
}
first = false;
s = s + &t.to_str1(names);
}
s
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>

View file

@ -75,7 +75,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
if args.len() > 0 { if args.len() > 0 {
let editor = PTYListEditor::new( let editor = PTYListEditor::new(
ctx, ctx,
args[0].clone(), (args[0].clone().0)[0].clone(),
Some(','), Some(','),
depth + 1 depth + 1
); );
@ -125,7 +125,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("List").unwrap(), id: ctx.read().unwrap().get_typeid("List").unwrap(),
args: vec![ args: vec![
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()) TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()).into()
] ]
}, },
depth+1 depth+1
@ -173,7 +173,7 @@ pub fn init_editor_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
TypeTerm::Type { TypeTerm::Type {
id: ctx.read().unwrap().get_typeid("List").unwrap(), id: ctx.read().unwrap().get_typeid("List").unwrap(),
args: vec![ args: vec![
TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()) TypeTerm::new(ctx.read().unwrap().get_typeid("Char").unwrap()).into()
] ]
}, },
depth+1 depth+1
@ -215,7 +215,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
id: _, args id: _, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
match args[0] { match (args[0].0)[0] {
TypeTerm::Num(radix) => { TypeTerm::Num(radix) => {
let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth); let node = DigitEditor::new(ctx.clone(), radix as u32).into_node(depth);
Some( Some(
@ -252,7 +252,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
id: _, args id: _, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
match args[0] { match (args[0].0)[0] {
TypeTerm::Num(_radix) => { TypeTerm::Num(_radix) => {
let pty_editor = PTYListEditor::from_editor( let pty_editor = PTYListEditor::from_editor(
editor, editor,
@ -291,7 +291,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
id: _, args id: _, args
} => { } => {
if args.len() > 0 { if args.len() > 0 {
match args[0] { match (args[0].0)[0] {
TypeTerm::Num(radix) => { TypeTerm::Num(radix) => {
let mut node = Context::make_node( let mut node = Context::make_node(
@ -302,6 +302,7 @@ pub fn init_math_ctx(parent: Arc<RwLock<Context>>) -> Arc<RwLock<Context>> {
TypeTerm::new(ctx.read().unwrap().get_typeid("Digit").unwrap()) TypeTerm::new(ctx.read().unwrap().get_typeid("Digit").unwrap())
.num_arg(radix) .num_arg(radix)
.clone() .clone()
.into()
] ]
}, },
depth+1 depth+1

View file

@ -1,13 +1,17 @@
pub mod type_term;
pub mod repr_tree;
pub mod context; pub mod context;
pub mod dict;
pub mod term;
pub mod ladder;
pub mod repr_tree;
pub mod make_editor; pub mod make_editor;
//pub mod type_term_editor; //pub mod editor;
pub use { pub use {
repr_tree::{ReprTree}, dict::*,
type_term::{TypeDict, TypeID, TypeTerm, TypeLadder}, ladder::*,
repr_tree::*,
term::*,
context::{Context, MorphismMode, MorphismType, MorphismTypePattern}, context::{Context, MorphismMode, MorphismType, MorphismTypePattern},
// type_term_editor::TypeTermEditor, // type_term_editor::TypeTermEditor,
make_editor::* make_editor::*

View file

@ -1,66 +1,36 @@
use {crate::utils::Bimap, std::collections::HashMap}; use {
crate::{
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> type_system::{TypeLadder, TypeID}
},
pub type TypeID = u64; std::collections::HashMap
};
#[derive(Clone)]
pub struct TypeLadder(pub Vec<TypeTerm>);
impl From<Vec<TypeTerm>> for TypeLadder {
fn from(l: Vec<TypeTerm>) -> Self {
TypeLadder(l)
}
}
impl TypeLadder {
/// if compatible, returns the number of descents neccesary
pub fn is_compatible_with(&self, other: &TypeLadder) -> Option<usize> {
if let Some(other_top_type) = other.0.first() {
for (i, t) in self.0.iter().enumerate() {
if t == other_top_type {
return Some(i);
}
}
None
} else {
None
}
}
pub fn is_matching_repr(&self, other: &TypeLadder) -> Result<usize, Option<(usize, usize)>> {
if let Some(start) = self.is_compatible_with(other) {
for (i, (t1, t2)) in self.0.iter().skip(start).zip(other.0.iter()).enumerate() {
if t1 != t2 {
return Err(Some((start, i)));
}
}
Ok(start)
} else {
Err(None)
}
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>> //<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
#[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(Clone, PartialEq, Eq, Hash, Debug)]
pub enum TypeTerm { pub enum TypeTerm {
Type { id: TypeID, args: Vec<TypeTerm> }, Type {
id: u64,
args: Vec< TypeLadder >
},
Var(u64),
Num(i64), Num(i64),
// Var(u64), Char(char)
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
impl TypeTerm { impl TypeTerm {
pub fn new(id: TypeID) -> Self { pub fn new(id: TypeID) -> Self {
TypeTerm::Type { id, args: vec![] } match id {
TypeID::Fun(id) => TypeTerm::Type { id, args: vec![] },
TypeID::Var(_) => {unreachable!();}
}
} }
pub fn arg(&mut self, t: TypeTerm) -> &mut Self { pub fn arg(&mut self, t: impl Into<TypeLadder>) -> &mut Self {
if let TypeTerm::Type { id: _, args } = self { if let TypeTerm::Type { id: _, args } = self {
args.push(t); args.push(t.into());
} }
self self
@ -70,7 +40,11 @@ impl TypeTerm {
self.arg(TypeTerm::Num(v)) self.arg(TypeTerm::Num(v))
} }
pub fn from_str(s: &str, names: &HashMap<String, u64>) -> Option<Self> { pub fn char_arg(&mut self, c: char) -> &mut Self {
self.arg(TypeTerm::Char(c))
}
pub fn from_str(s: &str, names: &HashMap<String, TypeID>) -> Option<Self> {
let mut term_stack = Vec::<Option<TypeTerm>>::new(); let mut term_stack = Vec::<Option<TypeTerm>>::new();
for token in s.split_whitespace() { for token in s.split_whitespace() {
@ -100,13 +74,13 @@ impl TypeTerm {
f.num_arg(i64::from_str_radix(atom, 10).unwrap()); f.num_arg(i64::from_str_radix(atom, 10).unwrap());
} else { } else {
f.arg(TypeTerm::new( f.arg(TypeTerm::new(
*names.get(atom).expect(&format!("invalid atom {}", atom)), names.get(atom).expect(&format!("invalid atom {}", atom)).clone(),
)); ));
} }
} }
None => { None => {
*f = Some(TypeTerm::new( *f = Some(TypeTerm::new(
*names.get(atom).expect(&format!("invalid atom {}", atom)), names.get(atom).expect(&format!("invalid atom {}", atom)).clone(),
)); ));
} }
} }
@ -118,13 +92,13 @@ impl TypeTerm {
} }
// only adds parenthesis where args.len > 0 // only adds parenthesis where args.len > 0
pub fn to_str1(&self, names: &HashMap<u64, String>) -> String { pub fn to_str1(&self, names: &HashMap<TypeID, String>) -> String {
match self { match self {
TypeTerm::Type { id, args } => { TypeTerm::Type { id, args } => {
if args.len() > 0 { if args.len() > 0 {
format!( format!(
"({}{})", "({}{})",
names[id], names[&TypeID::Fun(*id)],
if args.len() > 0 { if args.len() > 0 {
args.iter().fold(String::new(), |str, term| { args.iter().fold(String::new(), |str, term| {
format!(" {}{}", str, term.to_str1(names)) format!(" {}{}", str, term.to_str1(names))
@ -134,20 +108,22 @@ impl TypeTerm {
} }
) )
} else { } else {
names[id].clone() names[&TypeID::Fun(*id)].clone()
} }
} }
TypeTerm::Num(n) => format!("{}", n), TypeTerm::Num(n) => format!("{}", n),
TypeTerm::Char(c) => format!("'{}'", c),
TypeTerm::Var(varid) => format!("T"),
} }
} }
// always adds an enclosing pair of parenthesis // always adds an enclosing pair of parenthesis
pub fn to_str(&self, names: &HashMap<u64, String>) -> String { pub fn to_str(&self, names: &HashMap<TypeID, String>) -> String {
match self { match self {
TypeTerm::Type { id, args } => format!( TypeTerm::Type { id, args } => format!(
"( {} {})", "( {} {})",
names[id], names[&TypeID::Fun(*id)],
if args.len() > 0 { if args.len() > 0 {
args.iter().fold(String::new(), |str, term| { args.iter().fold(String::new(), |str, term| {
format!("{}{} ", str, term.to_str1(names)) format!("{}{} ", str, term.to_str1(names))
@ -158,47 +134,8 @@ impl TypeTerm {
), ),
TypeTerm::Num(n) => format!("{}", n), TypeTerm::Num(n) => format!("{}", n),
TypeTerm::Char(c) => format!("'{}'", c),
TypeTerm::Var(varid) => format!("T"),
} }
} }
} }
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>
pub struct TypeDict {
typenames: Bimap<String, u64>,
type_id_counter: TypeID,
}
impl TypeDict {
pub fn new() -> Self {
TypeDict {
typenames: Bimap::new(),
type_id_counter: 0,
}
}
pub fn add_typename(&mut self, tn: String) -> TypeID {
let tyid = self.type_id_counter;
self.type_id_counter += 1;
self.typenames.insert(tn, tyid);
tyid
}
pub fn get_typename(&self, tid: &u64) -> Option<String> {
self.typenames.my.get(tid).cloned()
}
pub fn get_typeid(&self, tn: &String) -> Option<TypeID> {
self.typenames..get(tn).cloned()
}
pub fn type_term_from_str(&self, typename: &str) -> Option<TypeTerm> {
TypeTerm::from_str(typename, &self.typenames.)
}
pub fn type_term_to_str(&self, term: &TypeTerm) -> String {
term.to_str(&self.typenames.my)
}
}
//<<<<>>>><<>><><<>><<<*>>><<>><><<>><<<<>>>>