Skip to content
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
c63854b
[EQL] match automatically determines which comparator type to use, wh…
AbdelrhmanBassiouny Nov 19, 2025
dc6103c
[EQL] set_of can use match instances as its selectables.
AbdelrhmanBassiouny Nov 20, 2025
9df3ea4
[EQLMatch] match does not require kwargs.
AbdelrhmanBassiouny Nov 20, 2025
191df0a
[EQLMatch] selectables.
AbdelrhmanBassiouny Nov 20, 2025
4de351f
[EQLMatch] match can return a set_of.
AbdelrhmanBassiouny Nov 20, 2025
d0581d1
[EQLMatch] match can return a set_of.
AbdelrhmanBassiouny Nov 20, 2025
cac9883
[EQLMatch] in progress selecting literals.
AbdelrhmanBassiouny Nov 20, 2025
d0ec235
[EQL] select seems to work.
AbdelrhmanBassiouny Nov 21, 2025
7e5af65
[EQLMatch] cleaning.
AbdelrhmanBassiouny Nov 24, 2025
0a9a16c
[EQLMatch] only return entity() with the parent match variable select…
AbdelrhmanBassiouny Nov 24, 2025
d430882
[EQLMatch] cleaning.
AbdelrhmanBassiouny Nov 24, 2025
16503d5
[EQLMatch] cleaning.
AbdelrhmanBassiouny Nov 24, 2025
bb00cf5
[EQLMatch] doc.
AbdelrhmanBassiouny Nov 24, 2025
3f59ad7
[EQLMatch] fix type hints of match return
AbdelrhmanBassiouny Nov 24, 2025
ad9fe80
[EQLMatch] test match.
AbdelrhmanBassiouny Nov 24, 2025
bd59c08
[EQLMatch] test match any
AbdelrhmanBassiouny Nov 24, 2025
ae2ebec
[EQLMatch] cleaning and docs.
AbdelrhmanBassiouny Nov 24, 2025
7bcd501
[EQLMatch] more tests, cleaning.
AbdelrhmanBassiouny Nov 25, 2025
993b245
[EQLMatch] back to match_any, and select_any.
AbdelrhmanBassiouny Nov 25, 2025
0426954
Merge remote-tracking branch 'code_iai/main' into better_match
AbdelrhmanBassiouny Nov 25, 2025
67a7522
[EQLMatch] restructuring, created match.py, and quantify_entity.py.
AbdelrhmanBassiouny Nov 25, 2025
c321957
[EQLMatch] update docs.
AbdelrhmanBassiouny Nov 25, 2025
db9f2e5
[EQLMatch] better way of finding if variable values are iterable.
AbdelrhmanBassiouny Nov 25, 2025
2a3ee59
[EQLMatch] more efficient exists and comparator.
AbdelrhmanBassiouny Nov 25, 2025
c613396
[EQLMatch] doc update
AbdelrhmanBassiouny Nov 25, 2025
95e1955
[EQLMatch] doc update
AbdelrhmanBassiouny Nov 25, 2025
7ea4804
[EQL] updated match logic, need to fix existential and universal cond…
AbdelrhmanBassiouny Nov 26, 2025
d627aaa
[EQL] universal match doesn't work.
AbdelrhmanBassiouny Nov 27, 2025
6157830
[EQL] Symbol doc update.
AbdelrhmanBassiouny Nov 27, 2025
b261b8e
[EQL] fixed match all.
AbdelrhmanBassiouny Nov 28, 2025
cead85e
[EQL] fixed match notebook.
AbdelrhmanBassiouny Nov 28, 2025
e948639
[EQL] fixed match notebook.
AbdelrhmanBassiouny Nov 28, 2025
84f8a87
[EQL] fix method doc.
AbdelrhmanBassiouny Nov 28, 2025
8c5365f
[EQL] review changes.
AbdelrhmanBassiouny Nov 28, 2025
7686f7f
[EQL] review changes.
AbdelrhmanBassiouny Nov 28, 2025
f0c159d
[EQL] review changes.
AbdelrhmanBassiouny Nov 28, 2025
e5f6838
[EQL] Created AttributeAssignment class.
AbdelrhmanBassiouny Nov 28, 2025
11358b3
[EQL] Class doc.
AbdelrhmanBassiouny Nov 28, 2025
1fda110
[EQLMatch] fix type hints.
AbdelrhmanBassiouny Nov 29, 2025
6d9582e
[EQLMatch] doc fix.
AbdelrhmanBassiouny Nov 29, 2025
5387298
Merge remote-tracking branch 'code_iai/main' into better_match
AbdelrhmanBassiouny Nov 29, 2025
144ff40
[EQLMatch] fix selection.
AbdelrhmanBassiouny Nov 29, 2025
51981cd
Merge remote-tracking branch 'code_iai/main' into better_match
AbdelrhmanBassiouny Nov 29, 2025
3a3e138
[EQLMatch] us normal in.
AbdelrhmanBassiouny Nov 29, 2025
a6f2415
Merge remote-tracking branch 'code_iai/main' into better_match
AbdelrhmanBassiouny Nov 29, 2025
2f72c1d
[EQLMatch] compare variables using hash to avoid symbolic comparison.
AbdelrhmanBassiouny Nov 29, 2025
591faa0
[EQLMatch] compare variables using hash to avoid symbolic comparison.
AbdelrhmanBassiouny Nov 29, 2025
b5b9418
[EQLFeatures] review changes.
AbdelrhmanBassiouny Nov 30, 2025
32d029a
[EQLMatch] removed unused method.
AbdelrhmanBassiouny Dec 1, 2025
d620f52
[EQLMatch] review changes.
AbdelrhmanBassiouny Dec 1, 2025
bf2e0c9
[EQLMatch] review changes.
AbdelrhmanBassiouny Dec 1, 2025
d497b41
[EQLMatch] fix None instances problem.
AbdelrhmanBassiouny Dec 1, 2025
c63d037
removed is_universal_match and is_existential_match
LucaKro Dec 1, 2025
5be0136
Merge pull request #2 from LucaKro/better_match
AbdelrhmanBassiouny Dec 2, 2025
31ea32d
Merge remote-tracking branch 'code_iai/main' into better_match
AbdelrhmanBassiouny Dec 2, 2025
a78c6d4
[EQLMatch] fix and cleaning
AbdelrhmanBassiouny Dec 2, 2025
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
3 changes: 2 additions & 1 deletion examples/eql/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ from dataclasses import dataclass

from typing_extensions import List

from krrood.entity_query_language.entity import entity, an, let, contains, Symbol
from krrood.entity_query_language.entity import entity, let, contains, Symbol
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/comparators.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ from dataclasses import dataclass
from typing_extensions import List

from krrood.entity_query_language.entity import (
entity, an, let, Symbol,
entity, let, Symbol,
in_, contains, not_, and_, or_,
)
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 1 addition & 2 deletions examples/eql/domain_mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,11 @@ from typing_extensions import List, Dict
from krrood.entity_query_language.entity import (
entity,
set_of,
an,
let,
flatten,
Symbol,
)

from krrood.entity_query_language.quantify_entity import an

@dataclass
class Body(Symbol):
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/eql_for_sql_experts.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ from dataclasses import dataclass, field

from typing_extensions import List

from krrood.entity_query_language.entity import let, Symbol, entity, an, and_, in_, contains, set_of
from krrood.entity_query_language.entity import let, Symbol, entity, and_, in_, contains, set_of
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ from dataclasses import dataclass

from typing_extensions import List

from krrood.entity_query_language.entity import entity, an, let, contains, Symbol
from krrood.entity_query_language.entity import entity, let, contains, Symbol
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/logical_operators.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ from dataclasses import dataclass

from typing_extensions import List

