Logic programming - Is subset with only one function symbol Turing - complete? - prolog

If I have a subset of logic programming which contains only one function symbol, am I able to do everything?
I think that I cannot but I am not sure at all.
A programming language can do anything user wants if it is a Turing-complete language. I was taught that this means it has to be able to execute if..then..else commands, recursion and that natural numbers should be defined.
Any help and opinions would be appreciated!

In classical predicate logic, there is a distinction between the formula level and the term level. Since an n-ary function can be represented as an (n+1)-ary predicate, restricting only the number of function symbols does not lessen the expressivity.
In prolog, there is no difference between the formula and the term level. You might pick an n-ary symbol p and try to encode turing machines or an equivalent notion(e.g. recursive functions) via nestings of p.
From my intution I would assume this is not possible: you can basically describe n-ary trees with variables as leaves, but then you can always unify these trees. This means that every rule head will match during recursive derivations and therefore you are unable to express any case distinction. Still, this is just an informal argument, not a proof.
P.S. you might also be interested in monadic logic, where only unary predicates are allowed. This fragment of first-order logic is decidable.

Related

How to use Coq as calculator or as forward chaining rule engine/sequence application tool?

Is it possible and how to use Coq as calculator or as rule engine in foward chaining mode? Coq script usually requires to declare the goal for which the proof can be found. But is it possible to go in other direction, e.g. to compute the set of some consequences bounded by some rule, e.g., by some number of steps. I am especially interested in the sequent calculus of full first order logic. I guess (but I don't know) that there are some implementation or package for some type of sequent calculus for first order logic, but it is for theorem proving. I woul like to use such sequent calculus to derive consequences in some directed order. Is that possible in Coq and how?
Coq can be used for forward reasoning as well, in particular with the assert tactic. When you write assert (H : P)., Coq generates a subgoal that asks you to prove P. When this goal is complete, it resumes the original proof, extending its context with a hypothesis H : P.
The ltac language used to write Coq scripts has a match goal operator that allows you to inspect the shape of your goal. This allows you to progressively saturate your proof context with new facts derived from your current assumptions using the assert tactic, and to stop once certain conditions are met. Adam Chlipala's CPDT book has a nice chapter covering these features of tactic programming.

Prolog - Avoid Infinite Loop

I am currently studying logic programming, and learn Prolog for that case.
We can have a Knowledge Base, which can lead us to some results, whereas Prolog will get in infinite loop, due to the way it expands the predicates.
Let assume we have the following logic program
p(X):- p(X).
p(X):- q(X).
q(X).
The query p(john) will get to an infinite loop because Prolog expands by default the first predicate that is unified. However, we can conclude that p(john) is true if we start expanding the second predicate.
So why doesn't Prolog expand all the matching predicates (implemented like threads/processes model with time slices), in order to conclude something if the KB can conclude something ?
In our case for example, two processes can be created, one expanded with p(X) and the other one with q(X). So when we later expand q(X), our program will conclude q(john).
Because Prolog's search algorithm for matching predicates is depth-first. So, in your example, once matching the first rule, it will match again the first rule, and will never explore the others.
This would not happen if the algorithm is breadth-first or iterative-deepening.
Usually is up to you to reorder the KB such that these situations never happen.
However, it is possible to encode breadth-first/iterative-deepening search in Prolog using a meta-interpreter that changes the search order. This is an extremely powerful technique that is not well known outside of the Prolog world. 'The Art of Prolog' describes this technique in detail.
You can find some examples of meta-interpreters here, here and here.

Prolog - what sort of sentences can't be expressed

I was wondering what sort of sentences can't you express in Prolog? I've been researching into logic programming in general and have learned that first-order logic is more expressive compared to definite clause logic (Horn clause) that Prolog is based on. It's a tough subject for me to get my head around.
So, for instance, can the following sentence be expressed:
For all cars, there does not exist at least 1 car without an engine
If so, are there any other sentences that CAN'T be expressed? If not, why?
You can express your sentence straightforward with Prolog using negation (\+).
E.g.:
car(bmw).
car(honda).
...
car(toyota).
engine(bmw, dohv).
engine(toyota, wenkel).
no_car_without_engine:-
\+(
car(Car),
\+(engine(Car, _))
).
Procedure no_car_without_engine/0 will succeed if every car has an engine, and fail otherwise.
The most problematic definitions in Prolog, are those which are left-recursive.
Definitions like
g(X) :- g(A), r(A,X).
are most likely to fail, due to Prolog's search algorithm, which is plain depth-first-search
and will run to infinity and beyond.
The general problem with Horn Clauses however is, that they're defined to have at most one positive element. That said, one can find a clause which is limited to those conditions,
for example:
A ∨ B
As a consequence, facts like ∀ X: cat(X) ∨ dog(X) can't be expressed directly.
There are ways to work around those and there are ways to allow such statements (see below).
Reading material:
These slides (p. 3) give an
example of which sentence you can't build using Prolog.
This work (p. 10) also explains Horn Clauses and their implications and introduces a method to allow 'invalid' Horn Clauses.
Prolog is a programming language, not a natural language interface.
The sentence you show is expressed in such a convoluted way that I had hard time attempting to understand it. Effectively, I must thanks gusbro that took the pain to express it in understandable way. But he entirely glossed over the knowledge representation problems that any programming language pose when applied to natural language, or even simply negation in first order logic. These problems are so urgent that the language selected is often perceived as 'unimportant'.
Relating to programming, Prolog lacks the ability to access in O(1) (constant time) any linear data structure (i.e. arrays). Then a QuickSort, for instance, that requires access to array elements in O(1), can't be implemented in efficient way.
But it's nevertheless a Turing complete language, for what is worth. Then there are no statements that can't be expressed in Prolog.
So you are looking for sentences that can't be expressed in clausal logic that can be expressed in first order logic.
Strictly speaking, there are many, simply because clausal logic is a restriction of FOL. So that's true by definition.
What you can do though is you can rewrite any set of FOL sentences into a logic program that is not equivalent but with good properties. So for example if you want to know if p is a consequence of your theory, you can use equivalently the transformed logic program.
A few notes on the other answers:
Negation in Prolog (\+) is negation as failure and not first order logic negation
Prolog is a programming language, as correctly pointed out, we should be talking about clausal logic instead.
Left recursion is not a problem. You can easily use a different selection rule, or some other inference mechanism.

What does the s() predicate do in Prolog?

I have been trying to learn Prolog, and am totally stumped on what the predicate s() does.
I see it used often and there is so little resources on the internet about Prolog that I cannot find an answer.
Ex.
/* sum(Is,S) is true if S is the sum of the list of integers Is. */
sum([],0).
sum([0|Is],S):-sum(Is,S).
sum([s(I)|Is], s(Z) ):-sum([I|Is],Z).
s/1 does not do anything in itself, and it's not really a predicate. They are just terms, a representation of the successor of their argument. So, s(0) is used to represent the successor of 0 (i.e. 1), s(s(0)) is used to represent the successor of s(0) (i.e. 2), and so on and so forth. They are so widespread in Prolog because Prolog is quite fine a language to perform symbolic computation, whereas even simple arithmetic operations feel clunky, meaning that they are not seamlessly integrated with the programming paradigm.
s/1 stands for successor. It's used to represent numbers in a logically accessible ways.
It is Prolog-implementation specific. It refers to a successor-predicate, see this for some more info

Recursive languages vs context-sensitive languages

In Chomsky's hierarchy, the set of recursive languages is not defined. I know that recursive languages are a subset of recursively enumerable languages and that all recursive languages are decidable.
What I'm curious about is how recursive languages compare to context-sensitive languages. Can I assume that context-sensitive languages are a strict subset of recursive languages, and therefore all context-sensitive languages are decidable?
To recognize a recursive language you need a kind of automaton named Decider . It is exactly a Turing Machine tricked by a limited control flow, that is, to ensure it will always halt.
Concerning context-sensitive languages, they are indeed a proper subset of recursive ones. It's trivial giving that the minimal automaton to recognize a context-sensitive language, a Linear bounded automaton is strictly less powerful than a decider. I guess that it would also be possible to demonstrate based on grammar restriction rules.
If your question is only if every context sensitive language is in the set of all recursive languages, you should try to prove it the classical way through formal automata. Ask yourself what formal automaton can simulate generation of context sensitive language and what is used to generate recursive language. Then just try to simulate one using the other. Once you look up the right automata in your textbook, you will sure be able to prove what you want.
set of context sensitive languages are a proper subset of recursive languages.
You dont have to assume this, refer to Peter Linz's book for proof.
According to Papadimitriou's book (3.4.2 (e)), context-sensitive grammars are equivalent to NSPACE(n), which is a proper subset of recursive languages. So, yes, your assumption is correct.
As per my references , I would also say that Context Sensitive Languages are a proper subset of a set of all Recursive Languages.You can find this proof in any Standard Textbook like
> An Introduction to Formal Languages and Automata (Edition 5) by Peter Linz

Resources