-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1. ✅基于「路径遍历器」与「路径构建器」的通用搜索特征 2. ✅基本实用的「名称匹配」逻辑,及其「路径遍历」应用测试(📄遇见名称与「nars」有关的就深入) 3. ✅适用于OpenNARS、ONA的「路径构建器」 4. 🚧TODO:PyNARS的「路径构建器」 5. 🚧TODO:不同类型「CIN搜索」的统一适配(通过用户输入选取,在选择后进行匹配,尽可能数据驱动)
- Loading branch information
1 parent
159aa91
commit e44b009
Showing
12 changed files
with
794 additions
and
3 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[package] | ||
name = "babel_nar" | ||
version = "0.8.0" | ||
version = "0.9.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
//! 🚩【2024-03-30 23:36:48】曾经的尝试: | ||
//! * 所有「路径构建器」都返回一个动态的「虚拟机启动器」类型 | ||
//! * 启动时只需在一个「Anyhow虚拟机启动器」列表中选择 | ||
trait Turned { | ||
fn say(&self); | ||
} | ||
trait Unturned { | ||
type Target: Turned; | ||
fn turn(self) -> Self::Target; | ||
fn turn_box(self: Box<Self>) -> Box<Self::Target>; | ||
fn turn_box_sized(self: Box<Self>) -> Box<Self::Target> | ||
where | ||
Self: Sized, | ||
{ | ||
Box::new(self.turn()) | ||
} | ||
} | ||
struct U(usize); | ||
struct T(usize); | ||
impl Turned for T { | ||
fn say(&self) { | ||
print!("I'm T({})", self.0) | ||
} | ||
} | ||
impl Unturned for U { | ||
type Target = T; | ||
fn turn(self) -> T { | ||
T(self.0) | ||
} | ||
fn turn_box(self: Box<Self>) -> Box<Self::Target> { | ||
self.turn_box_sized() | ||
} | ||
} | ||
struct AnyhowUnturned<T: Turned = AnyhowTurned> { | ||
inner: Box<dyn Unturned<Target = T>>, | ||
} | ||
struct AnyhowTurned { | ||
inner: Box<dyn Turned>, | ||
} | ||
impl Turned for AnyhowTurned { | ||
fn say(&self) { | ||
self.inner.say() | ||
} | ||
} | ||
impl Unturned for AnyhowUnturned<T> { | ||
type Target = AnyhowTurned; | ||
fn turn(self) -> AnyhowTurned { | ||
AnyhowTurned { | ||
inner: self.inner.turn_box(), | ||
} | ||
} | ||
|
||
fn turn_box(self: Box<Self>) -> Box<Self::Target> { | ||
self.turn_box_sized() | ||
} | ||
} | ||
impl<T: Turned, U: Unturned<Target = T>> From<U> for AnyhowUnturned<T> { | ||
fn from(value: U) -> Self { | ||
Self { | ||
inner: Box::new(value), | ||
} | ||
} | ||
} | ||
struct AnyhowUnturned2 { | ||
inner: AnyhowTurned, | ||
} | ||
|
||
fn main() { | ||
let unturned: AnyhowUnturned<_> = U(1).into(); | ||
} | ||
|
||
// pub struct AnyhowLauncher<'a, Runtime: VmRuntime + 'a> { | ||
// pub launcher: Box<dyn VmLauncher<Runtime> + 'a>, | ||
// } | ||
|
||
// impl<'a, Runtime: VmRuntime + 'a> AnyhowLauncher<'a, Runtime> { | ||
// pub fn new<Launcher>(launcher: impl VmLauncher<Runtime> + 'a) -> Self | ||
// where | ||
// Launcher: VmLauncher<Runtime> + 'a, | ||
// { | ||
// Self { | ||
// launcher: Box::new(launcher), | ||
// } | ||
// } | ||
// } | ||
|
||
// /// ! Box<Runtime>不能充当`VmLauncher`的参数:未实现`VmRuntime` | ||
// impl<'a, Runtime: VmRuntime + 'a> VmLauncher<AnyhowRuntime<'a>> for AnyhowLauncher<'a, Runtime> { | ||
// fn launch(self) -> AnyhowRuntime<'a> { | ||
// AnyhowRuntime { | ||
// inner: Box::new(self.launcher.launch()), | ||
// } | ||
// } | ||
// } | ||
|
||
// struct AnyhowRuntime<'a> { | ||
// inner: Box<dyn VmRuntime + 'a>, | ||
// } | ||
|
||
// impl AnyhowRuntime<'_> { | ||
// fn new(inner: impl VmRuntime) -> Self { | ||
// Self { | ||
// inner: Box::new(inner), | ||
// } | ||
// } | ||
// } | ||
|
||
// impl VmRuntime for AnyhowRuntime<'_> { | ||
// fn input_cmd(&mut self, cmd: navm::cmd::Cmd) -> anyhow::Result<()> { | ||
// self.inner.input_cmd(cmd) | ||
// } | ||
|
||
// fn fetch_output(&mut self) -> anyhow::Result<navm::output::Output> { | ||
// self.inner.fetch_output() | ||
// } | ||
|
||
// fn try_fetch_output(&mut self) -> anyhow::Result<Option<navm::output::Output>> { | ||
// self.inner.try_fetch_output() | ||
// } | ||
|
||
// fn terminate(self) -> anyhow::Result<()> { | ||
// self.inner.terminate() | ||
// } | ||
// } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
//! CIN启动器中有关「CIN路径构建(搜索)」的逻辑 | ||
//! * ✨根据「CIN路径构建器」搜索(判别)系统中已存在的CIN实现(并自动构建) | ||
//! * 🚩输入:搜索起点(一般是编译后exe所在文件夹) | ||
//! * 🚩输出:NAVM启动器列表 | ||
//! * ❓【2024-03-30 19:12:29】是否要考虑返回更细化的「CIN实例位置」而非「CIN启动器」,以避免额外的性能开销? | ||
use nar_dev_utils::mods; | ||
|
||
/// 导出模块 | ||
mods! { | ||
// 路径遍历器 | ||
use pub path_walker; | ||
// 路径构造器 | ||
use pub path_builder; | ||
// anyhow | 弃用 | ||
// anyhow_vm; | ||
// 名称匹配 | ||
use pub name_match; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
//! 封装「名称匹配」逻辑 | ||
//! * 🎯用于「语义化」「模糊化」的字符串匹配 | ||
//! * ✨无视大小写匹配 | ||
//! * 📄"opennars"匹配"OpenNARS" | ||
//! * ✨「含于」与「包含」匹配 | ||
//! * 📄"opennars"匹配"OpenNARS 3.0.4"(含于)与"nars"(包含) | ||
//! * ✨返回一个「匹配度」的数值 | ||
//! * `0`统一表示「未匹配」 | ||
//! * 剩余值可用于排序 | ||
use nar_dev_utils::{first, if_return}; | ||
|
||
/// 名称匹配 | ||
/// * 🎯用于「语义化」「模糊化」的字符串匹配 | ||
/// * ✨无视大小写匹配 | ||
/// * 📄"opennars"匹配"OpenNARS" | ||
/// * ✨「含于」与「包含」匹配 | ||
/// * 📄"opennars"匹配"OpenNARS 3.0.4"(含于)与"nars"(包含) | ||
/// * ⚙️返回一个「匹配度」的数值 | ||
/// * `0`统一表示「未匹配」 | ||
/// * 剩余值可用于排序 | ||
pub fn name_match(name: &str, target: &str) -> usize { | ||
// 完全相等⇒最高级 | ||
if_return! { | ||
// 完全相等⇒高 | ||
name == target => 6 | ||
// 包含于⇒中 | ||
target.contains(name) => 4 | ||
// 包含⇒低 | ||
name.contains(target) => 2 | ||
} | ||
|
||
// 忽略大小写的情况 | 忽略大小写,降一个匹配度 | ||
let name = name.to_lowercase(); | ||
let target = target.to_lowercase(); | ||
|
||
first! { | ||
// 完全相等⇒高 | ||
name == target => 5, | ||
// 包含于⇒中 | ||
target.contains(&name) => 3, | ||
// 包含⇒低 | ||
name.contains(&target) => 1, | ||
// 否则⇒不匹配 | ||
_ => 0, | ||
} | ||
} | ||
|
||
/// 名称匹配/仅「含于」 | ||
/// * 🚩与[`name_match`]类似,但仅「含于」而不适配「包含」 | ||
/// * 🎯用于「长串名称作为内部关键词」的匹配 | ||
pub fn name_match_only_contains(name: &str, target: &str) -> usize { | ||
// 完全相等⇒最高级 | ||
if_return! { | ||
// 完全相等⇒高 | ||
name == target => 4 | ||
// 含于⇒低 | ||
target.contains(name) => 2 | ||
} | ||
|
||
// 忽略大小写的情况 | 忽略大小写,降一个匹配度 | ||
let name = name.to_lowercase(); | ||
let target = target.to_lowercase(); | ||
|
||
first! { | ||
// 完全相等⇒高 | ||
name == target => 3, | ||
// 含于⇒低 | ||
target.contains(&name) => 1, | ||
// 否则⇒不匹配 | ||
_ => 0, | ||
} | ||
} | ||
|
||
/// 判断「是否匹配」,不管「匹配度」多少 | ||
/// * 🚩直接复用逻辑,以牺牲一定性能为代价 | ||
pub fn is_name_match(name: &str, target: &str) -> bool { | ||
name_match(name, target) > 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
//! 统一的「路径构建器」逻辑 | ||
use navm::vm::{VmLauncher, VmRuntime}; | ||
use std::path::Path; | ||
|
||
/// CIN路径构建器 | ||
/// * 🚩本身不承担「遍历路径」的任务,只负责 | ||
/// * 📌判断是否「可以用于构建NAVM运行时」 | ||
/// * 📌从某路径构建「NAVM启动器」 | ||
/// * ❌【2024-03-30 19:05:48】放弃「通用启动器/通用运行时」的适配尝试 | ||
/// * 📝目前[`CinSearch::Launcher`]总是要带上[`CinSearch::Runtime`]作类型参数 | ||
/// * 📌堵点:难以定义一个使用`Box<dyn VmLauncher<?>>`封装的`AnyhowVmLauncher`类型 | ||
/// * 📍问题领域:特征对象及其转换 | ||
/// * ❓一个可能的参考:[`anyhow`]对「错误类型」的统一 | ||
/// * ❌【2024-03-30 21:24:10】尝试仍然失败:有关`Box<Self>`的所有权转换问题 | ||
/// * 🔗技术参考1:<https://stackoverflow.com/questions/46620790/how-to-call-a-method-that-consumes-self-on-a-boxed-trait-object> | ||
pub trait CinPathBuilder { | ||
/// 搜索结果的启动器类型 | ||
/// * 📌启动后变为[`CinSearch::Runtime`]运行时类型 | ||
type Launcher: VmLauncher<Self::Runtime>; | ||
|
||
/// 搜索结果的运行时类型 | ||
type Runtime: VmRuntime; | ||
|
||
/// 路径匹配 | ||
/// * 🎯匹配某路径(可能是文件夹,也可能是文件)是否可用于「构建NAVM启动器」 | ||
/// * ⚠️与**该路径是否存在**有关 | ||
/// * 📌需要访问本地文件系统 | ||
/// * 📄一些CIN可能要求判断其子目录的文件(附属文件) | ||
/// * ⚙️返回「匹配度」 | ||
/// * 📌`0`⇒不匹配,其它⇒不同程度的匹配 | ||
/// * 🎯对接「名称匹配」中的「匹配度」 | ||
/// * ✨可用于后续排序 | ||
fn match_path(&self, path: &Path) -> usize; | ||
|
||
/// 用于检查路径是否匹配 | ||
/// * 🔗参见[`match_path`] | ||
fn is_path_matched(&self, path: &Path) -> bool { | ||
self.match_path(path) > 0 | ||
} | ||
|
||
/// 路径构建 | ||
/// * 🎯从某个路径构建出一个NAVM启动器 | ||
/// * ✅除路径以外,其它参数可作默认 | ||
/// * 📄OpenNARS的「Java最大堆大小」 | ||
/// | ||
/// # Panics | ||
/// | ||
/// ⚠️需要保证[`is_path_matched`]为真 | ||
/// * 为假时可能`panic` | ||
fn construct_from_path(&self, path: &Path) -> Self::Launcher; | ||
|
||
/// 尝试路径构建 | ||
/// * 🚩返回一个[`Option`] | ||
/// * 能构建⇒返回构建后的结果 `Some((启动器, 匹配度))` | ||
/// * 无法构建⇒返回[`None`] | ||
#[inline] | ||
fn try_construct_from_path(&self, path: &Path) -> Option<(Self::Launcher, usize)> { | ||
match self.match_path(path) { | ||
// 不匹配⇒无 | ||
0 => None, | ||
// 匹配⇒元组 | ||
n => Some((self.construct_from_path(path), n)), | ||
} | ||
} | ||
} |
Oops, something went wrong.