A practical (but not fielded) use that I found with Prolog: programs are multi-use. That is, if you mentally model (and I think this is natural for new Prolog programmers) a program as running in one direction, you will be pleasantly surprised to find that you can use the same program to accomplish multiple effects. Using the built-in append/3 as an example:
% find the list resulting from appending two lists
append([1],[2],C). %% => C = [1,2]
% find the prefix given a suffix
append(A,[2],[1,2]). %% => A = [1]
% find the suffix given a prefix
append([1],B,[1,2]). %% => B = [2]
% find all prefixes and suffixes
append(A,B,[1,2]).
A = [], B = [1,2];
A = [1], B = [2];
A = [1,2], B = [];
false ;; no more results
The first line is what most programmers new to Prolog will be used to, a function performs a computation in a forward fashion (here: given two knowns, calculate something). But all the others come along "for free" (if you write it correctly, which isn't too hard once you've learned a bit of the language and style).
My practical use for this was with a (prototyped, not fielded) scenario generator. Using the rules (specification for the protocol) I could generate arbitrary scenarios. I could constrain them by filling in some variables, but leaving others blank. And I could take an existing scenario and determine if it was even valid. Using append again:
append(A,[3],[1,2]). %% => false
Now, in my situation instead of a hardcoded [1,2] I had a recording of an exchange between nodes, and I could use this to get an answer to why it didn't conform to the spec. One program that could be used in many different ways.
The other reason to use Prolog, this was a much higher level of abstraction to work with than what we ended up using. It was much shorter, but less familiar to others. So we ended up with a C# + SQL solution where we had to write each variation of the program (generate, test for validity, identify problems).
My practical use for this was with a (prototyped, not fielded) scenario generator. Using the rules (specification for the protocol) I could generate arbitrary scenarios. I could constrain them by filling in some variables, but leaving others blank. And I could take an existing scenario and determine if it was even valid. Using append again:
Now, in my situation instead of a hardcoded [1,2] I had a recording of an exchange between nodes, and I could use this to get an answer to why it didn't conform to the spec. One program that could be used in many different ways.The other reason to use Prolog, this was a much higher level of abstraction to work with than what we ended up using. It was much shorter, but less familiar to others. So we ended up with a C# + SQL solution where we had to write each variation of the program (generate, test for validity, identify problems).