Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Proost
Manage
Activity
Members
Labels
Plan
Issues
33
Issue boards
Milestones
Code
Merge requests
18
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package Registry
Model registry
Operate
Terraform modules
Analyze
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
loutr
Proost
Compare revisions
main to 2-term-definitions
Compare revisions
Changes are shown as if the
source
revision was being merged into the
target
revision.
Learn more about comparing revisions.
Source
loutr/proost
Select target project
No results found
2-term-definitions
Select Git revision
Swap
Target
loutr/proost
Select target project
loutr/proost
jeanas/proost
2 results
main
Select Git revision
Show changes
Only incoming changes from source
Include changes to target since source was created
Compare
Commits on Source (4)
feat(term): Add early Term struct + Display trait
· 011ba7b0
v-lafeychine
authored
2 years ago
011ba7b0
feat(term): Early beta-reduction
· 7495353b
v-lafeychine
authored
2 years ago
7495353b
[WIP] feat(term): Improve beta-reduction + Add tests
· 2448ee4e
v-lafeychine
authored
2 years ago
2448ee4e
feat(term): Complete beta-reduction
· 601b10f4
v-lafeychine
authored
2 years ago
601b10f4
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
core/src/command.rs
+1
-1
1 addition, 1 deletion
core/src/command.rs
core/src/lib.rs
+1
-0
1 addition, 0 deletions
core/src/lib.rs
core/src/term.rs
+227
-7
227 additions, 7 deletions
core/src/term.rs
with
229 additions
and
8 deletions
core/src/command.rs
View file @
601b10f4
use
crate
::
Term
;
use
std
::
fmt
::{
Display
,
Formatter
};
#[derive(Clone,
Debug,
PartialEq)]
#[derive(Clone,
Debug,
Eq,
PartialEq)]
pub
enum
Command
{
Define
(
String
,
Term
),
CheckType
(
Term
,
Term
),
...
...
This diff is collapsed.
Click to expand it.
core/src/lib.rs
View file @
601b10f4
#![feature(box_patterns)]
#![feature(box_syntax)]
mod
command
;
...
...
This diff is collapsed.
Click to expand it.
core/src/term.rs
View file @
601b10f4
use
std
::
fmt
::{
Display
,
Formatter
};
#[derive(Clone,
Debug,
PartialEq)]
// TODO: Use derive_more to constraint types (#11)
// struct Index(usize);
// struct Level(usize);
#[derive(Clone,
Debug,
Eq,
PartialEq)]
pub
enum
Term
{
Prop
,
Var
(
usize
),
...
...
@@ -10,15 +14,231 @@ pub enum Term {
Prod
(
Box
<
Term
>
,
Box
<
Term
>
),
}
use
Term
::
*
;
impl
Term
{
/// Apply one step of β-reduction, using leftmost outermost evaluation strategy.
pub
fn
beta_reduction
(
self
)
->
Term
{
match
self
{
App
(
box
Abs
(
_
,
box
t1
),
box
t2
)
=>
t1
.substitute
(
t2
,
1
),
App
(
box
t1
,
box
t2
)
=>
App
(
box
t1
.beta_reduction
(),
box
t2
),
Abs
(
x
,
box
t
)
=>
Abs
(
x
,
box
t
.beta_reduction
()),
_
=>
self
,
}
}
fn
shift
(
self
,
offset
:
usize
,
depth
:
usize
)
->
Term
{
match
self
{
Var
(
i
)
if
i
>
depth
=>
Var
(
i
+
offset
),
App
(
box
t1
,
box
t2
)
=>
App
(
box
t1
.shift
(
offset
,
depth
),
box
t2
.shift
(
offset
,
depth
)),
Abs
(
t1
,
box
t2
)
=>
Abs
(
t1
,
box
t2
.shift
(
offset
,
depth
+
1
)),
Prod
(
t1
,
box
t2
)
=>
Prod
(
t1
,
box
t2
.shift
(
offset
,
depth
+
1
)),
_
=>
self
,
}
}
fn
substitute
(
self
,
rhs
:
Term
,
depth
:
usize
)
->
Term
{
match
self
{
Var
(
i
)
if
i
==
depth
=>
rhs
.shift
(
depth
-
1
,
0
),
Var
(
i
)
if
i
>
depth
=>
Var
(
i
-
1
),
App
(
l
,
r
)
=>
App
(
box
l
.substitute
(
rhs
.clone
(),
depth
),
box
r
.substitute
(
rhs
,
depth
),
),
Abs
(
t
,
term
)
=>
Abs
(
t
,
box
term
.substitute
(
rhs
,
depth
+
1
)),
Prod
(
t
,
term
)
=>
Prod
(
t
,
box
term
.substitute
(
rhs
,
depth
+
1
)),
_
=>
self
,
}
}
}
impl
Display
for
Term
{
fn
fmt
(
&
self
,
f
:
&
mut
Formatter
)
->
std
::
fmt
::
Result
{
match
self
{
Term
::
Prop
=>
write!
(
f
,
"
\u{02119}
"
),
Term
::
Var
(
i
)
=>
write!
(
f
,
"{}"
,
i
),
Term
::
Type
(
i
)
=>
write!
(
f
,
"
\u{1D54B}
({})"
,
i
),
Term
::
App
(
t1
,
t2
)
=>
write!
(
f
,
"({}
)
{}"
,
t1
,
t2
),
Term
::
Abs
(
t1
,
t2
)
=>
write!
(
f
,
"
\u{003BB}
{}
\u{02192}
{}"
,
t1
,
t2
),
Term
::
Prod
(
t1
,
t2
)
=>
write!
(
f
,
"
\u{02200}
{}
\u{02192}
{}"
,
t1
,
t2
),
Prop
=>
write!
(
f
,
"
\u{02119}
"
),
Var
(
i
)
=>
write!
(
f
,
"{}"
,
i
),
Type
(
i
)
=>
write!
(
f
,
"
\u{1D54B}
({})"
,
i
),
App
(
t1
,
t2
)
=>
write!
(
f
,
"({} {}
)
"
,
t1
,
t2
),
Abs
(
t1
,
t2
)
=>
write!
(
f
,
"
\u{003BB}
{}
\u{02192}
{}"
,
t1
,
t2
),
Prod
(
t1
,
t2
)
=>
write!
(
f
,
"
\u{02200}
{}
\u{02192}
{}"
,
t1
,
t2
),
}
}
}
#[cfg(test)]
mod
tests
{
// TODO: Correctly types lambda terms (#9)
use
super
::
Term
::
*
;
#[test]
fn
simple_subst
()
{
// λx.(λy.x y) x
let
term
=
Abs
(
box
Prop
,
box
App
(
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
2
),
box
Var
(
1
))),
box
Var
(
1
),
),
);
// λx.x x
let
reduced
=
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
Var
(
1
)));
assert_eq!
(
term
.beta_reduction
(),
reduced
);
}
#[test]
fn
complex_subst
()
{
// (λa.λb.λc.(a (λd.λe.e (d b) (λ_.c)) (λd.d)) (λa.λb.a b)
let
term
=
App
(
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
App
(
box
App
(
box
Var
(
3
),
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
App
(
box
Var
(
2
),
box
Var
(
4
))),
),
),
),
box
Abs
(
box
Prop
,
box
Var
(
2
)),
),
box
Abs
(
box
Prop
,
box
Var
(
1
)),
),
),
),
),
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
2
),
box
Var
(
1
)))),
);
// λa.λb.(((λc.λd.c d) (λc.λd.d (c a))) (λ_.b)) (λc.c)
let
term_step_1
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
App
(
box
App
(
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
2
),
box
Var
(
1
)))),
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
App
(
box
Var
(
2
),
box
Var
(
4
))),
),
),
),
box
Abs
(
box
Prop
,
box
Var
(
2
)),
),
box
Abs
(
box
Prop
,
box
Var
(
1
)),
),
),
);
// λa.λb.((λc.(λd.λe.e (d a)) c) (λ_.b)) (λc.c)
let
term_step_2
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
App
(
box
Abs
(
box
Prop
,
box
App
(
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
App
(
box
Var
(
2
),
box
Var
(
5
))),
),
),
box
Var
(
1
),
),
),
box
Abs
(
box
Prop
,
box
Var
(
2
)),
),
box
Abs
(
box
Prop
,
box
Var
(
1
)),
),
),
);
// λa.λb.[(λc.λd.(d (c a))) (λ_.b)] (λc.c)
let
term_step_3
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
App
(
box
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
App
(
box
Var
(
2
),
box
Var
(
4
))),
),
),
box
Abs
(
box
Prop
,
box
Var
(
2
)),
),
box
Abs
(
box
Prop
,
box
Var
(
1
)),
),
),
);
// λa.λb.(λc.c ((λ_.b) a)) (λc.c)
let
term_step_4
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Abs
(
box
Prop
,
box
App
(
box
Var
(
1
),
box
App
(
box
Abs
(
box
Prop
,
box
Var
(
3
)),
box
Var
(
3
)),
),
),
box
Abs
(
box
Prop
,
box
Var
(
1
)),
),
),
);
// λa.λb.(λc.c) ((λ_.b) a)
let
term_step_5
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Abs
(
box
Prop
,
box
Var
(
1
)),
box
App
(
box
Abs
(
box
Prop
,
box
Var
(
2
)),
box
Var
(
2
)),
),
),
);
// λa.λb.(λc.b) a
let
term_step_6
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
App
(
box
Abs
(
box
Prop
,
box
Var
(
2
)),
box
Var
(
2
))),
);
// λa.λb.b
let
term_step_7
=
Abs
(
box
Prop
,
box
Abs
(
box
Prop
,
box
Var
(
1
)));
assert_eq!
(
term
.beta_reduction
(),
term_step_1
);
assert_eq!
(
term_step_1
.beta_reduction
(),
term_step_2
);
assert_eq!
(
term_step_2
.beta_reduction
(),
term_step_3
);
assert_eq!
(
term_step_3
.beta_reduction
(),
term_step_4
);
assert_eq!
(
term_step_4
.beta_reduction
(),
term_step_5
);
assert_eq!
(
term_step_5
.beta_reduction
(),
term_step_6
);
assert_eq!
(
term_step_6
.beta_reduction
(),
term_step_7
);
assert_eq!
(
term_step_7
.clone
()
.beta_reduction
(),
term_step_7
);
}
}
This diff is collapsed.
Click to expand it.