Skip to content

Commit

Permalink
Merge pull request #265 from saulshanabrook/match-rational
Browse files Browse the repository at this point in the history
Add support for matching on rationals
  • Loading branch information
oflatt authored Oct 25, 2023
2 parents 713078c + 2b969c7 commit ceed816
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 4 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ Rational numbers (fractions) with 64-bit precision for numerator and denominator
+ - * / ; arithmetic
min max neg abs floor ceil round
rational ; construct from a numerator and denominator
numer denom ; get numerator and denominator
pow log sqrt
< > <= >= ; comparisons
```
Expand Down
11 changes: 7 additions & 4 deletions src/sort/rational.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ impl Sort for RationalSort {
add_primitives!(eg, "ceil" = |a: R| -> R { a.ceil() });
add_primitives!(eg, "round" = |a: R| -> R { a.round() });
add_primitives!(eg, "rational" = |a: i64, b: i64| -> R { R::new(a, b) });
add_primitives!(eg, "numer" = |a: R| -> i64 { *a.numer() });
add_primitives!(eg, "denom" = |a: R| -> i64 { *a.denom() });

add_primitives!(eg, "to-f64" = |a: R| -> f64 { a.to_f64().unwrap() });

add_primitives!(eg, "pow" = |a: R, b: R| -> Option<R> {
Expand Down Expand Up @@ -101,10 +104,10 @@ impl Sort for RationalSort {
}
});

add_primitives!(eg, "<" = |a: R, b: R| -> Opt { if a < b {Some(())} else {None} });
add_primitives!(eg, ">" = |a: R, b: R| -> Opt { if a > b {Some(())} else {None} });
add_primitives!(eg, "<=" = |a: R, b: R| -> Opt { if a <= b {Some(())} else {None} });
add_primitives!(eg, ">=" = |a: R, b: R| -> Opt { if a >= b {Some(())} else {None} });
add_primitives!(eg, "<" = |a: R, b: R| -> Opt { if a < b {Some(())} else {None} });
add_primitives!(eg, ">" = |a: R, b: R| -> Opt { if a > b {Some(())} else {None} });
add_primitives!(eg, "<=" = |a: R, b: R| -> Opt { if a <= b {Some(())} else {None} });
add_primitives!(eg, ">=" = |a: R, b: R| -> Opt { if a >= b {Some(())} else {None} });
}
fn make_expr(&self, _egraph: &EGraph, value: Value) -> (Cost, Expr) {
assert!(value.tag == self.name());
Expand Down
14 changes: 14 additions & 0 deletions tests/rational.egg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; Test that can run rule matching on rational

(datatype Pretty
(pretty-str String)
(pretty-rational Rational))

; This will fail with `Unbound variable x in primitive computation` currently:
; (rewrite (pretty-rational (rational x y)) (pretty-str (+ (to-string x) "/" (to-string y))))

(rewrite (pretty-rational r) (pretty-str (+ (to-string (numer r)) "/" (to-string (denom r)))))

(let z (pretty-rational (rational 1 2)))
(run 1)
(check (= z (pretty-str "1/2")))

0 comments on commit ceed816

Please sign in to comment.