Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
137ccee
Other failed experiment
saulshanabrook Sep 14, 2023
37b31fd
Tmp
saulshanabrook Sep 20, 2023
6d767b3
Fixes
saulshanabrook Sep 20, 2023
ae4cd19
First sort of working version but much too slow
saulshanabrook Sep 27, 2023
0e02ffc
Change fact to take any expression not just unit
saulshanabrook Sep 27, 2023
2306428
Add first working version
saulshanabrook Sep 27, 2023
8395a0e
Almost working with parents set
saulshanabrook Sep 28, 2023
2e24569
Real working version!
saulshanabrook Sep 28, 2023
698c047
Get function generation working
saulshanabrook Oct 1, 2023
cc09fe1
Add compilation to python value
saulshanabrook Oct 1, 2023
5dcae1e
Set default function name
saulshanabrook Oct 1, 2023
fa8309e
Start moving array api into new form
saulshanabrook Oct 1, 2023
afec7b6
Lint fixes
saulshanabrook Oct 1, 2023
c3d1bb2
Make getting started tutorial clearer
saulshanabrook Oct 4, 2023
6d001b8
fix displaying graphs in notebook
saulshanabrook Oct 4, 2023
0720ada
Try not to extract parents
saulshanabrook Oct 4, 2023
0d12b8f
Fix compilation of program args
saulshanabrook Oct 4, 2023
3e8bda5
Fix array api test
saulshanabrook Oct 4, 2023
f85a074
Add split primitive outputs option
saulshanabrook Oct 4, 2023
80debbc
Highlight paths in graphviz output
saulshanabrook Oct 4, 2023
1c65e75
Increase cost of emitting var
saulshanabrook Oct 4, 2023
b5bfbd2
Fix docs
saulshanabrook Oct 4, 2023
e305089
Adds changelog entries
saulshanabrook Oct 4, 2023
b587059
Merge main into fix-string-gen
saulshanabrook Oct 4, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 86 additions & 94 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.18.1", features = ["extension-module"] }
egglog = { git = "https://github.com/egraphs-good/egglog", rev = "4d67f262a6f27aa5cfb62a2cfc7df968959105df" }
egglog = { git = "https://github.com/egraphs-good/egglog", rev = "45d05e727cceaab13413b4e51a60ee3be9fbf403" }
# egglog = { git = "https://github.com/oflatt/egg-smol", rev = "f6df3ff831b65405665e1751b0ef71c61b025432" }
# egglog = { git = "https://github.com/saulshanabrook/egg-smol", rev = "c01695618ed4de2fbfa8116476e208bc1ca86612" }
# egglog = { git = "https://github.com/saulshanabrook/egg-smol", rev = "38b3014b34399cc78887ede09c845b2a5d6c7d19" }

pyo3-log = "0.8.1"
log = "0.4.17"
Expand Down
16 changes: 14 additions & 2 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ _This project uses semantic versioning. Before 1.0.0, this means that every brea

## Unreleased

- Bump [egglog dep](https://github.com/egraphs-good/egglog/compare/4d67f262a6f27aa5cfb62a2cfc7df968959105df...45d05e727cceaab13413b4e51a60ee3be9fbf403)

### New Features

- Adds ability for custom user defined types in a union for proper static typing with conversions [#49](https://github.com/metadsl/egglog-python/pull/49)
- Adds `py_eval` function to `EGraph` as a helper to eval Python code. [#49](https://github.com/metadsl/egglog-python/pull/49)
- Adds on hover behavior for edges in graphviz SVG output to make them easier to trace [#49](https://github.com/metadsl/egglog-python/pull/49)
- Adds `egglog.exp.program_gen` module that will compile expressions into Python statements/functions [#49](https://github.com/metadsl/egglog-python/pull/49)
- Adds `py_exec` primitive function for executing Python code [#49](https://github.com/metadsl/egglog-python/pull/49)

### Bug fixes

- Clean up example in tutorial with demand based expression generation [#49](https://github.com/metadsl/egglog-python/pull/49)

## 0.6.0 (2023-09-20)

- Bump [egglog dep](https://github.com/egraphs-good/egglog/compare/c83fc750878755eb610a314da90f9273b3bfe25d...4d67f262a6f27aa5cfb62a2cfc7df968959105df)
Expand All @@ -19,8 +33,6 @@ _This project uses semantic versioning. Before 1.0.0, this means that every brea
- Add `Relation` and `PrintOverallStatistics` low level commands [#46](https://github.com/metadsl/egglog-python/pull/46)
- Adds `count-matches` and `replace` string commands [#46](https://github.com/metadsl/egglog-python/pull/46)

### Bug fixes

### Uncategorized

- Added initial supported for Python objects [#31](https://github.com/metadsl/egglog-python/pull/31)
Expand Down
15 changes: 0 additions & 15 deletions docs/reference/egglog-translation.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,21 +245,6 @@ As shown above, we can also use the `@classmethod` and `@property` decorators to
Note that reflected methods (i.e. `__radd__`) are handled as a special case. If defined, they won't create their own egglog functions.
Instead, whenever a reflected method is called, we will try to find the corresponding non-reflected method and call that instead.

#### Custom Type Promotion

Similar to how an `int` can be automatically upcasted to an `i64`, we also support registering conversion to your custom types. For example:

```{code-cell} python
converter(int, Math, Math)
converter(str, Math, Math.var)

Math(2) + 30 + "x"
# equal to
Math(2) + Math(i64(30)) + Math.var(String("x"))
```

Regstering a conversion from A to B will also register all transitively reachable conversions from A to B.

### Declarations

In egglog, the `(declare ...)` command is syntactic sugar for a nullary function. In Python, these can be declare either as class variables or with the toplevel `egraph.constant` function:
Expand Down
70 changes: 66 additions & 4 deletions docs/reference/python-integration.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,13 @@ egraph.load_object(egraph.extract(PyObject.from_int(1)))
We also support evaling arbitrary Python bode, given some locals and globals. This technically allows us to implement any Python method:

```{code-cell} python
empty_dict = egraph.save_object({})
egraph.load_object(egraph.extract(py_eval("1 + 2", empty_dict, empty_dict)))
egraph.load_object(egraph.extract(py_eval("1 + 2")))
```

Execing Python code is also supported. In this case, the return value will be the updated globals dict, which will be copied first before using.

```{code-cell} python
egraph.load_object(egraph.extract(py_exec("x = 1 + 2")))
```

Alongside this, we support a function `dict_update` method, which can allow you to combine some local local egglog expressions alongside, say, the locals and globals of the Python code you are evaling.
Expand All @@ -87,11 +92,68 @@ locals_expr = egraph.save_object(locals())
globals_expr = egraph.save_object(globals())
# Need `one` to map to the expression for `1` not the Python object of the expression
amended_globals = globals_expr.dict_update(PyObject.from_string("one"), one)
evalled = py_eval("one + 2", locals_expr, amended_globals)
evalled = py_eval("my_add(one, 2)", locals_expr, amended_globals)
assert egraph.load_object(egraph.extract(evalled)) == 3
```

This is a bit subtle at the moment, and we plan on adding an easier wrapper to eval arbitrary Python code in the future.
### Simpler Eval

Instead of using the above low level primitive for evaling, there is a higher level wrapper function, `egraph.eval_fn`.

It takes in a Python function and converts it to a function of PyObjects, by using `py_eval`
under the hood.

The above code code be re-written like this:

```{code-cell} python
def my_add(a, b):
return a + b

evalled = egraph.eval_fn(lambda a: my_add(a, 2))(one)
assert egraph.load_object(egraph.extract(evalled)) == 3
```

#### Custom Type Promotion

Similar to how an `int` can be automatically upcasted to an `i64`, we also support registering conversion to your custom types. For example:

```{code-cell} python
@egraph.class_
class Math(Expr):
def __init__(self, x: i64Like) -> None: ...

@classmethod
def var(cls, name: StringLike) -> Math: ...

def __add__(self, other: Math) -> Math: ...

converter(i64, Math, Math)
converter(String, Math, Math.var)

Math(2) + i64(30) + String("x")
# equal to
Math(2) + Math(i64(30)) + Math.var(String("x"))
```

Regstering a conversion from A to B will also register all transitively reachable conversions from A to B, so you can also use:

```{code-cell} python
Math(2) + 30 + "x"
```

If you want to have this work with the static type checker, you can define your own `Union` type, which MUST include
have the Egglog class as the first item in the union. For example, in this case you could then define:

```{code-cell} python
from typing import Union
MathLike = Union[Math, i64Like, StringLike]

@egraph.function
def some_math_fn(x: MathLike) -> MathLike:
...

some_math_fn(10)
```

## "Preserved" methods

Expand Down
Loading