Skip to content

Instantly share code, notes, and snippets.

@refset
Created February 3, 2022 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save refset/21b3fc1dec9a6928943073809e13356d to your computer and use it in GitHub Desktop.
Save refset/21b3fc1dec9a6928943073809e13356d to your computer and use it in GitHub Desktop.
flix-datalog-comparison-test.clj
(with-open [n (xt/start-node {})]
(xt/q (xt/db n) '{:find [component date]
:where [(ready-date component date)]
:rules [[(ready-date part date)
(delivery-date part date)]
[(ready-date part date)
[(+ assembly-time* component-date) date]
(part-depends part component)
(assembly-time part assembly-time*)
(ready-date component component-date)]
[(delivery-date part date)
[(identity [["Chassis" 2]
["Piston" 1]
["Ignition" 7]]) [[part date]]]]
[(assembly-time part assembly-time)
[(identity [["Car" 7]
["Engine" 2]]) [[part assembly-time]]]]
[(part-depends part component)
[(identity [["Car" "Chassis"]
["Car" "Engine"]
["Engine" "Piston"]
["Engine" "Ignition"]]) [[part component]]]]]}))
;; => #{["Car" 16] ["Car" 9] ["Engine" 9] ["Chassis" 2] ["Piston" 1] ["Car" 10] ["Engine" 3] ["Ignition" 7]}
;;
;; vs.
;; https://flix.dev/
;; Datalog Enriched with Lattice Semantics
;;Flix supports Datalog constraints enriched with lattice semantics.
;;The program on the right computes the delivery date for a collection of parts. Each part is assembled from a collection of sub-components with various delivery dates. For example, a car depends on a chassis and an engine. To build a car, we need to wait for the chassis and engine to assembled and then we can assemble the car itself.
;;Note that parts may depend on sub-components that themselves may depend on other sub-components. In other words, the problem is recursive.
;;Datalog constraints enriched with lattice semantics is one of the more advanced features of Flix and requires some background knowledge of lattice theory and fixpoints.
;;let p = #{
;; /// Parts and the components they depend on.
;; PartDepends("Car", "Chassis").
;; PartDepends("Car", "Engine").
;; PartDepends("Engine", "Piston").
;; PartDepends("Engine", "Ignition").
;;
;; /// Time required to assemble a part from its components.
;; AssemblyTime("Car", 7).
;; AssemblyTime("Engine", 2).
;;
;; /// Expected delivery date for certain components.
;; DeliveryDate("Chassis"; 2).
;; DeliveryDate("Piston"; 1).
;; DeliveryDate("Ignition"; 7).
;;
;; /// A part is ready when it is delivered.
;; ReadyDate(part; date) :-
;; DeliveryDate(part; date).
;;
;; /// Or when it can be assembled from its components.
;; ReadyDate(part; assemblyTime + componentDate) :-
;; PartDepends(part, component),
;; AssemblyTime(part, assemblyTime),
;; ReadyDate(component; componentDate).
;;};
;;// Computes the delivery date for each component.
;;let r = query p select (c; d) from ReadyDate(c; d)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment