I have no idea how people solve constraint problems without prolog and clpfd/z. these types of problems seem to be everywhere, and yet prolog still has a very small user base, how come?
A lot of constraint problems can be solved by SAT/SMT solvers. Many other problems can be solved via Linear/Integer Programming Algorithms. Then are large fields of Combinatorics, Operations Research and Graph Theory with many other kinds of Algorithms.
Prolog uses backtracking search. Backtracking search is quite a good and generic approach. Its not the only approach. Depending on your problem space you can probably totally avoid Prolog.
Personally, I would not choose to solve a constraint programming problem in Prolog, unless I really needed to use a specific global constraint that is only available in some Prolog engine (such as the geost constraint in SICStus Prolog).
When I need to solve a CP problem, I typically do one of the following
* Write a simple model in MiniZinc. This is great for experimentation and testing different solvers to see which kind of solver might be suitable (different CP solvers, MIP solvers, etc)
* For some cases or if I need to integrate with a larger system I write my code using a library directly, such as Gecode, Choco, or or-tools. Using a system directly has the benefit that it is possible to program a custom search heuristic, which I find is often very useful for solving problems in practice.
* Write a custom algorithm. Sometimes the right answer is to just write some code solving the problem directly.
I find models written in a modeling language such as MiniZinc or in a traditional
Programming language such as C++, Java, or Python to be easier to read and reason about than Prolog programs that solve constraint problems. That is a personal preference, and varies depending on familiarity.
CPLEX is one of the best MIP (mixed integer) solvers out there. They also have a "CP" constraint programming solver as well. If I needed to solve that kind of problem, I'd just call out to the CPLEX API. As much as I love things like Prolog, it's always been easier to me to have an application mostly be written in a popular language (C#, Python, Java..etc) using more traditional programming techniques (OO) and call out to a specific solver for just the tiny piece I need that does the optimization. If there is a Prolog out there that works for your problem set, you can use the same strategy, but you'd have to learn logic programming which is challenging in my eyes (and likely those of many). Prolog is seriously cool though.
"Can this user do this thing given these constraints?" or even "Show me all the things this user can do given these constraints"
Our team is solving for this use case. While we focus a lot on abstractions, APIs, etc. that are appropriate for our use case, under the hood everything is driven by an embeddable logic language that we write in Rust, called Polar: https://docs.osohq.com/reference/polar.html
That is, trying to converge a system from current state to desired state.
If it were written with logic programming and were able to run things in reverse, then it would be able to explain exactly why it is unable to converge the system to the desired state, and what other factors it is waiting on to do so. I think that would greatly enhance observability in a complex system.
I was also in the process of writing a chat bot accepting commands be able to autocompletion that takes authorization into account. So given what the user has typed so far, and what it is authorized to use, it would be able to show the available commands.
As a proof of concept, I implemented a test scenario generator for work using Prolog. There was an existing tool and we stuck with it, but we essentially recreated a large bit of Prolog (a corollary to Greenspun's Tenth Rule) in doing so. The protocol being tested (a back and forth between, for my demo purposes, two nodes) was fairly easy to codify (if not byte-for-byte, structurally) in Prolog. So I could put in a message and have the program tell me what response was expected. Supply a few constraints for the scenario and you could generate a sequence of messages for both sides, one being what we'd transmit to the system under test, and the other the expected response back.
In principle, this would have allowed us to do something akin to property based integration testing (we only tested the fully integrated system, no partial integrations of subsystems or unit testing). The same program could have been used to analyze recordings of real world communications to see if they were correct (to the spec) and where they diverged if not, with only minor modification to the way we interacted with it.
That's actually one of the really nice things about Prolog, you can work in both directions with the same program, you can't do that in any of the mainstream programming languages without libraries (minikanren, for instance, allows for an embedding of this in many languages).
For instance, while trivial, you can use append/3 in Prolog to get the result of appending two lists, or to find all prefixes and suffixes of a list, or to find a particular prefix/suffix given both the combined list and the other (suffix or prefix, respectively).
append([1,2], [3,4], AB). -- AB = [1,2,3,4]
append(A, [3,4], [1,2,3,4]). -- A = [1,2]
append([1,2], B, [1,2,3,4]). -- B = [3,4]
append(A, B, [1,2,3,4]). -- A = [], B = [1,2,3,4];
-- A = [1], B = [2,3,4];
-- ...
By writing one program, perhaps supplying synonyms to get something that reads better, you can get all these options depending on which parts you choose to supply as knowns and which you leave as variables.
Board game rules. "Given the current state of the board, what are all the actions player 1 can do? Choosing one of those actions, which targets can they choose from?" etc.
There are techniques that are purely academic, but there are lots of cases where constraint modeling turns up and is useful. In my experience, the area where constraint programming is used the most is in applications that do things like scheduling and rostering.
Any kind of multi-component mechanical modeling will require the use of constraints. Single components in mechanical modeling literally use dimensional constraints.