问题
Under the closed-world assumption,
what is not currently known to be true, is false
Prolog's semantics is often said to follow the closed-world assumption, for example, here:
Prolog is based on closed world assumption (CWA) -- that is, if a proposition is not in the fact database and not derivable from the fact database, then it is not true.
However, it doesn't quite behave this way. Under CWA, I'd expect
?- a.
false.
But instead, in SWI-Prolog, I get:
?- a.
ERROR: Undefined procedure: a/0 (DWIM could not correct goal)
Why is that? Is it wrong to say that Prolog is based on CWA?
回答1:
When talking about Closed-World Assumption (CWA) in the context of Prolog, a distinction must be made between unknown predicates versus know predicates to the (runtime) system. In both cases, predicates with or without clauses.
Calling an unknown predicate will, by default, raise a predicate existence error. There's a standard flag, unknown
, whose default value is error
, that can be set to fail
. That will give you the behavior that you're apparently looking for. Sill, I strongly advise you to keep the flag set to its default value of error
, as it allows easier detection of programming predicates (e.g. typos in predicate names or arity).
What makes a predicate known to the runtime? Predicate directives or predicate clauses. The most familiar example is the dynamic/1
directive. If your code consists solely of the following text:
:- dynamic(foo/1).
Then, after compiling and loading, you can expect:
?- foo(_).
no.
But other directives have the same effect (e.g. multifile/1
and discontiguous/1
, assuming that is a standard conforming Prolog implementation!).
Thus, for known predicates, the interpretation of CWA in Prolog is simple: what we cannot prove to be true, is false. I.e. negation by failure, which is not the same as logical negation. The name Prolog comes from programming in logic but Prolog also aims to be a pragmatic and practical programming language.
What's lacking in Prolog (and is provided by e.g. Logtalk) is being able to declare a predicate without being forced to declare it as dynamic, or multifile, or ... or requiring providing clauses for it (see e.g. this example). This provides simpler and clearer CWA semantics: calling a declared predicate with no clauses fails (without the need of messing with the problematic unknown
flag); calling a non-declared predicate raises a predicate existence error.
Hope this helps. Searching for negation as failure should provide further clarification.
回答2:
Your query must be in the language itself, for a
to be a proposition a/0
must be in the language, i.e., defined as a predicate. All nullary predicates in the language are propositions. You cannot query a new term as predicate without first adding it to the language.
For a/1
when you define it just as a(b).
it is in the language, then the query a(X), dif(X,b)
will fail since the prolog system does not know any other terms that satisfy it and assuming close world there are no other.
来源:https://stackoverflow.com/questions/65014705/is-prolog-really-based-on-the-closed-world-assumption