Skip to content

Instantly share code, notes, and snippets.

Created February 3, 2022 09:39
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
(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.
;; 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