diff --git a/dedukti-parse/examples/README.md b/dedukti-parse/examples/README.md
new file mode 100644
index 0000000..8b1aef4
--- /dev/null
+++ b/dedukti-parse/examples/README.md
@@ -0,0 +1,23 @@
+When we have a theory with many definitions that are used exactly one
+(after having been declared), then we might want to eliminate these definitions
+by inlining them, so that the signature during type checking remains small.
+
+For this, we have to traverse our theory file twice:
+first to find out which definitions are used exactly once, and
+second to eliminate these definitions and to inline them.
+
+The first step is done by `symcount`.
+It actually counts for every constant how often it is used.
+A count of 0 means that the constant was declared, but never used.
+
+ cargo run --release --example symcount -- in.dk > in.symcount
+
+To get those constants that are used exactly once, we use some UNIX magic:
+
+ grep "^1[^0-9]" in.symcount | sed 's/^1.//' > in.inline
+
+Finally, we use `inline`.
+To save memory, this will forget any definition that has been inlined once,
+so you currently cannot use this to inline definitions that are used more than once!
+
+ cargo run --release --example inline -- in.dk in.inline > in.inlined.dk
diff --git a/dedukti-parse/examples/inline.rs b/dedukti-parse/examples/inline.rs
index 704ac42..66a28cc 100644
--- a/dedukti-parse/examples/inline.rs
+++ b/dedukti-parse/examples/inline.rs
@@ -1,10 +1,10 @@
use core::hash::Hash;
-use dedukti_parse::{term, Command, Intro, Lazy, Symb};
+use dedukti_parse::{term, Command, Intro, Strict, Symb};
use std::collections::{HashMap, HashSet};
-fn map_atoms(t: term::Term, f: &impl Fn(A) -> term::Term) -> term::Term {
+fn map_atoms(t: term::Term, f: &mut impl FnMut(A) -> term::Term) -> term::Term {
use term::AppH;
- let args = t.args.into_iter().map(|a| map_atoms(a, f));
+ let args = t.args.into_iter().map(|a| map_atoms(a, f)).collect();
let head = match t.head {
AppH::Atom(a) => {
let b = f(a);
@@ -18,61 +18,56 @@ fn map_atoms(t: term::Term, f: &impl Fn(A) -> term::Term) -
ty.map(|t| Box::new(map_atoms(*t, f))),
Box::new(map_atoms(*tm, f)),
),
- AppH::Prod(v, ty, tm) => AppH::Prod(
- v,
- Box::new(map_atoms(*ty, f)),
- Box::new(map_atoms(*tm, f)),
- ),
+ AppH::Prod(v, ty, tm) => {
+ AppH::Prod(v, Box::new(map_atoms(*ty, f)), Box::new(map_atoms(*tm, f)))
+ }
};
- let args = args.collect();
term::Term { head, args }
}
fn subst(
- map: &HashMap>,
+ map: &mut HashMap>,
t: term::Term,
) -> term::Term {
- map_atoms(t, &|a| match map.get(&a) {
+ map_atoms(t, &mut |a| match map.remove(&a) {
None => term::Term {
head: term::AppH::Atom(a),
args: Vec::new(),
},
- Some(t) => t.clone(),
+ Some(t) => t,
})
}
fn main() -> std::io::Result<()> {
- let mut map = HashMap::new();
-
- use std::fs::File;
- use std::io::{BufRead, BufReader};
+ let mut map: HashMap, _> = HashMap::new();
let args: Vec = std::env::args().collect();
- let set: Result, _> = BufReader::new(File::open(&args[2])?).lines().collect();
- let set = set?;
+ let to_inline = std::fs::read_to_string(&args[2])?;
+ let set: HashSet<&str> = to_inline.lines().collect();
- let file = File::open(&args[1])?;
- let reader = BufReader::new(file);
+ let file = std::fs::read_to_string(&args[1])?;
- let cmds = Lazy::<_, _, String>::new(reader.lines().map(|l| l.unwrap()));
+ let cmds = Strict::<_, _, &str>::new(&file);
for cmd in cmds {
let cmd = cmd.unwrap();
//println!("{cmd:?}");
match cmd {
- Command::Intro(name, args, Intro::Definition(_, Some(tm)) | Intro::Theorem(_, tm)) if set.contains(&name) && args.is_empty() => {
- map.insert(Symb::new(name), subst(&map, tm));
+ Command::Intro(name, args, Intro::Definition(_, Some(tm)) | Intro::Theorem(_, tm))
+ if set.contains(&name) && args.is_empty() =>
+ {
+ let tm = subst(&mut map, tm);
+ map.insert(Symb::new(name), tm);
}
Command::Intro(name, args, intro) => {
let args = args
.into_iter()
- .map(|(v, ty)| (v, subst(&map, ty)))
+ .map(|(v, ty)| (v, subst(&mut map, ty)))
.collect();
let intro = intro
- .map_type(|t| subst(&map, t))
- .map_term(|t| subst(&map, t));
+ .map_type(|t| subst(&mut map, t))
+ .map_term(|t| subst(&mut map, t));
println!("{}.", Command::Intro(name, args, intro));
-
}
cmd @ Command::Rules(..) => println!("{cmd}."),
}