Prolog gives me headaches in places that other programming languages cannot reach, and I would not for an instant want to try to use it to create any significant sort of application; but it does teach a very fundamental and very important lesson.
Programs should, as much as is practicable, try to function as executable specifications, and to state their purpose in declarative form.
To achieve this, we can write somewhat general purpose machines, the parameters for which serve as the behavior specification.
In Prolog, the inference engine is the general purpose machine, the rule database is the executable specification.
For the majority of real-world projects that I have encountered, it has been possible to write libraries that together constitute a set of (somewhat less) general purpose machines; the configuration for which, in declarative form, serves as the "executable" specification of the problem.
All of my work therefore tends to be divided into two parts: A set of general purpose libraries that provide some configurable functionality, and a set of products that combine and configure those libraries, doing double duty as specification-documentation and top-level executable.
From Prolog comes the feeling that the declarative form is more suitable than the imperative form for the specification and communication of program function; and therefore the imperative parts of the program should be subsumed under a declarative layer.
Of course, none of this is new. Also, this notion does not by itself guarantee success, and must be tempered by simplicity and common sense.