mirror of
https://github.com/HigherOrderCO/Kind1.git
synced 2024-09-19 04:37:28 +03:00
feat: finished a simple version of the query handler
This commit is contained in:
parent
77a452e5fb
commit
e2a4df9577
@ -1,8 +1,17 @@
|
||||
[package]
|
||||
name = "kind-cli"
|
||||
version = "0.1.0"
|
||||
version = "0.3.0"
|
||||
edition = "2021"
|
||||
description = "A pure functional functional language that uses the HVM."
|
||||
repository = "https://github.com/Kindelia/Kind2"
|
||||
license = "MIT"
|
||||
keywords = ["functional", "language", "type-theory", "proof-assistant"]
|
||||
|
||||
[[bin]]
|
||||
name = "kind2"
|
||||
path = "src/main.rs"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.0.10", features = ["derive"] }
|
||||
|
@ -1,14 +0,0 @@
|
||||
pub fn add(left: usize, right: usize) -> usize {
|
||||
left + right
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let result = add(2, 2);
|
||||
assert_eq!(result, 4);
|
||||
}
|
||||
}
|
79
src/kind-cli/src/main.rs
Normal file
79
src/kind-cli/src/main.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(author, version, about, long_about = None)]
|
||||
#[clap(propagate_version = true)]
|
||||
struct Cli {
|
||||
/// Configuration file to change information about
|
||||
/// pretty printing or project root.
|
||||
#[arg(short, long, value_name = "FILE")]
|
||||
config: Option<PathBuf>,
|
||||
|
||||
/// Turn on the debugging information generated
|
||||
/// by the compiler.
|
||||
#[arg(short, long)]
|
||||
debug: bool,
|
||||
|
||||
/// Show warning messages
|
||||
#[arg(short, long)]
|
||||
warning: bool,
|
||||
|
||||
#[command(subcommand)]
|
||||
command: Command,
|
||||
}
|
||||
|
||||
#[derive(Subcommand)]
|
||||
enum Command {
|
||||
/// Check a file
|
||||
#[clap(aliases = &["c"])]
|
||||
Check { file: String },
|
||||
|
||||
/// Evaluates Main on Kind2
|
||||
#[clap(aliases = &["e"])]
|
||||
Eval { file: String },
|
||||
|
||||
/// Runs Main on the HVM
|
||||
#[clap(aliases = &["r"])]
|
||||
Run { file: String },
|
||||
|
||||
/// Derives .kind2 files from a .type file
|
||||
#[clap(aliases = &["der"])]
|
||||
Derive { file: String },
|
||||
|
||||
/// Generates a checker (.hvm) for a file
|
||||
#[clap(aliases = &["gc"])]
|
||||
GenChecker { file: String },
|
||||
|
||||
/// Stringifies a file
|
||||
#[clap(aliases = &["s"])]
|
||||
Show { file: String },
|
||||
|
||||
/// Compiles a file to Kindelia (.kdl)
|
||||
#[clap(aliases = &["kdl"])]
|
||||
ToKDL {
|
||||
file: String,
|
||||
/// If given, a namespace that goes before each compiled name. Can be at most 10 charaters long.
|
||||
#[clap(long, aliases = &["ns"])]
|
||||
namespace: Option<String>,
|
||||
},
|
||||
|
||||
/// Compiles a file to HVM (.hvm)
|
||||
#[clap(aliases = &["hvm"])]
|
||||
ToHVM { file: String },
|
||||
|
||||
/// Watch for file changes and then
|
||||
/// check when some file change.
|
||||
#[clap(aliases = &["w"])]
|
||||
Watch { file: String },
|
||||
|
||||
|
||||
/// Read eval print loop
|
||||
#[clap(aliases = &["re"])]
|
||||
Repl,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let _ = Cli::parse();
|
||||
}
|
117
src/kind-query/src/core/graph.rs
Normal file
117
src/kind-query/src/core/graph.rs
Normal file
@ -0,0 +1,117 @@
|
||||
use std::{
|
||||
collections::{HashSet},
|
||||
sync::{Arc, RwLock},
|
||||
};
|
||||
|
||||
use dashmap::DashMap;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Edge {
|
||||
pub children: HashSet<u64>,
|
||||
pub parents: HashSet<u64>,
|
||||
pub updated: bool,
|
||||
pub database: u8,
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct DepGraph {
|
||||
pub edges: Arc<DashMap<u64, Arc<RwLock<Edge>>>>,
|
||||
}
|
||||
|
||||
impl DepGraph {
|
||||
pub fn add(&mut self, parent: u64, child: u64, db: u8) -> Arc<RwLock<Edge>> {
|
||||
let edges = self.edges.clone();
|
||||
// I'm not sure on how DashMap drops the Shard guard
|
||||
// so it forces some drop I think.
|
||||
{
|
||||
if parent != child {
|
||||
let entry_arc = edges.entry(parent).or_default();
|
||||
let mut entry = entry_arc.write().unwrap();
|
||||
entry.children.insert(child);
|
||||
entry.database = db;
|
||||
}
|
||||
}
|
||||
{
|
||||
let entry_arc = edges.entry(child).or_default();
|
||||
let mut entry = entry_arc.write().unwrap();
|
||||
if parent != child {
|
||||
entry.parents.insert(parent);
|
||||
}
|
||||
entry_arc.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_single(&self, child: u64, db: u8) -> Arc<RwLock<Edge>> {
|
||||
let edges = self.edges.clone();
|
||||
let entry_c = edges.entry(child).or_default();
|
||||
let mut entry = entry_c.write().unwrap();
|
||||
entry.database = db;
|
||||
entry_c.clone()
|
||||
}
|
||||
|
||||
pub fn updated(&self, node_id: u64) -> bool {
|
||||
if let Some(res) = self.edges.get(&node_id) {
|
||||
let entry = res.read().unwrap();
|
||||
entry.updated
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove_direct_child(&self, node_id: u64) -> HashSet<u64> {
|
||||
let edges = self.edges.clone();
|
||||
let mut children = HashSet::new();
|
||||
edges.entry(node_id).and_modify(|node| {
|
||||
let mut node = node.write().unwrap();
|
||||
children = node.children.clone();
|
||||
node.children = HashSet::new();
|
||||
});
|
||||
for child_id in &children {
|
||||
edges.entry(*child_id).and_modify(|child| {
|
||||
let mut child = child.write().unwrap();
|
||||
child.parents.remove(&node_id);
|
||||
});
|
||||
}
|
||||
children
|
||||
}
|
||||
|
||||
|
||||
pub fn remove(&self, node_id: u64, dangling: bool) -> Vec<u64> {
|
||||
let mut to_delete = Vec::new();
|
||||
{
|
||||
let edges = self.edges.clone();
|
||||
let mut children = HashSet::new();
|
||||
let mut parents = HashSet::new();
|
||||
|
||||
edges.entry(node_id).and_modify(|node| {
|
||||
let node = node.read().unwrap();
|
||||
children = node.children.clone();
|
||||
parents = node.parents.clone();
|
||||
});
|
||||
|
||||
if dangling && parents.len() != 0 {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
for parent_id in parents {
|
||||
edges.entry(parent_id).and_modify(|parent| {
|
||||
let mut parent = parent.write().unwrap();
|
||||
parent.updated = true;
|
||||
parent.children.remove(&node_id);
|
||||
});
|
||||
}
|
||||
|
||||
for child_id in children {
|
||||
edges.entry(child_id).and_modify(|child| {
|
||||
let mut child = child.write().unwrap();
|
||||
child.parents.remove(&node_id);
|
||||
if child.parents.len() == 0 {
|
||||
to_delete.push(child_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
edges.remove(&node_id);
|
||||
}
|
||||
to_delete
|
||||
}
|
||||
}
|
2
src/kind-query/src/core/mod.rs
Normal file
2
src/kind-query/src/core/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
pub mod graph;
|
||||
pub mod store;
|
86
src/kind-query/src/core/store.rs
Normal file
86
src/kind-query/src/core/store.rs
Normal file
@ -0,0 +1,86 @@
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use crate::core::graph::{DepGraph, Edge};
|
||||
|
||||
pub trait Session: Clone {
|
||||
fn delete_from_cache(&self, node_id: u64, db_idx: u8);
|
||||
|
||||
fn dependency_graph(&self) -> DepGraph;
|
||||
|
||||
fn get_parent(&self) -> Option<u64>;
|
||||
|
||||
fn set_parent(&mut self, hash: u64);
|
||||
|
||||
fn delete(&self, node_id: u64) {
|
||||
let graph = self.dependency_graph();
|
||||
let edge = graph.edges.get(&node_id).map(|arc| arc.read().unwrap().database);
|
||||
if let Some(db_idx) = edge {
|
||||
let other_ones = graph.remove(node_id, false);
|
||||
self.delete_from_cache(node_id, db_idx);
|
||||
for other in other_ones {
|
||||
self.delete(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn create_edge(&self, child_hash: u64, db_idx: u8) -> Arc<RwLock<Edge>> {
|
||||
let mut graph = self.dependency_graph();
|
||||
if let Some(parent) = self.get_parent() {
|
||||
graph.add(parent, child_hash, db_idx)
|
||||
} else {
|
||||
graph.add_single(child_hash, db_idx)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_or_create_node(&self, child_hash: u64, db_idx: u8) -> Arc<RwLock<Edge>> {
|
||||
let graph = self.dependency_graph();
|
||||
let res = graph.edges.get(&child_hash);
|
||||
if let Some(edge) = res {
|
||||
edge.clone()
|
||||
} else {
|
||||
graph.add_single(child_hash, db_idx)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_query_memoized<T: Clone>(&self, child_hash: u64, db: std::sync::Arc<dashmap::DashMap<u64, T>>, db_idx: u8, fun: impl FnOnce(&Self) -> T) -> (T, bool) {
|
||||
let graph = self.dependency_graph();
|
||||
|
||||
self.create_edge(child_hash, db_idx);
|
||||
|
||||
if let Some(res) = db.get(&child_hash).map(|x| x.clone()) {
|
||||
if !graph.updated(child_hash) {
|
||||
return (res.clone(), true);
|
||||
}
|
||||
}
|
||||
|
||||
let mut ctx = self.clone();
|
||||
ctx.set_parent(child_hash);
|
||||
let res = fun(&ctx);
|
||||
db.insert(child_hash, res.clone());
|
||||
|
||||
(res, false)
|
||||
}
|
||||
|
||||
fn run_query_flat<T>(&self, child_hash: u64, fun: impl FnOnce(&Self) -> T) -> T
|
||||
where
|
||||
T: Clone,
|
||||
{
|
||||
// TODO: DbIDX sohudl be NONE \/
|
||||
let edge = self.create_edge(child_hash, 255);
|
||||
let children = self.dependency_graph().remove_direct_child(child_hash);
|
||||
|
||||
let mut ctx = self.clone();
|
||||
ctx.set_parent(child_hash);
|
||||
let res = fun(&ctx);
|
||||
|
||||
let new_children = edge.read().unwrap().children.clone();
|
||||
|
||||
let diff = children.difference(&new_children);
|
||||
|
||||
for diff_hash in diff {
|
||||
self.delete(*diff_hash);
|
||||
}
|
||||
|
||||
res
|
||||
}
|
||||
}
|
@ -1,93 +0,0 @@
|
||||
use std::{collections::HashSet, sync::{Arc, Condvar, Mutex}};
|
||||
|
||||
use dashmap::DashMap;
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
pub struct Edge {
|
||||
pub children: HashSet<u64>,
|
||||
pub parents: HashSet<u64>,
|
||||
pub hash: u64,
|
||||
pub updated: bool,
|
||||
pub database: u8,
|
||||
pub computing: Mutex<()>
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct DepGraph {
|
||||
pub edges: Arc<DashMap<u64, Edge>>,
|
||||
}
|
||||
|
||||
impl DepGraph {
|
||||
pub fn add(&mut self, parent: u64, child: u64, db: u8) {
|
||||
let edges = self.edges.clone();
|
||||
{
|
||||
let mut entry = edges.entry(parent).or_default();
|
||||
entry.children.insert(child);
|
||||
entry.database = db;
|
||||
}
|
||||
{
|
||||
let mut entry = edges.entry(child).or_default();
|
||||
entry.parents.insert(parent);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_single(&mut self, child: u64, db: u8) {
|
||||
let edges = self.edges.clone();
|
||||
let mut entry = edges.entry(child).or_default();
|
||||
entry.database = db;
|
||||
}
|
||||
|
||||
pub fn updated(&self, node_id:u64) -> bool {
|
||||
if let Some(res) = self.edges.get(&node_id) {
|
||||
res.updated
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, node_id: u64, dangling: bool) -> Vec<u64> {
|
||||
let mut to_delete = Vec::new();
|
||||
{
|
||||
let edges = self.edges.clone();
|
||||
let mut children = HashSet::new();
|
||||
let mut parents = HashSet::new();
|
||||
|
||||
edges.entry(node_id).and_modify(|node| {
|
||||
children = node.children.clone();
|
||||
parents = node.parents.clone();
|
||||
});
|
||||
|
||||
if dangling && parents.len() != 0 {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
for parent_id in parents {
|
||||
edges.entry(parent_id).and_modify(|parent| {
|
||||
parent.updated = true;
|
||||
parent.children.remove(&node_id);
|
||||
});
|
||||
}
|
||||
|
||||
for child_id in children {
|
||||
edges.entry(child_id).and_modify(|child| {
|
||||
child.parents.remove(&node_id);
|
||||
if child.parents.len() == 0 {
|
||||
to_delete.push(child_id);
|
||||
}
|
||||
});
|
||||
}
|
||||
edges.remove(&node_id);
|
||||
}
|
||||
to_delete
|
||||
}
|
||||
|
||||
pub fn set_hash(&mut self, node_id: u64, hash: u64) {
|
||||
let edges = self.edges.clone();
|
||||
edges.entry(node_id).and_modify(|node| {
|
||||
if node.hash != hash {
|
||||
node.hash = hash;
|
||||
node.updated = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
@ -1,40 +1,17 @@
|
||||
pub mod graph;
|
||||
pub mod query;
|
||||
pub mod session;
|
||||
pub mod store;
|
||||
pub mod core;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::{rc::Rc};
|
||||
|
||||
use kind_macros::make_provider;
|
||||
use rayon::prelude::{IntoParallelRefIterator, ParallelIterator};
|
||||
use crate::store::Session;
|
||||
|
||||
#[make_provider]
|
||||
pub trait Teste {
|
||||
#[input_node]
|
||||
fn fib(&self, kek: u64) -> Box<u64>;
|
||||
}
|
||||
|
||||
pub fn teste() {
|
||||
let provider = TesteProvider {
|
||||
fib: |db, c| {
|
||||
if c > 10 {
|
||||
println!("Computing {}", c);
|
||||
let t = (1..10).collect::<Vec<u64>>().par_iter().map(|x| *db.fib(c-x)).sum();
|
||||
println!("Finalized {}", c);
|
||||
Box::new(t)
|
||||
} else {
|
||||
Box::new(c)
|
||||
}
|
||||
},
|
||||
};
|
||||
let db = TesteDatabase::new(Arc::new(provider));
|
||||
println!("Res {}", db.fib(15));
|
||||
println!("Res {}", db.fib(2));
|
||||
println!("Res {}", db.fib(1));
|
||||
println!("Res {}", db.fib(0));
|
||||
db.delete(1);
|
||||
println!("Res {}", db.fib(2));
|
||||
println!("Res {}", db.fib(1));
|
||||
println!("Res {}", db.fib(0));
|
||||
use kind_tree::{concrete, desugared};
|
||||
|
||||
#[kind_macros::make_provider]
|
||||
pub trait Query {
|
||||
#[memoize]
|
||||
fn parse_book(&self, code: String) -> Rc<concrete::Book>;
|
||||
|
||||
#[memoize]
|
||||
fn desugarize_book(&self, book: concrete::Book) -> Rc<desugared::Book>;
|
||||
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
use std::collections::HashMap;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use kind_report::{Chars, RenderConfig};
|
||||
|
||||
pub struct SessionData {
|
||||
pub loaded_paths: RwLock<HashMap<PathBuf, usize>>,
|
||||
pub loaded_files: RwLock<Vec<(PathBuf, String)>>,
|
||||
pub render_config: RenderConfig<'static>,
|
||||
pub root: PathBuf,
|
||||
}
|
||||
|
||||
impl SessionData {
|
||||
pub fn add_file(&self, path: PathBuf, code: String) -> usize {
|
||||
let mut files = self.loaded_files.write().unwrap();
|
||||
let mut paths = self.loaded_paths.write().unwrap();
|
||||
paths.insert(path.clone(), files.len());
|
||||
files.push((path, code));
|
||||
files.len() - 1
|
||||
}
|
||||
|
||||
pub fn new(root: PathBuf) -> SessionData {
|
||||
SessionData {
|
||||
loaded_paths: RwLock::new(HashMap::new()),
|
||||
loaded_files: RwLock::new(Vec::new()),
|
||||
render_config: RenderConfig {
|
||||
indent: 2,
|
||||
chars: Chars::unicode(),
|
||||
},
|
||||
root,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Session = Arc<SessionData>;
|
@ -1,63 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::graph::DepGraph;
|
||||
|
||||
pub trait Session : Clone {
|
||||
fn delete_from_cache(&self, node_id: u64, db_idx: u8);
|
||||
|
||||
fn dependency_graph(&self) -> DepGraph;
|
||||
|
||||
fn get_parent(&self) -> Option<u64>;
|
||||
|
||||
fn set_parent(&mut self, hash: u64);
|
||||
|
||||
fn delete(&self, node_id: u64) {
|
||||
let edge = {self.dependency_graph().edges.get(&node_id).map(|x| x.database)};
|
||||
if let Some(db_idx) = edge {
|
||||
let other_ones = self.dependency_graph().remove(node_id, false);
|
||||
self.delete_from_cache(node_id, db_idx);
|
||||
for other in other_ones {
|
||||
self.delete(other);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_query<T: Clone>(&self, child_hash: u64, db: std::sync::Arc<dashmap::DashMap<u64,T >>, db_idx: u8, fun: impl FnOnce(&Self) -> T) -> T {
|
||||
let mut graph = self.dependency_graph();
|
||||
if let Some(parent) = self.get_parent() {
|
||||
graph.add(
|
||||
parent,
|
||||
child_hash,
|
||||
db_idx
|
||||
);
|
||||
} else {
|
||||
graph.add_single(
|
||||
child_hash,
|
||||
db_idx
|
||||
);
|
||||
}
|
||||
let m = {
|
||||
let res = graph.edges.get(&child_hash).unwrap();
|
||||
res.computing.lock().unwrap()
|
||||
};
|
||||
let result = db.get(&child_hash).map(|x| x.clone());
|
||||
if let Some(res) = result {
|
||||
if graph.updated(child_hash) {
|
||||
let mut ctx = self.clone();
|
||||
ctx.set_parent(child_hash);
|
||||
let res = fun(&ctx);
|
||||
db.insert(child_hash, res.clone());
|
||||
res
|
||||
} else {
|
||||
res.clone()
|
||||
}
|
||||
} else {
|
||||
let mut ctx = self.clone();
|
||||
ctx.set_parent(child_hash);
|
||||
let res = fun(&ctx);
|
||||
db.insert(child_hash, res.clone());
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user