[HN Gopher] Clolog
___________________________________________________________________
Clolog
Author : todsacerdoti
Score : 250 points
Date : 2025-04-15 17:04 UTC (23 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| mark_l_watson wrote:
| Very cool! I just cloned the repository, will play with it later.
|
| BTW, Clojure was such a brilliant name (from Rich): Whenever I
| see a project starting with "Clo" I pay attention.
|
| EDIT: had a chance to try it: a very cool resource!
| iLemming wrote:
| > Clojure was such a brilliant name
|
| IIRC Rich wanted a name that has CLR and J in it - Clojure
| initially was officially to be supported on both .Net and Java
| stacks. Later he realized that keeping it completely compatible
| on both platforms is an uphill battle. CLR Clojure still
| exists, but it's not "an officially supported" runtime.
| mappu wrote:
| My /usr/share/dict/words offers Clojure, cajolery, and
| jocular[ly/ity]. Jocular's not bad.
| iLemming wrote:
| hahaha. Jocular reminded me the naming story of Karma test
| runner. Initially they named the project "Testacular". With
| a description that was something like "Spectacular test
| runner" (or something like that). Sadly, they had to rename
| it and the choice imo was a lame one. Karma? Really? I
| suppose some Mormon-backed Google partner thought the
| initial name was inscripturesque and the team had to choose
| something Buddhist to passive-aggressively throw a finger.
| mindcrime wrote:
| > Whenever I see a project starting with "Clo" I pay attention.
|
| You're going to love my "Cobol in Clojure" project "Clobol"
| then!
| phlakaton wrote:
| "Surely this is a joke," I thought as I read this.
|
| Then I did a Google search just to make sure...
| mindcrime wrote:
| So, I actually _was_ joking. But then I did a Google search
| after reading your response, and much to my astonishment I
| found that there actually is a clobol project[1]! I
| honestly had no idea.
|
| [1]: https://github.com/enajski/clobol
| anonzzzies wrote:
| This is very nice, I played with it before and working on a
| similar idea in CL (I am one of those people who finds the
| uniformity of no syntax soothing).
| sterlind wrote:
| really happy to see something of a revival of interest for logic
| programming lately. it's an extremely powerful tool if you know
| when to reach for it.
| MarkMarine wrote:
| When would you reach for it?
| winwang wrote:
| I've seen shops (e.g. Netflix I think) use Datalog for
| certain query types.
| iLemming wrote:
| Scheduling, e.g., course scheduling - allocating rooms,
| professors, time slots while satisfying constraints; Product
| configuration systems - helping customers select compatible
| options for complex products; Genealogical research -
| querying family relationships and ancestry; Static analysis
| tools for code - finding bugs or verifying properties without
| execution; Medical diagnosis systems - inferring conditions
| from symptoms based on medical knowledge; Travel planning -
| finding optimal routes with multiple constraints; Legal
| reasoning systems - determining applicability of laws to
| specific cases; Natural language interfaces - parsing
| questions and generating appropriate database queries;
| Hardware verification - proving correctness of circuit
| designs; Puzzle solvers - Sudoku, crosswords, logic puzzles;
|
| Basically anything that excels when declarative specification
| of relationships is more natural than imperative algorithms.
| sethhochberg wrote:
| This all makes perfect sense. The gap I usually have - and
| I admit its probably something of a skill issue, I have
| relatively little formal CS background - is how these
| abstract declarations of rules are integrated into a
| product. The example code in projects like this is usually
| pretty dense and intangible.
|
| Does anyone have good examples of open source codebases or
| reading material in this area? Lets imagine I have a set of
| complex business rules about the way a product can be
| configured and I want to use a logic programming language
| to enforce them, called from a web interface based on
| config data stored in a traditional relational database. Is
| that... a misunderstanding of how these things are to be
| used?
|
| I've love a good book about how to bring tools and
| techniques for logical correctness into a Rails
| ecosystem... or similar language/framework for app dev. I
| love the promises many of logic languages make but can't
| rewrite existing applications in them wholesale and it
| seems like they're a poor fit for that anyways. How are
| people blending these worlds at large enterprises? Maybe
| the answer is that nobody really is yet, and thats what
| makes things like Clolog + Clojure so exciting?
| iLemming wrote:
| FWIW I have no formal CS background whatsoever (maybe you
| shouldn't even listen to me on this matter), but if you
| want to gain some understanding of rule engines, you
| probably shouldn't start with core.logic or clolog (I
| have not looked into this project myself just yet, so my
| assumptions might be completely misleading) - core.logic
| imo good for complex constrains and relationships, it's
| based on miniKanren, but has quite steep learning curve,
| and not sure if it's worth the effort (as a starting
| point).
|
| oakes/odoyle-rules is a forward-chaining rules engine
| with a more straightforward approach - for someone
| already familiar with Clojure, it should be fun to try
| out. Then maybe check out Clara Rules, if I'm not
| mistaken the lib is specifically designed for business
| rules processing. For understanding the theoretical
| pieces, you probably want to look into forward vs.
| backward chaining rule systems; pattern matching used in
| rules engines; understanding how to model domain rules
| declaratively; Rete algorithm (odoyle lib explains it and
| iirc links to the paper).
| ARandomerDude wrote:
| Great comments, thank you for taking the time to mentor a
| few interested strangers.
| iLemming wrote:
| Awww, thank you. As a Clojurian, I aspire to be kind and
| helpful. The Clojure community is renowned for its
| friendly, coaching-oriented attitude. Anyone with
| questions (even those unrelated to Clojure) should
| absolutely reach out to Clojuristas -- just go to
| http://clojurians.net and don't be shy.
|
| I'm forever thankful for Clojure for reigniting my
| passion for programming, but particularly, I'm indebted
| to the many individuals in the Clojure community.
| Whenever I pose a question expecting just straightforward
| guidance or documentation links, I consistently receive
| profound, thought-provoking answers that surpass my
| expectations. Virtually every discussion I initiate with
| them ends up being incredibly educational, teaching me
| far more than I initially sought. I can confidently admit
| - yes, learning Clojure has made a better programmer out
| of me, but most importantly, it made me a better person.
| drob518 wrote:
| There are lots of good Prolog books available, many from
| the 1980s now released freely in PDF form. I would
| suggest starting there. IMO, Prolog is definitely worth
| understanding, but I personally tend to desire a Prolog
| available as an embedded resource in another language.
| So, Clolog is great for Clojure programmers, of which I
| am one, for instance. I find that Prolog excels for
| certain types of programming, but while it's Turing
| complete, and thus capable of doing anything any other
| language can do, it can get cumbersome for other types of
| programming. So, I like to think of logic programming
| similar to the way that I think of a SAT solver,
| something that I call out to in order to solve a problem,
| but then it returns the answer to the main program which
| presents that answer to the user using the host language.
| cess11 wrote:
| The classic books can be a bit rough on the newbie, I'd
| recommend slogging through Triska's site and trying stuff
| out in Scryer, SWI or Tau first.
|
| https://www.metalevel.at/prolog
| whartung wrote:
| Well the bigger question is how big does the system have to
| be to warrant breaking out a new technique, much less
| adding a new runtime or other large dependency.
|
| Now, I have no direct experience with any of the common
| logical programming systems. I have familiarity.
|
| But anytime I came upon anything that might justify such a
| system, the need just didn't seem to justify it.
|
| Talking less than 100 rules. Most likely less than a couple
| dozen. Stacking some IFs and a bit of math, strategically
| grouped in a couple aptly named wrapper methods to help
| reduce the cognitive load, and it's all worked pretty well.
|
| And, granted, if I had solid experience using these
| systems, onboarding cost would be lower.
|
| When have you found it to be worth cutting over?
| iLemming wrote:
| Absolutely valid and befitting point - adding complexity
| without clear benefits never should be justified. Most
| (business) applications have ruleset logic for specific
| problems not exceeding a dozens of rules - regular code
| often works fine.
|
| Logic systems tend to show the value when rules become
| complex with many interdependencies or non-linear
| execution patterns emerge, or rules change frequently or
| need to be defined at runtime; when you need explanation
| tools - e.g., why was this conclusion reached?, etc.
|
| I agree, situations for when you need to implement a
| logic system are not extremely common, but maybe I just
| have not worked in industries where they are - on top of
| my head I can think of: factory floor scheduling;
| regulatory compliance (e.g., complex tax rules);
| insurance systems, risk-calculation (credit approval);
| strategy games; retail - complex discounting; etc.
| sterlind wrote:
| I had the (self-inflicted) problem of modeling systems of
| linear equations in C#. `x` is a Sym, `x+2` is an Expr,
| `[2x,3y]` is a TermVector, etc. I wanted the comforts of
| NumPy, so adding an Int to a SymVector should make an
| ExprVector by broadcast, you should be able to multiply
| two IntMatrixes together but not two SymMatrixes (since
| that's not linear), etc. It would have been a lot of
| wrapper code to write.
|
| Instead, I implemented a minimal set of primitives, and
| wrote a set of derivation rules (e.g. "if you have X+Y,
| and Y supports negation, you can derive X-Y by X+(-Y)"),
| and constraints (operator overloads mustn't have
| ambiguous signatures, no cycles allowed in the call
| tree), and set up a code generator.
|
| 250 lines of Prolog, plus another 250 of ASP (a dialect
| of Prolog), and I had a code synthesizer.
|
| it was one of the most magical experiences of my entire
| career. I'd write an optimized version of a function,
| rerun synthesis and it would use it everywhere it could.
| I'd add new types and operators and it'd instantly plumb
| them through. seeing code synthesis dance for you feels
| amazingly liberating. it's like the opposite of technical
| debt.
| cess11 wrote:
| For a simple problem, the equivalent of one customer
| demand, something like n-queens, 'placements can't
| conflict', the difference isn't very large between Prolog
| and, say, Java.
|
| https://www.metalevel.at/queens/
|
| https://leetcode-in-
| java.github.io/src/main/java/g0001_0100/...
|
| That is, if you manage to figure out your own special
| case rule engine rather than a nest of if:s and for:s
| growing more organically.
|
| If you have ten of these, e.g. more dimensions that would
| result in conflicts or constraints on where placement is
| possible in the domain, the Java (or PHP or JavaScript or
| whatever) solution is likely to turn out rather
| inscrutable. At least that's my experience in ERP and
| CRM-adjacent systems where I've spent considerable time
| figuring out and consolidating many years of piecemeal
| additions of constraint threading in things like planning
| and booking tasks and the like.
|
| Sometimes I've scratched up algebraic expressions or
| standalone Prolog implementations to suss out what
| simpler code ought to look like.
| barrenko wrote:
| I really don't know not nearly enough about the topic - but
| couldn't a lot of these be handled with types, so my
| question is - are types at least adjacent to logical
| programming? (apologies in advance)
| iLemming wrote:
| Yes, afaik there is meaningful relevance between logic
| programming and type systems - Curry-Howard; Dependent
| types; SMT solvers (related to SAT solvers mentioned in
| this discussion). However, constraint problems discussed
| (scheduling, travel planning, puzzles) would require
| quite verbose and complex encoding to solve with a type
| system and significant sophistication - Idris or Coq
| aren't for the faint-hearted.
|
| Type systems would absolutely choke on trying to solve
| things like: Knowlege representation and querying -
| imagine medical diagnosis systems with thousands symptoms
| and conditions; Dynamic constraint solving - where
| constraints emerge at runtime; Exploratory search
| problems requiring bfs/dfs of large solution spaces -
| e.g., route finding with changing conditions; NLP tasks -
| grammar parsing and understanding; etc.
| baq wrote:
| Same reason you'd reach for SQL when querying relations - a
| good enough tool designed for the job.
|
| The problem has always been getting facts into the prolog
| system. I've been looking for a prolog which is as easy to
| embed in eg Python or node as a Postgres client and...
| crickets.
| Avshalom wrote:
| I dunno which postgres client you're thinking of but:
|
| https://github.com/tau-prolog/tau-prolog
|
| https://pyswip.org/ https://www.swi-
| prolog.org/packages/mqi/prologmqi.html
|
| Unfortunately the tau site's certificate seems to have
| lapsed sometime in the last week or so, but I swear it's
| actually very good.
| cess11 wrote:
| Prolog has very little syntax, usually it's not
| particularly hard to serialise your data structure directly
| into Prolog code and consult it. If your data is streaming
| you might have to resort to assert/asserta/assertz/retract,
| depending on your use case.
| log("2024-10-22", "09:09:23", "Mozilla", "/login").
| log("2024-10-23", "09:09:24", "Safari", "/dash").
| log("2024-10-24", "09:09:25", "Chrome", "/user").
| log("2024-10-25", "09:09:26", "Brave", "/login").
|
| Implementing a transform of a web server log file into
| Prolog can be as simple as this. In practice you'll have
| more like ten or twenty fields, of course. Then you can
| query along the lines of log(Date, Time, "user agent
| constraint", Resource). and don't have to be as diligent as
| when stacking grep:s or such.
|
| If you already keep all your logs in analytics databases
| the example isn't very good, but it ought to be easy to see
| how this trivial technique can be applied elsewhere.
| paddy_m wrote:
| I'm working on a problem that I think logic programming might
| be a fit for. And I already have a lisp. Anyone interested in
| giving me some feedback on a mini language for heuristics?
|
| https://marimo.io/p/@paddy-mullen/notebook-b79pj7
| winwang wrote:
| This might unironically be a reason for me to finally try
| Clojure!
| jdminhbg wrote:
| Can anybody comment on when or why to choose this over
| core.logic?
| drob518 wrote:
| Clolog is more of a direct translation of Prolog into Clojure,
| with an s-expression syntax rather than Prolog's standard
| syntax, but close. Core.logic is a translation of Mini-Kanren
| into Clojure and doesn't use anything close to Prolog's syntax,
| even one based on s-expressions. Prolog and Mini-Kanren, while
| both logic programming systems also use different search
| algorithms. Prolog uses a depth-first exploration of the
| solution space, whereas Mini-Kanren uses a breadth-first
| search. Consequently, Prolog can be more memory efficient
| (remember, it was created in the 1970s), but it can get stuck
| in infinite parts of the solution tree and never find a
| solution. Mini-Karen is less memory efficient as it explores
| the solution tree more broadly, but it can find solutions even
| if the solution tree has infinite branches.
|
| So, why/when to choose this? When you want something much more
| Prolog-like, using the same search algorithm as Prolog. That
| said, they both do logic programming. I haven't benchmarked,
| but from comments in the README, I suspect core.logic will be
| more performant as it compiles down to Clojure function calls
| which are then compiled down to Java function calls. It's sort
| of like choosing between Python and Java. They both do
| imperative programming with objects but they both have their
| own strengths and weaknesses.
| jdminhbg wrote:
| Thank you, very helpful.
| Blackthorn wrote:
| core.logic has a lot of limitations you pretty quickly run
| into, and they languish on their bug tracker for years now
| because nobody actually works on it.
| Pet_Ant wrote:
| Well this repo seems not to have had any commits for a year,
| so I'm not sure how much better this is:
|
| https://github.com/bobschrag/clolog/commits/main/
|
| Maybe this post will spark some interest and revitalise it a
| bit?
| cpdean wrote:
| I absolutely love the aesthetic of a repo having a giant
| README.md
| SOLAR_FIELDS wrote:
| I think about docs a lot and the best docs are the ones that
| are easiest to find. There is few things right in front of you
| more than README.md
| AtlasBarfed wrote:
| So is prolog just a big SAT solver?
| drob518 wrote:
| No, but they share logic as the foundation. A SAT solver merely
| solves a series of Boolean equations, typically in conjunctive
| normal form. Prolog has deduction capabilities that go far
| beyond that, where you can reason over a tree data structure,
| computing various parts of it according to a set of
| constraints. A SAT solver is not Turing complete. Prolog is.
| You could use Prolog to write a SAT solver (though it wouldn't
| be very competitive with solvers written in C or other
| languages).
| perdomon wrote:
| Coming from Javascript and PHP, this seems completely foreign and
| alien and I have almost no idea what I'm looking at. Can't wait
| to try it.
| alex-robbins wrote:
| It strikes me as too bad that this API is so imperative. You can
| see a pattern over and over in the README where they have `do`
| blocks, in which they clear some global state (`initialize-
| prolog`), then add some assertions back into that global state
| (via side-effectful API calls), and finally run a query (which is
| implicitly a query on the state that's been built up). Why not
| represent the knowledge base as a normal Clojure data structure,
| rather than as the effect of a sequence of API calls? Then it can
| be passed in by the caller alongside the query, instead of being
| stored as mutable state.
|
| This isn't just a style thing, either; there are consequences.
| REPL-driven development loses a lot of its slickness when some
| expressions can only be eval'd in a special context.
|
| Also, what am I supposed to do if two different parts of my
| program want to use Clolog? If I'm using Clolog, and one of my
| dependencies is using it too, will we end up trashing each
| other's global state? (The case of external dependencies is just
| an example. Let's say I have an application that sets up the
| Clolog state and runs a query. Part of the setup involves calls
| to other parts of my application. At the time the code was
| written, those other parts didn't use Clolog, but now they do,
| and there's a bug, because those other parts are trashing the
| Clolog state that their caller had set up, before it runs its
| query.) Of course, you could get around this by adding something
| like a dynamically bound variable that points to the instance of
| state to use, but at that point you're jumping through hoops to
| support a subpar (stateful) paradigm that Clojure developers
| expect to be free of.
| Pet_Ant wrote:
| Submit a PR? If you have an idea how it would look better,
| submit it. It's nice that they got it to this point as is. Lets
| make it better.
___________________________________________________________________
(page generated 2025-04-16 17:02 UTC)