from krrood.entity_query_language.entity import entity, an, or_, Symbol, let, not_, and_
from krrood.entity_query_language.entity import entity, or_, Symbol, let, not_, and_
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
164 changes: 162 additions & 2 deletions examples/eql/match.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@ from dataclasses import dataclass
from typing_extensions import List

from krrood.entity_query_language.entity import (
let, entity, the,
match, entity_matching, Symbol,
let, entity, Symbol,
)
from krrood.entity_query_language.quantify_entity import the
from krrood.entity_query_language.match import (
match,
entity_matching,
)
from krrood.entity_query_language.predicate import HasType

Expand Down Expand Up @@ -123,3 +127,159 @@ Notes:
- Use `entity_matching` for the outer pattern when a domain is involved; inner attributes use `match`.
- Nested `match(...)` can be composed arbitrarily deep following your object graph.
- `entity_matching` is a syntactic sugar over the explicit `entity` + predicates form, so both are interchangeable.

## Selecting inner objects with `select()`

Use `select(Type)` when you want the matched inner objects to appear in the result. The evaluation then
returns a mapping from the selected variables to the concrete objects (a unification dictionary).
Comment thread
AbdelrhmanBassiouny marked this conversation as resolved.

```{code-cell} ipython3
from krrood.entity_query_language.match import select

container, handle = select(Container), select(Handle)
fixed_connection_query = the(
entity_matching(FixedConnection, world.connections)(
parent=container(name="Container1"),
child=handle(name="Handle1"),
)
)

answers = fixed_connection_query.evaluate()
print(answers[container].name, answers[handle].name)
```

## Existential matches in collections with `match_any()`

When matching a container-like attribute (for example, a list), use `match_any(pattern)` to express that
at least one element of the collection should satisfy the given pattern.

Below we add two simple view classes and build a small scene of drawers and a cabinet.

```{code-cell} ipython3
from dataclasses import dataclass
from typing_extensions import List
from krrood.entity_query_language.match import match_any


@dataclass
class Drawer(Symbol):
handle: Handle
container: Container


@dataclass
class Cabinet(Symbol):
container: Container
drawers: List[Drawer]


# Build a simple set of views
drawer1 = Drawer(handle=h1, container=c1)
drawer2 = Drawer(handle=Handle("OtherHandle"), container=other_c)
cabinet1 = Cabinet(container=c1, drawers=[drawer1, drawer2])
views = [drawer1, cabinet1]

# Query: find the cabinet that has a drawer whose handle is named "Handle1"
drawer_pattern = the(entity_matching(Drawer, views)(handle=match(Handle)(name="Handle1")))
cabinet_query = the(entity_matching(Cabinet, views)(drawers=match_any(drawer_pattern)))

found_cabinet = cabinet_query.evaluate()
print(found_cabinet.container.name, found_cabinet.drawers[0].handle.name)
```

## Selecting elements from collections with `select_any()`

If you want to retrieve a specific element from a collection attribute while matching, use `select_any(Type)`.
It behaves like `match_any(Type)` but also selects the matched element so you can access it in the result.

```{code-cell} ipython3
from krrood.entity_query_language.match import select_any

selected_drawer = select_any(Drawer)
cabinet_with_selected_drawer = the(
entity_matching(Cabinet, views)(
drawers=selected_drawer(handle=match(Handle)(name="Handle1"))
)
)

ans = cabinet_with_selected_drawer.evaluate()
print(ans[selected_drawer].handle.name)
```

## Selecting inner objects with `select()`

Use `select(Type)` when you want the matched inner objects to appear in the result. The evaluation then
returns a mapping from the selected variables to the concrete objects (a unification dictionary).

