ciao-lang / ciao

Ciao is a modern Prolog implementation that builds up from a logic-based simple kernel designed to be portable, extensible, and modular.
https://ciao-lang.org
GNU Lesser General Public License v3.0
267 stars 20 forks source link

functor/3 incorrectly fails &ct #90

Open UWN opened 9 months ago

UWN commented 9 months ago

?- functor(T,F,A).

no, unexpected.
   instantiation_error. % expected, but not found
?- functor(T,1,2).

no, unexpected.
   type_error(atom,1). % expected, but not found
?- functor(T,f,5000).

no, unexpected.
   representation_error(max_arity) % expected, but not found reported 2010-06-09
|  T = f(...)                                          % alternate answer with larger max_arity
UWN commented 8 months ago

@jfmc: are you aware of another system that fails here? At least SICStus, Scryer, Trealla, GNU, Ichiban, ECLiPSe, SWI, Tau, YAP, XSB, B, Minerva, IF, IV all produce an instantiation error.

jfmc commented 8 months ago

Indeed unfortunately we still retain here the classic pre-standard behavior. It is not so much procrastination but rather that there are a few thousand calls to functor/3 in our codebase (Ciao itself and applications) that need to be carefully checked one by one. Most calls should be fine but we did identify some critical code that depends on the pre-ISO behavior. We are also aware that there are still a few issues with is/2 and arg/3 that have also been stagnated forever. The good news is that we recently started an internal student project to push conformity on this and other fronts, so we do hope to have some progress here shortly. Our intention has always been to be conformant as reasonably possible!

UWN commented 8 months ago

You are suggesting that this is an ISO only feature. But many pre-ISO systems produced this instantiation error as well. Like Quintus. And to quote the User's Guide to DECsystem-10 Prolog of 1978 (same in the 1982 manual):

    functor(T,F,N)

         The principal functor of term T has name F and arity N,  where  F
         is  either  an  atom or, provided N is 0, an integer.  Initially,
         either T must be instantiated to a non-variable, or F and N  must
         be   instantiated   to,   respectively,  either  an  atom  and  a
         non-negative integer or an integer and 0. If these conditions are
         not satisfied, an error message is given.  In the case where T is
         initially instantiated to a variable, the result of the  call  is
         to  instantiate  T  to the most general term having the principal
         functor indicated.

So it is not clear what you refer to as "classic" behavior. The most recent version of SICStus Prolog that silently failed (that I am aware of) is 0.7#7 of 1991-11. That is 32 years ago.

jfmc commented 8 months ago

Thanks @UWN for identifying when the "classic" behavior was abandoned in SICStus, and for clarifying that it was not so widespread as we thought.

UWN commented 8 months ago

For the record. A SICStus that already produces the instantiation error:


In SICStus 2.1 #5: Sat May 16 22:12:10 MET DST 1992:

| ?- [user].
| A.
{INSTANTIATION ERROR: functor/3 - arg 2}
jfmc commented 8 months ago
?- functor(T,F,A).

no, unexpected.
   instantiation_error. % expected, but not found
?- functor(T,1,2).

no, unexpected.
   type_error(atom,1). % expected, but not found
?- functor(T,f,5000).

no, unexpected.
   representation_error(max_arity) % expected, but not found reported 2010-06-09
|  T = f(...)                                          % alternate answer with larger max_arity

(internal note) For the record, these bugs are captured in https://github.com/ciao-lang/iso_tests/blob/master/src/iso_tests_basic_term.pl:

pmoura commented 8 months ago

Also for the record:

$ logtalk_tester -p ciao -g "set_logtalk_flag(clean,off)" -w -t 360
% Batch testing started @ 2023-12-21 11:20:36
%         Logtalk version: 3.74.0-b01
%         Ciao Prolog version: 1.22.0-commit_info(master,18eeb4b77ade15a73508323bc768f5d2c68abc6a,2023-07-22 14:50:23 +0200,1.22.0)
% ...
% 564 test sets: 422 completed, 101 skipped, 13 broken, 0 timedout, 28 crashed
% 6744 tests: 186 skipped, 4918 passed, 1640 failed (4 flaky)
%
% Batch testing ended @ 2023-12-21 11:45:02

In particular:

% logtalk/tests/prolog/predicates/functor_3
%         19 tests: 0 skipped, 12 passed, 7 failed (0 flaky)
%         completed tests from object tests in 1 second
%         clause coverage n/a
!     iso_functor_3_12: failure (in 0.000288000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(instantiation_error,A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 67-71
!     iso_functor_3_13: failure (in 0.000292000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(instantiation_error,A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 72-74
!     iso_functor_3_14: failure (in 0.000249000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(type_error(integer,a),A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 75-77
!     iso_functor_3_15: failure (in 0.000249000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(type_error(atom,1.5),A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 78-80
!     iso_functor_3_16: failure (in 0.000250000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(type_error(atomic,foo(a)),A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 81-83
!     iso_functor_3_17: failure (in 0.000140000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(representation_error(max_arity),A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 89-90
!     iso_functor_3_18: failure (in 0.000247000 seconds)
!       test goal failed but should have thrown an error:
!         expected error(domain_error(not_less_than_zero,-1),A)
!       in file logtalk/tests/prolog/predicates/functor_3/tests.lgt between lines 92-94
UWN commented 4 days ago

The manual of version 3 of Quintus Prolog already discusses this very example. While I do not know the precise date of release, I do know that Quintus 3 existed April/May of 1990 since at that time in the WG17 meeting in Vienna it was used to demonstrate the executable specification (and I had to borrow a SPARCstation 1 from a vendor).