mirror of
https://github.com/HigherOrderCO/Kind.git
synced 2024-08-17 00:20:32 +03:00
WIP, starting working with KindAI soon
This commit is contained in:
parent
bf2d62a572
commit
3062ce4b6e
@ -1,3 +1,14 @@
|
||||
/// Performs the logical AND operation on two boolean values.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first boolean value.
|
||||
/// * `b` - The second boolean value.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// Returns `true` if both `a` and `b` are `true`, otherwise returns `false`.
|
||||
|
||||
use Bool/{true,false,and}
|
||||
|
||||
and
|
||||
|
@ -1,3 +1,9 @@
|
||||
/// Represents the 'false' boolean value.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The 'false' value of type Bool.
|
||||
|
||||
false
|
||||
: Bool
|
||||
|
||||
|
@ -1,8 +1,23 @@
|
||||
/// Conditional expression for Bool values.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `P` - The type of the result.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `b` - The boolean condition.
|
||||
/// * `t` - The value to return if the condition is true.
|
||||
/// * `f` - The value to return if the condition is false.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// Returns `t` if `b` is true, otherwise returns `f`.
|
||||
|
||||
use Bool/{true,false}
|
||||
|
||||
if
|
||||
if <P: *>
|
||||
- b: Bool
|
||||
- P: *
|
||||
- t: P
|
||||
- f: P
|
||||
: P
|
||||
|
@ -1,3 +1,16 @@
|
||||
/// Provides a way to pattern match on boolean values.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `P` - The motive of the elimination, a type family indexed by Bool.
|
||||
/// * `t` - The case for when the boolean is true.
|
||||
/// * `f` - The case for when the boolean is false.
|
||||
/// * `b` - The boolean value to match on.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The result of the elimination, which has type `(P b)`.
|
||||
|
||||
use Bool/{true,false}
|
||||
|
||||
match
|
||||
|
@ -1,3 +1,13 @@
|
||||
/// Negates a boolean value.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `x` - The boolean value to negate.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The negation of the input boolean.
|
||||
|
||||
use Bool/{true,false}
|
||||
|
||||
not
|
||||
|
@ -1,3 +1,14 @@
|
||||
/// Performs the logical OR operation on two boolean values.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first boolean value.
|
||||
/// * `b` - The second boolean value.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The result of `a OR b`.
|
||||
|
||||
use Bool/{true,false}
|
||||
|
||||
or
|
||||
@ -8,4 +19,4 @@ or
|
||||
match a {
|
||||
true: true
|
||||
false: b
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
apply <A: *> <B: *> <a: A> <b: B>
|
||||
use Equal/refl
|
||||
|
||||
apply <A: *> <B: *> <a: A> <b: A>
|
||||
- f: A -> B
|
||||
- e: (Equal A a b)
|
||||
: (Equal B (f a) (f b))
|
||||
|
||||
match e {
|
||||
Equal/refl: ~λPλe(e (f e.a))
|
||||
}: (Equal B (f a) (f b))
|
||||
refl: ~λPλe(e (f e.a))
|
||||
}: (Equal B (f e.a) (f e.b))
|
||||
|
@ -1,3 +1,14 @@
|
||||
/// Computes the logical AND of all boolean values in a list.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `list` - A list of boolean values.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// Returns `true` if all elements in the list are `true`, otherwise `false`.
|
||||
/// An empty list returns `true` (vacuous truth).
|
||||
|
||||
use List/{cons,nil}
|
||||
use Bool/{true}
|
||||
|
||||
@ -8,4 +19,4 @@ and
|
||||
fold list {
|
||||
cons: (Bool/and list.head list.tail)
|
||||
nil: true
|
||||
}
|
||||
}
|
@ -7,9 +7,11 @@ filter <A>
|
||||
: (List A)
|
||||
|
||||
match list {
|
||||
nil: (nil _)
|
||||
cons: match result = (cond list.head) {
|
||||
true: (cons _ list.head (filter _ cond list.tail))
|
||||
false: (filter _ cond list.tail)
|
||||
}
|
||||
cons:
|
||||
let test = (cond list.head)
|
||||
let head = match test { true: (cons _ list.head) false: λx x }: (List A) -> (List A)
|
||||
let tail = (filter _ cond list.tail)
|
||||
(head tail)
|
||||
nil:
|
||||
(nil _)
|
||||
}
|
||||
|
@ -3,14 +3,16 @@ use List/{cons,nil}
|
||||
use Maybe/{some,none}
|
||||
|
||||
find <A>
|
||||
- cond: A -> Bool
|
||||
- fn: A -> Bool
|
||||
- xs: (List A)
|
||||
: (Maybe A)
|
||||
|
||||
match xs {
|
||||
cons: match result = (cond xs.head) {
|
||||
true: (some _ xs.head)
|
||||
false: (find _ cond xs.tail)
|
||||
}
|
||||
cons:
|
||||
let result = (fn xs.head)
|
||||
match result {
|
||||
true: (some _ xs.head)
|
||||
false: (find _ fn xs.tail)
|
||||
}
|
||||
nil: (none _)
|
||||
}
|
||||
|
@ -1,3 +1,19 @@
|
||||
/// Maps a function over a list, transforming each element.
|
||||
///
|
||||
/// # Parameters
|
||||
///
|
||||
/// * `A` - The type of elements in the input list.
|
||||
/// * `B` - The type of elements in the output list.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `xs` - The input list of type (List A).
|
||||
/// * `fn` - A function that transforms elements from type A to type B.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// A new list of type (List B) with the function applied to each element.
|
||||
|
||||
use List/{cons,nil}
|
||||
|
||||
map <A> <B>
|
||||
@ -5,7 +21,11 @@ map <A> <B>
|
||||
- fn: A -> B
|
||||
: (List B)
|
||||
|
||||
fold xs {
|
||||
cons: (cons _ (fn xs.head) xs.tail)
|
||||
nil: (nil _)
|
||||
match xs {
|
||||
cons:
|
||||
let head = (fn xs.head)
|
||||
let tail = (List/map _ _ xs.tail fn)
|
||||
(cons _ head tail)
|
||||
nil:
|
||||
(nil _)
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
/// Performs a logical OR operation on a list of booleans.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `list` - A list of boolean values.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The result of applying OR to all elements in the list.
|
||||
|
||||
use List/{cons,nil}
|
||||
use Bool/{false}
|
||||
|
||||
@ -8,4 +18,4 @@ or
|
||||
fold list {
|
||||
cons: (Bool/or list.head list.tail)
|
||||
nil: false
|
||||
}
|
||||
}
|
@ -1,3 +1,14 @@
|
||||
/// Adds two natural numbers.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first natural number.
|
||||
/// * `b` - The second natural number.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The sum of `a` and `b`.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
|
||||
add
|
||||
|
@ -1,3 +1,13 @@
|
||||
/// Doubles a natural number.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `n` - The natural number to be doubled.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// The result of doubling `n`.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
|
||||
double
|
||||
|
@ -1,3 +1,14 @@
|
||||
/// Checks if two natural numbers are equal.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first natural number.
|
||||
/// * `b` - The second natural number.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// `true` if `a` and `b` are equal, `false` otherwise.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/// Computes half of a natural number, rounding down.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `n` - The natural number to halve.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// Half of `n`, rounded down to the nearest natural number.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// * `(half 0) = 0`
|
||||
/// * `(half 1) = 0`
|
||||
/// * `(half 2) = 1`
|
||||
/// * `(half 3) = 1`
|
||||
/// * `(half 4) = 2`
|
||||
|
||||
use Nat/{succ,zero}
|
||||
|
||||
half
|
||||
|
24
book/Nat/is_even.kind2
Normal file
24
book/Nat/is_even.kind2
Normal file
@ -0,0 +1,24 @@
|
||||
/// Determines if a natural number is even.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `n` - The natural number to check.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// `true` if `n` is even, `false` otherwise.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
is_even
|
||||
- n: Nat
|
||||
: Bool
|
||||
|
||||
match n {
|
||||
succ: match n.pred {
|
||||
succ: (is_even n.pred.pred)
|
||||
zero: false
|
||||
}
|
||||
zero: true
|
||||
}
|
18
book/Nat/is_gte.kind2
Normal file
18
book/Nat/is_gte.kind2
Normal file
@ -0,0 +1,18 @@
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
is_gtn_or_eql
|
||||
- a: Nat
|
||||
- b: Nat
|
||||
: Bool
|
||||
|
||||
match a {
|
||||
zero: match b {
|
||||
zero: true
|
||||
succ: false
|
||||
}
|
||||
succ: match b {
|
||||
zero: true
|
||||
succ: (is_gtn_or_eql a.pred b.pred)
|
||||
}
|
||||
}
|
@ -1,3 +1,14 @@
|
||||
/// Checks if the first natural number is greater than the second.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first natural number.
|
||||
/// * `b` - The second natural number.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// `true` if `a` is greater than `b`, `false` otherwise.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
|
23
book/Nat/is_lte.kind2
Normal file
23
book/Nat/is_lte.kind2
Normal file
@ -0,0 +1,23 @@
|
||||
/// Checks if a natural number is less than or equal to another.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `a` - The first natural number.
|
||||
/// * `b` - The second natural number.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// `true` if `a` is less than or equal to `b`, `false` otherwise.
|
||||
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
is_lte
|
||||
- a: Nat
|
||||
- b: Nat
|
||||
: Bool
|
||||
|
||||
match is_lt = (Nat/is_ltn a b) {
|
||||
true: true
|
||||
false: (Nat/equal a b)
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
use Nat/{succ,zero}
|
||||
use Bool/{true,false}
|
||||
|
||||
is_ltn_or_eql
|
||||
- a: Nat
|
||||
- b: Nat
|
||||
: Bool
|
||||
|
||||
match is_lt = (Nat/is_ltn a b) {
|
||||
true: true
|
||||
false: (Nat/equal a b)
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
use Nat/{succ,zero,half,double}
|
||||
|
||||
bft (n: Nat) :
|
||||
(Equal Nat (half (double n)) n) =
|
||||
match n {
|
||||
succ:
|
||||
let ind = (bft n.pred)
|
||||
let prf = (Equal/apply _ _ _ _ succ ind)
|
||||
prf
|
||||
zero:
|
||||
{=}
|
||||
}
|
||||
bft
|
||||
- n: Nat
|
||||
: (Equal Nat (half (double n)) n)
|
||||
|
||||
match n {
|
||||
succ: (Equal/apply/ succ (bft n.pred))
|
||||
zero: {=}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
use Nat/{succ,zero}
|
||||
|
||||
mul
|
||||
- a: Nat
|
||||
- b: Nat
|
||||
: Nat
|
||||
|
||||
match b {
|
||||
succ: (Nat/add a (Nat/mul a b.pred))
|
||||
zero: zero
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
use Pair/{new}
|
||||
|
||||
fst <A> <B> (p: (Pair A B)) : A =
|
||||
match p {
|
||||
new: p.fst
|
||||
}
|
||||
fst <A> <B>
|
||||
- p: (Pair A B)
|
||||
: A
|
||||
|
||||
match p {
|
||||
new: p.fst
|
||||
}
|
||||
|
@ -1,6 +1,10 @@
|
||||
use Pair/{new}
|
||||
|
||||
get <A> <B> <P> (p: (Pair A B)) (f: A -> B -> P) : P =
|
||||
match p {
|
||||
new: (f p.fst p.snd)
|
||||
}
|
||||
get <A> <B> <P>
|
||||
- p: (Pair A B)
|
||||
- f: A -> B -> P
|
||||
: P
|
||||
|
||||
match p {
|
||||
new: (f p.fst p.snd)
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
match <A> <B>
|
||||
(P: (Pair A B) -> *)
|
||||
(new: ∀(fst: A) ∀(snd: B) (P (Pair/new A B fst snd)))
|
||||
(pair: (Pair A B))
|
||||
: (P pair) =
|
||||
(~pair P new)
|
||||
- P: (Pair A B) -> *
|
||||
- new: ∀(fst: A) ∀(snd: B) (P (Pair/new A B fst snd))
|
||||
- pair: (Pair A B)
|
||||
: (P pair)
|
||||
|
||||
(~pair P new)
|
||||
|
@ -1,2 +1,6 @@
|
||||
new <A> <B> (a: A) (b: B) : (Pair A B) =
|
||||
~λP λnew (new a b)
|
||||
new <A> <B>
|
||||
- a: A
|
||||
- b: B
|
||||
: (Pair A B)
|
||||
|
||||
~λP λnew (new a b)
|
||||
|
@ -1,6 +1,9 @@
|
||||
use Pair/{new}
|
||||
|
||||
snd <A> <B> (p: (Pair A B)) : B =
|
||||
match p {
|
||||
new: p.snd
|
||||
}
|
||||
snd <A> <B>
|
||||
- p: (Pair A B)
|
||||
: B
|
||||
|
||||
match p {
|
||||
new: p.snd
|
||||
}
|
||||
|
12
book/Term/_.kind2
Normal file
12
book/Term/_.kind2
Normal file
@ -0,0 +1,12 @@
|
||||
/// Defines the type for untyped lambda calculus terms using Higher-Order Abstract Syntax (HOAS).
|
||||
///
|
||||
/// # Constructors
|
||||
///
|
||||
/// * `app` - Represents function application.
|
||||
/// * `lam` - Represents lambda abstraction.
|
||||
/// * `var` - Represents a variable.
|
||||
|
||||
data Term
|
||||
| lam (bod: Term -> Term)
|
||||
| app (fun: Term) (arg: Term)
|
||||
| var (idx: U48)
|
19
book/Term/app.kind2
Normal file
19
book/Term/app.kind2
Normal file
@ -0,0 +1,19 @@
|
||||
/// Constructs an application term in the untyped lambda calculus.
|
||||
///
|
||||
/// This function creates a new Term representing the application of one term to another.
|
||||
///
|
||||
/// # Inputs
|
||||
///
|
||||
/// * `fun` - The function term (the term being applied).
|
||||
/// * `arg` - The argument term (the term being passed to the function).
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// A new Term representing the application of `fun` to `arg`.
|
||||
|
||||
app
|
||||
- fun: Term
|
||||
- arg: Term
|
||||
: Term
|
||||
|
||||
~λP λlam λapp λvar (app fun arg)
|
17
book/Term/lam.kind2
Normal file
17
book/Term/lam.kind2
Normal file
@ -0,0 +1,17 @@
|
||||
/// Constructs a lambda abstraction term in the untyped lambda calculus.
|
||||
///
|
||||
/// This function creates a new Term representing a lambda abstraction.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `bod` - A function that takes a Term and returns a Term, representing the body of the lambda abstraction.
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// A new Term representing the lambda abstraction.
|
||||
|
||||
lam
|
||||
- bod: Term -> Term
|
||||
: Term
|
||||
|
||||
~λP λlam λapp λvar (lam bod)
|
17
book/Term/var.kind2
Normal file
17
book/Term/var.kind2
Normal file
@ -0,0 +1,17 @@
|
||||
/// Constructs a variable term in the untyped lambda calculus.
|
||||
///
|
||||
/// This function creates a new Term representing a variable with a given index.
|
||||
///
|
||||
/// # Input
|
||||
///
|
||||
/// * `idx` - The index of the variable (represented as a U48).
|
||||
///
|
||||
/// # Output
|
||||
///
|
||||
/// A new Term representing the variable with the given index.
|
||||
|
||||
var
|
||||
- idx: U48
|
||||
: Term
|
||||
|
||||
~λP λlam λapp λvar (var idx)
|
@ -1,2 +1,11 @@
|
||||
/// Defines the Unit type, which has only one inhabitant.
|
||||
///
|
||||
/// The Unit type is often used to represent a trivial or empty type,
|
||||
/// or as a placeholder when no meaningful value is needed.
|
||||
///
|
||||
/// # Constructor
|
||||
///
|
||||
/// * `new` - The single constructor for the Unit type.
|
||||
|
||||
data Unit
|
||||
| new
|
||||
|
@ -8,7 +8,12 @@ concat <T>
|
||||
- ys: (Vector T ys_len)
|
||||
: (Vector T (add xs_len ys_len))
|
||||
|
||||
match xs {
|
||||
cons: (cons _ (add xs.len ys_len) xs.head (concat _ xs.len ys_len xs.tail ys))
|
||||
nil: ys
|
||||
}: (Vector T (add xs.len ys_len))
|
||||
(Vector/match _ _ λxs.len(_)
|
||||
λxs.lenλxs.headλxs.tail(cons _ (add xs.len ys_len) xs.head (concat _ xs.len ys_len xs.tail ys))
|
||||
ys
|
||||
xs)
|
||||
|
||||
//match xs {
|
||||
//cons: (cons _ (add xs.len ys_len) xs.head (concat _ xs.len ys_len xs.tail ys))
|
||||
//nil: ys
|
||||
//}: (Vector T (add xs.len ys_len))
|
||||
|
8
book/Vector/match.kind2
Normal file
8
book/Vector/match.kind2
Normal file
@ -0,0 +1,8 @@
|
||||
match <T> <len: Nat>
|
||||
- P: ∀(l: Nat) (Vector T l) -> *
|
||||
- c: ∀(l: Nat) ∀(head: T) ∀(tail: (Vector T l)) (P (Nat/succ l) (Vector/cons T l head tail))
|
||||
- n: (P Nat/zero (Vector/nil T))
|
||||
- v: (Vector T len)
|
||||
: (P len v)
|
||||
|
||||
(~v P c n)
|
@ -39,14 +39,14 @@ impl Info {
|
||||
pub fn pretty(&self, book: &Book) -> String {
|
||||
match self {
|
||||
Info::Found { nam, typ, ctx } => {
|
||||
let msg = format!("?{} :: {}", nam, typ.show());
|
||||
let msg = format!("?{} : {}", nam, typ.show());
|
||||
let mut ctx_str = String::new();
|
||||
for x in ctx.iter() {
|
||||
if let Term::Ann { chk: _, val, typ } = x.clean() {
|
||||
ctx_str.push_str(&format!("\n- {}: {}", val.show(), typ.show()));
|
||||
}
|
||||
}
|
||||
format!("\x1b[1mFOUND:\x1b[0m {}{}", msg, ctx_str)
|
||||
format!("\x1b[1mGOAL\x1b[0m {}{}", msg, ctx_str)
|
||||
},
|
||||
Info::Error { exp, det, bad, src } => {
|
||||
let exp = format!("- expected: \x1b[32m{}\x1b[0m", exp.show());
|
||||
|
19
src/main.rs
19
src/main.rs
@ -82,6 +82,18 @@ fn load_book(name: &str) -> Book {
|
||||
})
|
||||
}
|
||||
|
||||
fn deps(name: &str) {
|
||||
let mut book = Book::new();
|
||||
let cwd = std::env::current_dir().expect("failed to get current directory");
|
||||
if let Err(e) = book.load(cwd.to_str().unwrap(), name) {
|
||||
eprintln!("{e}");
|
||||
std::process::exit(1);
|
||||
}
|
||||
for dep in book.defs.keys() {
|
||||
println!("{}", dep);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let matches = Command::new("kind2")
|
||||
.about("The Kind2 Programming Language")
|
||||
@ -104,6 +116,9 @@ fn main() {
|
||||
.subcommand(Command::new("compile")
|
||||
.about("Compiles to KINDC")
|
||||
.arg(Arg::new("name").required(true)))
|
||||
.subcommand(Command::new("deps")
|
||||
.about("Lists all dependencies of a symbol")
|
||||
.arg(Arg::new("name").required(true)))
|
||||
.get_matches();
|
||||
|
||||
match matches.subcommand() {
|
||||
@ -124,6 +139,10 @@ fn main() {
|
||||
let name = sub_matches.get_one::<String>("name").expect("required");
|
||||
compile(name);
|
||||
}
|
||||
Some(("deps", sub_matches)) => {
|
||||
let name = sub_matches.get_one::<String>("name").expect("required");
|
||||
deps(name);
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ impl Term {
|
||||
}
|
||||
|
||||
// Expands implicit calls, applying them to the correct number of metavars.
|
||||
// When a variable name ends with "/", we fill erased arguments with metas.
|
||||
// When a variable name ends with "!", we fill erased arguments with metas.
|
||||
pub fn expand_implicits(&mut self, env: im::Vector<String>, implicit_count: &BTreeMap<String, u64>) {
|
||||
match self {
|
||||
Term::All { era: _, nam, inp, bod } => {
|
||||
|
Loading…
Reference in New Issue
Block a user