[0] https://www.complang.tuwien.ac.at/ulrich/prolog_misc/acomip....
For those with familiarity with both Prolog and Erlang, can you comment on the similarities and differences between? Is/was Erlang basically Prolog with OTP bolted on?
% Prolog
next_light(green, yellow).
next_light(yellow, red).
next_light(red, green).
% Erlang
next_light(green) -> yellow;
next_light(yellow) -> red;
next_light(red) -> green.
Notable differences:- `;` in Erlang indicates multi clause function
- In Prolog next_light is database, in Erlang it's just a function
Question: What's the light before green?
% Erlang
% Returns actual value
prev_light_search() ->
[State || State <- [green, yellow, red], next_light(State) == green].
% Prolog (?- means that it's in query mode)
?- next_light(Light, green).
So syntax IS similar though the thing is that Prolog is more like binding and quering database and Erlang is executing function.In a nutshell Erlang is more like: "when I have X, then I can calculate Y" and Prolog like "If I want Y, what's the X".
Early versions of Erlang were implemented in Prolog, which is why Erlang's syntax looks a whole lot like Prolog's, but beyond that they're not very similar.
I guess what may also have contributed is that there are a number of concurrent logics implemented in Prolog for prototyping Erlang's scheduler such as Concurrent Transaction Logic ([1]).
Understanding is a personal achievement and has nothing to do with "forbidden knowledge" when the source of said knowledge is both quoted above and freely available.
I don't think I've ever felt like it's OK for my program to provide a list of answers where some are right and some are wrong, but reading this... and generally believing in P != NP.... maybe that's a decent way of looking at some stuff!
1) Read the JSON with Prolog (there's a library) and assertz() the facts from that, building an immutable database in the first phase before applying the rules in the second phase.
2) Externally transform the JSON into Prolog facts, load that into the app on startup and apply the same rules to it.
I agree that mutating the database in the second phase is probably a bad idea, but that's not the same as saying "assertz() always bad". I'd read his site before it appeared on HN and whilst there a lot of very good stuff on it, some of it reminds me of FP purist edicts - fine if you want to go that way and it's appropriate to your problem, but that isn't always going to be the case. That was the basis of my earlier (downvoted) "Mostly overblown" comment.
But nice to see Prolog mentioned at all on HN :-)
The version without ! looks identical to the version with ! except only the ! is removed - is this a joke?
import solver
solver.add_variable(x)
solver.variable_range(x, 0, 100)
solver.add_constraint(x, greater_than, 50)
solver.solve_for(x)
in pseudo-Prolog it can be: :- using constraint solver library
X in 0..100,
X #> 50,
label(X)
where "in" and "#>" were added into the language at runtime by the import of the constraint library. That is, it calls out to a custom 'function' which tells the constraint solver to restrict possible values for for X from 0..100 down to 51..100.> "and what ! does"
This is a concept which doesn't translate easily to other languages, but analogously it's like the performance difference between this code which always searches the entire haystack:
found = false
for item in haystack:
if item == 'needle':
found = true
return found
and this which stops searching the haystack if the needle is found, but still searches the entire haystack in the worst case: for item in haystack:
if item == 'needle':
return true
return false
The catch being that ! is not exactly a performance thing, it's an instruction to the Prolog runtime to skip some of the code, which can speed up performance but if you throw it in carelessly, your code no longer gives the right answers.[1] They aren't Prolog "functions", they are predicates, functions are different, but it will do for this explanation.
is/2 is arithmetic evaluator. It runs only in one direction and it does not solve equations.
#>, #=, etc. are constraints, like (in)equalities over linear arithmetic. When constraints have the form of some known theory (like in SMT solvers), they can be solved (incrementally). That is called "constraint logic programming" (CLP). Modern Prolog systems are indeed CLP systems.
Prolog is older than CLP. CLP is older than SMT. Prolog+CLP systems are turing complete, can be used as programming languages. SMT is powerful but not a programming language.
Can "impure" features be avoided? Not in all cases. Think of them as 'unsafe' in Rust, but less dangerous.
Markus pushes for more purity in Prolog (using CLPFD), but sometimes some impurity (or imperative-like code with side-effects) is the best solution. Sometimes the pure solution is also the better. In other cases, it is not. Better compilers and static analyzers can reduce the friction between these worlds.
Take away: do pure code if you can afford it and it looks like a natural solution to your problem, use impure features later if you really need them.
https://www.swi-prolog.org/pldoc/man?section=clpfd-integer-a...
Radio Yerevan: A listener asks: "Is it true that in Moscow, on Red Square, they are giving away cars?"
Our answer: "Yes, it is true. Except it isn't in Moscow, but in Leningrad. And it isn't on Red Square, but on Palace Square. And they aren't cars, but bicycles. And they aren't giving them away, they are stealing them."