```{code-cell} ipython3
from krrood.entity_query_language.match import select

container, handle = select(Container), select(Handle)
fixed_connection_query = the(
entity_matching(FixedConnection, world.connections)(
parent=container(name="Container1"),
child=handle(name="Handle1"),
)
)

answers = fixed_connection_query.evaluate()
print(answers[container].name, answers[handle].name)
```

## Existential matches in collections with `match_any()`

When matching a container-like attribute (for example, a list), use `match_any(pattern)` to express that
at least one element of the collection should satisfy the given pattern.

Below we add two simple view classes and build a small scene of drawers and a cabinet.

```{code-cell} ipython3
from dataclasses import dataclass
from typing_extensions import List
from krrood.entity_query_language.match import match_any


@dataclass
class Drawer(Symbol):
handle: Handle
container: Container


@dataclass
class Cabinet(Symbol):
container: Container
drawers: List[Drawer]


# Build a simple set of views
drawer1 = Drawer(handle=h1, container=c1)
drawer2 = Drawer(handle=Handle("OtherHandle"), container=other_c)
cabinet1 = Cabinet(container=c1, drawers=[drawer1, drawer2])
views = [drawer1, cabinet1]

# Query: find the cabinet that has a drawer whose handle is named "Handle1"
drawer_pattern = the(entity_matching(Drawer, views)(handle=match(Handle)(name="Handle1")))
cabinet_query = the(entity_matching(Cabinet, views)(drawers=match_any(drawer_pattern)))

found_cabinet = cabinet_query.evaluate()
print(found_cabinet.container.name, found_cabinet.drawers[0].handle.name)
```

## Selecting elements from collections with `select_any()`

If you want to retrieve a specific element from a collection attribute while matching, use `select_any(Type)`.
It behaves like `match_any(Type)` but also selects the matched element so you can access it in the result.

```{code-cell} ipython3
from krrood.entity_query_language.match import select_any

selected_drawer = select_any(Drawer)
cabinet_with_selected_drawer = the(
entity_matching(Cabinet, views)(
drawers=selected_drawer(handle=match(Handle)(name="Handle1"))
)
)

ans = cabinet_with_selected_drawer.evaluate()
print(ans[selected_drawer].handle.name)
```
3 changes: 2 additions & 1 deletion examples/eql/predicate_and_symbolic_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ Lets first define our model and some sample data.
from dataclasses import dataclass
from typing_extensions import List

from krrood.entity_query_language.entity import entity, let, an, Symbol
from krrood.entity_query_language.entity import entity, let, Symbol
from krrood.entity_query_language.predicate import Predicate, symbolic_function
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/result_quantifiers.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ from dataclasses import dataclass

from typing_extensions import List

from krrood.entity_query_language.entity import entity, let, the, Symbol, an
from krrood.entity_query_language.entity import entity, let, Symbol
from krrood.entity_query_language.quantify_entity import an, the
from krrood.entity_query_language.result_quantification_constraint import AtLeast, AtMost, Exactly, Range
from krrood.entity_query_language.failures import MultipleSolutionFound, LessThanExpectedNumberOfSolutions, GreaterThanExpectedNumberOfSolutions

Expand Down
3 changes: 2 additions & 1 deletion examples/eql/writing_queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ from dataclasses import dataclass

from typing_extensions import List

from krrood.entity_query_language.entity import entity, an, let, Symbol
from krrood.entity_query_language.entity import entity, let, Symbol
from krrood.entity_query_language.quantify_entity import an


@dataclass
Expand Down
3 changes: 2 additions & 1 deletion examples/eql/writing_rule_trees.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Lets define our domain model and build a small world. We will then build a rule
instances to the world.

```{code-cell} ipython3
from krrood.entity_query_language.entity import entity, an, let, and_, Symbol, inference
from krrood.entity_query_language.entity import entity, let, and_, Symbol, inference
from krrood.entity_query_language.quantify_entity import an

from krrood.entity_query_language.rule import refinement, alternative
from krrood.entity_query_language.conclusion import Add
Expand Down
Loading
Loading