Skip to content

Instantly share code, notes, and snippets.

@mrrodriguez
Last active September 24, 2021 13:00
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 mrrodriguez/09df52e5f9729992c61f21fc638a20e6 to your computer and use it in GitHub Desktop.
Save mrrodriguez/09df52e5f9729992c61f21fc638a20e6 to your computer and use it in GitHub Desktop.
Clara-rules typical logical loop
;; Usually the solution is to reframe the problem you have in a way that avoids the logical contradiction,
;; ie. 'not B => B'
;; and continue to use the default inserts (not unconditional type) that participate in truth maintenance
;; To avoid a rule like this:
(r/defrule b-contradiction
[A]
[:not [B]]
=>
(r/insert! (->B))
;; I think that situation often comes up when you are attempting to have “uniqueness” in your inserts
;; ie. you don’t want to insert B multiple times.
;; A way to work around that, is to insert some intermediary fact type,
;; eg. BCandidate, with no cardinality concerns.
;; Then have an aggregate rule that takes all BCandidates and aggregates it to a single B fact -
;; so you end up with the single cardinality/unique B fact for later rules to reason about.
(r/defrule find-b-candidates
[A]
=>
;; Do something with A data if needed here
(r/insert! (->BCandidate))
(r/defrule process-b-candidates
;; If there are join criteria with another fact type, like A, then that could be used here to filter
;; through the candidates.
[?bcs <- (acc/all) :from [BCandidate]]
=>
;; Build B however, is appropriate based on the candidate collection; using `first` here for demo
(r/insert! (-> ?bcs first map->B)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment