## Universal Quantification

Discussions related to Visual Prolog
Thomas Linder Puls
VIP Member
Posts: 1175
Joined: 28 Feb 2000 0:01
It is of course important to know what we are talking about, but I think the original post explains that very well.

When deciding whether it should be a construction in the language there are several parameters to take into account.

First of all whether it makes sense, which I clearly think the construction does: It is a "pure" logical operation that is faithful to the original declarative/logical reading of the Prolog languages.

Secondly whether it will actually be used, here I have a little more doubt: I guess that Martin that gave the suggestion will use it "extensively", perhaps because he programs more in logical terms than we actually do at PDC (I doubt that we will use it much, if at all, here).

Thirdly, whether alternative code (using already existing constructions) is complex and "unpleasant" or simple and "nice". The alternative code using two negations, comes from the normal logical duality of existential and universal quantifiers: If it is not possible to find "something" that does not fulfils "something", then every thing fulfills "something". Though this is a fundamental property of logic, the code with two nested nots, is both clumsy and unintuitive.
Fourthly it is also necessary to find good syntax for the construction. Good syntax should express the intuition of the semantics. Both so that people that read the code without knowing the construction in complete details, gets the correct idea about what it does, but also so that when they are looking for a construction that does something, they guess that this may be the one that does what they are looking for.

I think this construction qualifies on making sense and not having good alternative code, but I think it disqualifies on usability and syntax (also considering that there exist a mathematical paper that uses for all ... holds ...).
Regards Thomas Linder Puls
PDC

Martin Meyer
VIP Member
Posts: 280
Joined: 14 Nov 2002 0:01
Thomas, OK

Peter, I don't understand your use of dynamic cuts. An equivalent to a foreach-term resp. a forAll-predicate can be coded via a generator-fail-loop without dynamic cuts:

Code: Select all

``````class predicates
foreach_ : (
function_nd{Type} Gen,
predicate{Type} Body).
clauses
foreach_(Gen, Body) :-
Item = Gen(),
Body(Item),
fail.
foreach_(_, _).

class predicates
forAll : (
function_nd{Type} Gen,
predicate_dt{Type} Body)
determ.
clauses
forAll(Gen, Body) :-
Item = Gen(),
if not(Body(Item)) then
!
end if,
fail.
forAll(_, _).``````
Best regards
Martin

Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29
Martin,
I was motivated by the comment from Paul about programming when foreach/do and if/then/else were not available in Prolog. I could not figure out how you would write the forall() without using the dynamic cut.
Mutall Data Management Technical Support

Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29
Martin,
I thought about this a little bit more and found out why you did not understand the dynamic cuts in my code. In the first case, I was not really modelling foreach_() as currently implemented by the foreach/do construct. Your implementation is the correct one.

I revisited the for forAll_() without the dynamic cut and came up with this version, which I think is different from yours. Is it not?

Code: Select all

``````class predicates
forAll_ : (function_nd{Type} Gen, predicate_dt{Type} Body) determ.
clauses
forAll_(Gen, Body) :-
Item = Gen(),
not(Body(Item)),
!,
fail.
forAll_(_, _).``````
Mutall Data Management Technical Support

Martin Meyer
VIP Member
Posts: 280
Joined: 14 Nov 2002 0:01
Ohhh, I had not seen that. Of course your version is the better one.

Many regards
Martin

Thomas Linder Puls
VIP Member
Posts: 1175
Joined: 28 Feb 2000 0:01
To complete the circle :

Code: Select all

``````clauses
forAll_(Gen, Body) :-
Item = Gen(),
not(Body(Item)),
!,
fail.
forAll_(_, _).``````
is the same as

Code: Select all

``````clauses
forAll_(Gen, Body) :-
Item = Gen(),
not(Body(Item)),
!,
fail
or
succeed.``````
And since A, !, fail or succeed is the same as not(A) (aka cut-fail-negation) this clause is the same as:

Code: Select all

``````clauses
forAll_(Gen, Body) :-
not((
Item = Gen(),
not(Body(Item))
)).``````
Compare this to the very first code:

Code: Select all

``````not
((
Gen,
not(DetermBody)
))``````
Regards Thomas Linder Puls
PDC

Peter Muraya
VIP Member
Posts: 147
Joined: 5 Dec 2012 7:29
Thomas and Martin,
I'm always learning something new from his forum. cut-fail-negation ... that is news to me. It has helped me understand the following construct which at first was not obvious.

Code: Select all

``````not
((
Gen,
not(DetermBody)
))``````
You hope that this sort of thing does not happen a lot in your code; otherwise it becomes very difficult to follow for ordinary mortals.
Mutall Data Management Technical Support