EvgSkv / logica

Logica is a logic programming language that compiles to SQL. It runs on DuckDB, Google BigQuery, PostgreSQL and SQLite.
https://logica.dev
Apache License 2.0
1.73k stars 88 forks source link

External Functors #55

Open EvgSkv opened 3 years ago

EvgSkv commented 3 years ago

Functors in Logica are functions that map named tuples of predicates to a predicate. Currently the only available functors are substitutions. Any predicate can work as a functor.

External Functors would be arbitrary executables that are running in the middle of Logica program execution. They would create new database tables from the ones that Logica already produced. Here is a toy high level example of what application of such function would look like:


# LargestConnectedComponent takes in a graph and produces a graph
# that consists of a largest connected component.
# Note that this functor is in fact easy to implement in Logica, we use this example
# just because it's an intuitive problem.
@ExternalFunctor(
    LargestConnectedComponent,
    binary: "/path/to/extract_component");

# Building a traveling graph. Assuming Trips table that has source and destination of trips.
# There is an edge in traveling graph if there are more than 1000 trips between the cities.
TravelVolume(source, target) += 1 :- Trips(source:, target:);
@Ground(TravelEdge);
TravelEdge(source, target) :- TravelVolume(source, target) > 1000;

# This functor call results in execution of command like:
# /path/to/extract_component --args='{"Graph": "TravelEdge"} --dataset="logica_test"
# logica_test is a default dataset where Logica writes tables.
# The binary would read the logica_test.Graph dataset and write logica_test.LargestAreaGraph dataset.
# Logica would then associate logica_test.LargestAreaGraph table with LargestAreaGraph
# predicate. 
LargestAreaGraph := LargestConnectedComponent(Graph: TravelEdge);

NumCitiesInLargestComponent() Count= city :-
  city in [source, target], LargestAreaGraph(source, trarget);

To implement this we would need to implement new execution engine that would be doing these calls.

Estimated work time to implement: 3 - 5 weeks.

TimKam commented 3 years ago

To me, this looks like a generally useful feature. It also solves my problem, but this fact should not inform your design decisions :-)

EvgSkv commented 3 years ago

@TimKam, thanks for feedback!

This feature is inline with my vision of how Logica should evolve.

However, I don't think current contributors will be able to get to this anytime soon.

If you are interested in contributing towards making this happen let me know :-) In any case, I'll update this issue when we have an estimate when it happens.

TimKam commented 3 years ago

Thank you! Same here: unfortunately, it would be naive for me to commit to it right away, but if I will be able to understand the technical challenge and allocate time to it, I'll let you know.