1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8% 
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License. 
13% 
14% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
15% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
16% Portions created by the Initial Developer are
17% Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): 
20% 
21% END LICENSE BLOCK
22
23:- comment(alias, "Type Testing").
24:- comment(summary, "Meta-logical built-ins to test the type of terms").
25:- comment(categories, ["Built-In Predicates"]).
26
27:- comment(nonground / 2, [
28	summary:"Succeeds if Term is not a ground term and binds Variable to one of the
29variables inside Term.
30
31",
32	amode:(nonground(?,-) is semidet),
33	desc:html("   Used to test whether Term is not ground i.e. whether it contains at
34   least one uninstantiated variable.  The argument Variable is unified with one of
35   the variables inside Term, i.e. with one of the responsibles for its
36   non-groundness.  When Term contains several variables, it is not
37   specified which one will be returned as Variable.  As usual, attributed
38   variables are also considered variables.
39
40<P>
41"),
42	args:["Term" : "Prolog term.", "Variable" : "A variable."],
43	fail_if:"Fails if Term is ground",
44	eg:"
45Success:
46    nonground(Term, V).       % unifies V with Term
47    nonground(f(a,B,c), V).   % unifies V with B
48    nonground([x,Y|Z], V).    % unifies V with Y or Z
49    nonground(s(X{a}), V).    % unifies V with X{a}
50
51Fail:
52    nonground(atom, V).
53    nonground(likes(man, woman), V).
54
55
56
57",
58	see_also:[nonground / 1, nonground / 3, nonvar / 1, var / 1]]).
59
60:- comment(nonground / 3, [
61	summary:"Succeeds if Term contains at least N different variables, and returns N of
62them in the list VarList.
63
64",
65	amode:(nonground(+,?,-) is semidet),
66	desc:html("   Used to test whether Term contains at least N different variables.  The
67   argument VarList is unified with a list of exactly N of those variables.
68   If Term contains more than N variables, it is not further specified
69   which ones will be in the list and in which order.  As usual, attributed
70   variables are also considered variables.
71
72<P>
73   Note that this predicate is a generalisation of nonground/1 and
74   nonground/2 which could be written as:
75
76<P>
77<PRE>
78    nonground(Term) :- nonground(1, Term, _).
79    nonground(Term, Var) :- nonground(1, Term, [Var]).
80</PRE>
81"),
82	args:["N" : "Integer.", "Term" : "Prolog term.", "VarList" : "List or variable."],
83	fail_if:"Fails if Term contains less than N variables",
84	exceptions:[4 : "N is not instantiated.", 5 : "VarList instantiated but not to a list.", 6 : "N is not positive."],
85	eg:"
86Success:
87    nonground(1, Term, L).       % gives L = [Term]
88    nonground(1, f(a,B,c), L).   % gives L = [B]
89    nonground(2, [X,Y,Z], L).    % gives L = [Y,X]
90    nonground(2, [X,Y,Z], L).    % gives L = [Y,X]
91    nonground(1, s(X{a}), L).    % gives L = [X{a}]
92
93Fail:
94    nonground(1, atom, L).
95    nonground(2, f(a,B,c), L).
96    nonground(2, [X,X,X], L).
97
98
99
100",
101	see_also:[nonground / 1, nonground / 2, nonvar / 1, var / 1]]).
102
103:- comment(current_atom / 1, [
104	summary:"Succeeds if Atom is an atom in the system.
105
106",
107	amode:(current_atom(+) is det),
108	amode:(current_atom(-) is multi),
109	desc:html("   Used to return all currently defined atoms.
110
111<P>
112   Note that once an atom name is specified for the first time it is
113   automatically made known to the system, so calls to current_atom/1 with
114   any atom as an argument will always succeed.
115
116<P>
117"),
118	args:["Atom" : "Atom or variable."],
119	exceptions:[5 : "Atom is not instantiated to an atom."],
120	eg:"
121Success:
122   current_atom(eclipse).
123   current_atom(anything).
124   current_atom('My atom').
125
126   [eclipse]: current_atom(X).
127
128   X = []    More? (;)         % RETURN pressed
129   yes.
130   [eclipse]:
131
132Error:
133   current_atom(1).           Error 5.
134   current_atom(man(1)).      Error 5.
135
136
137
138",
139	see_also:[atom / 1, current_functor / 1]]).
140
141:- comment(current_functor / 1, [
142	summary:"Succeeds if PredSpec is a functor known to the system.
143
144",
145	amode:(current_functor(++) is semidet),
146	amode:(current_functor(-) is multi),
147	desc:html("   Used to test whether PredSpec is a functor known to the system or to
148   return all functors defined.
149
150<P>
151   Note that PredSpec is specified in the format Name/Arity and may be
152   specified with Name as an atom or variable and/or Arity as an integer or
153   variable.
154
155<P>
156"),
157	args:["PredSpec" : "Functor in the form Name/Arity or variable."],
158	fail_if:"Fails if PredSpec is not a currently known functor",
159	exceptions:[5 : "PredSpec is instantiated but not in the format Atom /    Integer"],
160	eg:"
161Success:
162   current_functor(findall/N).
163   current_functor(N/4).
164   current_functor((',')/2).
165
166   [eclipse]: current_functor(X).
167
168   X = '' / 0     More? (;)
169
170   X = findall / 0     More? (;)
171
172   X = findall / 3     More? (;)
173
174   X = at_eof_handler / 0     More? (;)    % RETURN pressed
175   yes.
176   [eclipse]:
177
178Fail:
179   current_functor(myfunctor/100).
180
181Error:
182   current_functor(abc)           Error 5.
183   current_functor(man(1)).       Error 5.
184
185
186
187",
188	see_also:[atom / 1, current_atom / 1, current_op / 3]]).
189
190:- comment(atom / 1, [
191	summary:"Succeeds if Atom is a Prolog atom.
192
193",
194	amode:(atom(?) is semidet),
195	desc:html("
196    Used to test whether Atom is an atom.
197    Note that this includes the empty list [].
198<P>
199"),
200	args:["Atom" : "Prolog term."],
201	fail_if:"Fails if Atom is not an atom",
202	eg:"
203Success:
204        atom(atom).
205        atom('Anything').
206        atom(*).
207        atom([]).
208        atom(#).
209        atom($).
210        atom(/).
211        atom(\\).
212
213Fail:
214        atom(1).
215        atom(this(is,a,structure)).
216        atom(X).
217
218
219
220",
221	see_also:[var / 1, is_list/1, is_array/1,callable/1, type_of / 2]]).
222
223:- comment(atomic / 1, [
224	summary:"Succeeds if Term is an atom, a number, or a string.
225
226",
227	amode:(atomic(?) is semidet),
228	desc:html("
229	Used to test whether Term is an atomic term.
230	This is the negation of compound/1.
231"),
232	args:["Term" : "Prolog term."],
233	fail_if:"Fails if Term is not an atom, a number or a string",
234	eg:"
235Success:
236    atomic(atom).
237    atomic(1.4).
238    atomic(3).
239    atomic(\"Hello world\").
240    atomic([]).
241
242Fail:
243    atomic([1,3,3,6]).
244    atomic(this(is,a,structure)).
245    atomic(X).
246
247
248
249",
250	see_also:[atom / 1, compound / 1, is_list/1, is_array/1,var / 1]]).
251
252:- comment(callable / 1, [
253	summary:"Succeeds if Term is callable, i.e. of type atom or compound.",
254	amode:(callable(?) is semidet),
255	desc:html("
256Used to test whether Term is a 'callable' term, i.e. whether it
257is an atom or compound term, and could therefore be used as a goal.
258Note that this is a purely syntactic check which does not say
259anything about the existence of a corresponding predicate.
260<P>
261This predicate is equivalent to
262<PRE>
263    callable(X) :- atom(X).
264    callable(X) :- compound(X).
265</PRE>
266Note that it also succeeds for lists.
267"),
268	args:["Term" : "Prolog term."],
269	fail_if:"Fails if Term is not an atom or a compound term",
270	eg:"
271Success:
272   callable(true).
273   callable(hello(\"world\",42)).
274   callable(f(1,2)).
275   callable([1,2,3]).
276   callable(.(1,2)).
277   callable(foo).
278   callable([]).
279
280Fail:
281   callable(\"f(1,2)\").
282   callable(_).
283   callable(42).
284   make_suspension(true,0,S), callable(S).
285",
286	see_also:[atom / 1, compound/1, is_list/1, is_array/1,var / 1]]).
287
288:- comment(compound / 1, [
289	summary:"Succeeds if Term is of type compound, i.e.  a structure or a list.
290
291",
292	amode:(compound(?) is semidet),
293	desc:html("Used to test whether Term is a compound term.
294	Compound terms have an arity greater than zero.
295	This test is the negation of atomic/1.
296<P>
297"),
298	args:["Term" : "Prolog term."],
299	fail_if:"Fails if Term is not a compound term",
300	eg:"
301   Success:
302   compound(f(1,2)).
303   compound(f(_,_)).
304   compound([1,2,3]).
305   compound(.(1,2)).
306   compound(f/1).
307   compound(1+2).
308   compound(1+2).
309   Fail:
310   compound(\"f(1,2)\").
311   compound(Term).
312   compound(atom).
313
314",
315	see_also:[atom / 1, atomic / 1, callable/1, is_list/1, is_array/1, var / 1]]).
316
317:- comment(integer / 1, [
318	summary:"Succeeds if Integer is an integer number.
319
320",
321	amode:(integer(?) is semidet),
322	desc:html("   Used to test whether Integer is of type integer.
323
324<P>
325"),
326	args:["Integer" : "Prolog term."],
327	fail_if:"Fails if Integer is not an integer number",
328	eg:"
329   Success:
330   integer(10).
331   integer(-40).
332   Fail:
333   integer(3.14).
334   integer('4').
335   integer(Integer).
336",
337	see_also:[integer_atom / 2, number / 1, float/1, real / 1, rational/1, breal/1]]).
338
339:- comment(nonground / 1, [
340	summary:"Succeeds if VarTerm is not ground.
341
342",
343	amode:(nonground(?) is semidet),
344	desc:html("
345    Used to test whether VarTerm is not ground i.e. whether it is itself a
346    variable, or it has at least one subterm that is a uninstantiated variable.
347    This is the negation of ground/1.
348<P>
349"),
350	args:["VarTerm" : "Prolog term."],
351	fail_if:"Fails if VarTerm is ground",
352	eg:"
353   Success:
354   nonground(VarTerm).
355   nonground(f(a,B,c)).
356   nonground([x,y|Z]).
357   Fail:
358   nonground(atom).
359   nonground(likes(man,woman)).
360",
361	see_also:[nonvar / 1, ground/1, nonground/2, nonground/3, type_of / 2, var / 1]]).
362
363:- comment(ground / 1, [
364	summary:"Succeeds if Term is ground.
365",
366	amode:(ground(?) is semidet),
367	desc:html("
368	Used to test whether Term is ground, i.e. contains no variables.
369	This is the negation of nonground/1.
370"),
371	args:["Term" : "Prolog term."],
372	fail_if:"Fails if Term is not ground",
373	eg:"
374   Success:
375   ground(atom).
376   ground(likes(mouse,cheese)).
377   Fail:
378   ground(VarTerm).
379   ground(f(a,B,c)).
380   ground([x,y|Z]).
381",
382	see_also:[nonvar / 1, nonground/1, nonground/2, nonground/3, type_of / 2, var / 1]]).
383
384:- comment(nonvar / 1, [
385	summary:"Succeeds if Term is instantiated.
386
387",
388	amode:(nonvar(?) is semidet),
389	desc:html("
390    Used to test whether Term is instantiated.  This is the negation of var/1,
391    i.e. it succeeds if Term is not an uninstantiated variable.
392    Note that it also succeeds if Term is a partially instantiated term,
393    i.e. a compound term with at least one uninstantiated subterm.
394<P>
395"),
396	args:["Term" : "Any Prolog term."],
397	fail_if:"Fails if Term is not instantiated",
398	eg:"
399   Success:
400   nonvar(atom).
401   nonvar(33).
402   nonvar(foo(3)).
403   nonvar(foo(_)).
404   nonvar([_|_]).
405   Fail:
406   nonvar(Var).
407
408
409
410",
411	see_also:[nonground / 1, type_of / 2, var / 1]]).
412
413:- comment(real / 1, [
414	summary:"Succeeds if Real is a real (float or breal) number.",
415	amode:(real(?) is semidet),
416	desc:html("   Used to test whether Real is a real number, i.e.
417	either a floating point number (float) or a bounded real number
418	(breal). It could be defined as:
419<PRE>
420   real(X) :- float(X).
421   real(X) :- breal(X).
422</PRE>
423"),
424	args:["Real" : "Prolog term."],
425	fail_if:"Fails if Real is not a real number",
426	eg:"
427   Success:
428   real(1.0).
429   real(0.99__1.01).
430   real(3e27).
431   real(1e300__1.0Inf).
432   Fail:
433   real(1).
434   real('1.0').
435   real(X).
436
437
438
439",
440	see_also:[atomic / 1, float/1, integer / 1, number / 1, rational/1, breal/1]]).
441
442:- comment(float / 1, [
443	summary:"Succeeds if Real is a floating point number.",
444	amode:(float(?) is semidet),
445	desc:html("   Used to test whether Real is a floating point number.
446
447<P>
448"),
449	args:["Real" : "Prolog term."],
450	fail_if:"Fails if Real is not a floating point number",
451	eg:"
452   Success:
453   float(1.0).
454   float(3e27).
455   Fail:
456   float(1).
457   float('1.0').
458   float(X).
459",
460	see_also:[atomic / 1, integer / 1, number / 1, rational/1, breal/1, real/1]]).
461
462:- comment(string / 1, [
463	summary:"Succeeds if String is a string.
464
465",
466	amode:(string(?) is semidet),
467	desc:html("   Used to test whether String is a string.
468
469<P>
470"),
471	args:["String" : "Prolog term."],
472	fail_if:"Fails if String is not a string",
473	eg:"
474   Success:
475   string(\"astring\").
476   Fail:
477   string('astring').
478   string(X).
479
480
481
482",
483	see_also:[atom / 1, atomic / 1, var / 1]]).
484
485:- comment(free / 1, [
486	summary:"Succeeds if Var is a free variable, not an attributed one.
487
488",
489	amode:(free(?) is semidet),
490	desc:html("   Used to test whether Var is a free variable.  free/1 is like var/1 but
491   does not succeed for attributed variables.
492<P>
493   CAUTION: is it usually a mistake to distinguish between free and attributed
494   variables, because variables can have several unrelated attributes (for
495   example, some attributes are only for debugging purposes and should not
496   affect the program behaviour at all). Correct code should check for the
497   presence or absence of a particular attribute, and only use the free/1
498   test as a shortcut for detecting the absence of any attribute, e.g.
499<PRE>
500    add_my_attribute_if_needed(X) :-
501        free(X),
502        % X has no attributes at all: add my one
503        add_attribute(X, my_attribute).
504    add_my_attribute_if_needed(X{my_attr:Attr}) ?-
505        ( var(Attr) ->
506            % X has attributes, but not my one: add it
507            add_attribute(X, my_attribute)
508        ;
509            % X already has my attribute: do nothing
510            true
511        ).
512</PRE>
513"),
514	args:["Var" : "Prolog term."],
515	fail_if:"Fails if Var is instantiated or an attributed variable",
516	eg:"
517Success:
518      free(X).
519      free(_abc).
520      free(_).
521
522Fail:
523      free(X{a}).
524      suspend:(X>0), free(X).
525      var(atom).
526      var('Abc').
527
528
529
530",
531	see_also:[nonground / 1, nonvar / 1, meta / 1, type_of / 2, var / 1]]).
532
533:- comment(is_list / 1, [
534	summary:"Succeeds if Term is a proper list.",
535	amode:(is_list(?) is semidet),
536	desc:html("\
537   Used to test whether Term is a proper list, i.e. either the empty list,
538   of a list element whose tail is itself a proper list.  The predicate
539   could be recursively defined as:
540<PRE>
541	is_list(X) :- var(X), !, fail.
542	is_list([_|Xs]) :- is_list(Xs).
543	is_list([]).
544</PRE>
545   The complexity of this operation is linear in the length of the list.
546"),
547	args:["Term" : "Prolog term."],
548	fail_if:"Fails if Term is not a proper list",
549	eg:"
550    ?- is_list([]).
551    Yes (0.00s cpu)
552
553    ?- is_list([1,2,3]).
554    Yes (0.00s cpu)
555
556    ?- is_list([1,2|3]).   % illegal tail
557    No (0.00s cpu)
558
559    ?- is_list([1,2|_]).   % open-ended list
560    No (0.00s cpu)
561
562    ?- is_list(list).
563    No (0.00s cpu)
564
565    ?- is_list(42).
566    No (0.00s cpu)
567
568    ?- is_list(X).
569    No (0.00s cpu)
570",
571	see_also:[atom/1,callable/1, compound/1,is_array/1,ground/1]]).
572
573:- comment(is_array / 1, [
574	summary:"Succeeds if Term is an array.",
575	amode:(is_array(?) is semidet),
576	desc:html("\
577   Used to test whether Term is an array, i.e. a term with functor []/N.
578   Could be defined as:
579<PRE>
580	is_array(X) :- nonvar(X), functor(X, [], _).
581</PRE>
582   Note that this includes the empty array [].
583"),
584	args:["Term" : "Prolog term."],
585	fail_if:"Fails if Term is not an array",
586	eg:"
587    ?- is_array([]).
588    Yes (0.00s cpu)
589
590    ?- is_array([](1,2,3)).
591    Yes (0.00s cpu)
592
593    ?- is_array([1,2,3]).
594    No (0.00s cpu)
595
596    ?- is_array(f(1,2)).
597    No (0.00s cpu)
598
599    ?- is_array(foo).
600    No (0.00s cpu)
601
602    ?- is_array(_).
603    No (0.00s cpu)
604",
605	see_also:[atom/1,callable/1,compound/1,is_list/1,ground/1]]).
606
607:- comment(is_handle / 1, [
608	summary:"Succeeds if Term is an external data handle.
609
610",
611	amode:(is_handle(?) is semidet),
612	desc:html("   Used to test whether Term is a handle for external data.
613   Such handles can be created by external predicates using the
614   ECLiPSe C or C++ API.
615
616<P>
617"),
618	args:["Term" : "Prolog term."],
619	fail_if:"Fails if Term is not an external data handle",
620	eg:"
621
622    ?- bag_create(B), is_handle(B).
623    B = 'BAG'(16'edc90b18)
624    Yes (0.00s cpu)
625
626    ?- is_handle(_).
627    No (0.00s cpu)
628
629    ?- is_handle(42).
630    No (0.00s cpu)
631
632",
633	see_also:[is_event/1,type_of/2,xget/3,xset/3]]).
634
635:- comment(is_event / 1, [
636	summary:"Succeeds if Term is an event name or handle",
637	amode:(is_event(?) is semidet),
638	desc:html("\
639   Used to test whether Term is either an event name (an atom) or an event
640   handle (a special kind of handle as created by event_create/3).
641"),
642	args:["Term" : "Prolog term."],
643	fail_if:"Fails if Term is neither an atom nor an event handle",
644	eg:"
645
646    ?- is_event(my_event).
647    Yes (0.00s cpu)
648
649    ?- event_create(true, [], E), is_event(E).
650    E = 'EVENT'(16'edc90b18)
651    Yes (0.00s cpu)
652
653    ?- bag_create(B), is_event(B).
654    No (0.00s cpu)
655
656    ?- is_event(_).
657    No (0.00s cpu)
658
659    ?- is_event(42).
660    No (0.00s cpu)
661",
662	see_also:[event/1,atom/1,is_handle/1,event_create/3,type_of/2]]).
663
664:- comment(is_suspension / 1, [
665	summary:"Succeeds if Term is a sleeping suspension.
666
667",
668	amode:(is_suspension(?) is semidet),
669	desc:html("   Used to test whether Term is a sleeping suspension, i.e.  a suspension
670   that has not yet been executed.  type_of/2 can be used to test for a
671   sleeping or executed suspension.
672
673<P>
674"),
675	args:["Term" : "Prolog term."],
676	fail_if:"Fails if Term is not a sleeping suspension",
677	eg:"
678Success:
679      make_suspension(true, 2, S), is_suspension(S).
680
681Fail:
682      is_suspension(X).
683
684      is_suspension(a).
685
686      make_suspension(true, 2, S), schedule_suspensions(1, s(S)),
687      wake, is_suspension(S).
688
689
690
691",
692	see_also:[type_of / 2, make_suspension / 3, schedule_suspensions / 2,
693		suspensions/1, suspensions/2]]).
694
695:- comment(meta / 1, [
696	summary:"Succeeds if Var is an attributed variable.
697
698",
699	amode:(meta(?) is semidet),
700	desc:html("   Used to test whether Var is an attributed variable.
701<P>
702   CAUTION: this test only detects the presence of any attribute, which is
703   usually not what is required. It is more common to check for the presence
704   of a particular attribute by using a matching clause of the form:
705<PRE>
706    has_my_attribute(_{my_attr:Attr}) ?-
707    	nonvar(Attr).
708</PRE>
709"),
710	args:["Var" : "Prolog term."],
711	fail_if:"Fails if Var is not an attributed variable",
712	eg:"
713Success:
714      meta(X{a}).
715      suspend:(X>0), meta(X).
716
717Fail:
718      meta(atom).
719      meta(X).
720
721
722
723",
724	see_also:[free / 1, type_of / 2, var / 1]]).
725
726:- comment(number / 1, [
727	summary:"Succeeds if Number is a number.
728
729",
730	amode:(number(?) is semidet),
731	desc:html("   Used to test whether Number is a number.  number/1 could be defined as
732
733<P>
734<PRE>
735   number(X) :- integer(X).
736   number(X) :- rational(X).
737   number(X) :- float(X).
738   number(X) :- breal(X).
739</PRE>
740"),
741	args:["Number" : "Prolog term."],
742	fail_if:"Fails if Number is not a number",
743	eg:"
744   Success:
745   number(10).
746   number(-21.0).
747   number(1_3).
748   number(3e27).
749   Fail:
750   number(pi).
751   number(e).
752   number('-21.0').
753   number(X).
754   number(fred).
755
756
757
758",
759	see_also:[atomic / 1, integer / 1, breal/1, rational / 1, float/1, real / 1]]).
760
761:- comment(rational / 1, [
762	summary:"Succeeds if Rational is a rational number.
763
764",
765	amode:(rational(?) is semidet),
766	desc:html("   Used to test whether Rational is a rational number.
767
768<P>
769"),
770	args:["Rational" : "Prolog term."],
771	fail_if:"Fails if Rational is not a rational number",
772	eg:"
773   Success:
774   rational(1_3).
775   set_flag(prefer_rationals, on), X is 1/3, rational(X).
776   Fail:
777   rational(1).
778   rational(1.0).
779   rational('1.0').
780   rational(a).
781   rational(X).
782
783
784
785",
786	see_also:[atomic / 1, integer / 1, number / 1, float/1, real / 1, breal/1]]).
787
788:- comment(breal / 1, [
789    summary:"Succeeds if Breal is a bounded real number.",
790    amode:(breal(?) is semidet),
791    desc:html("\
792	Used to test whether a term is a bounded real number.
793	A bounded real (breal) is conceptually a real number, and it
794	is represented by a lower and upper bound in floating point
795	format.
796"),
797    args:["Breal" : "A term."],
798    fail_if:"Fails if Breal is not a bounded real number",
799    eg:"
800Success:
801    ?- breal(0.99__1.01).
802    Yes (0.00s cpu)
803
804    ?- X is breal(pi), breal(X).
805    X = 3.1415926535897927__3.1415926535897936
806    Yes (0.00s cpu)
807
808Fail:
809    ?- breal(1.0).
810    No (0.00s cpu)
811
812    ?- breal(1).
813    No (0.00s cpu)
814
815    ?- breal(\"hello\").
816    No (0.00s cpu)
817",
818	see_also:[atomic / 1, integer / 1, number / 1, float/1, real / 1, rational/1, breal/2]]).
819
820:- comment(type_of / 2, [
821	summary:"Succeeds if Type is the data type of the term Term.
822
823",
824	amode:(type_of(?,-) is det),
825	desc:html("   The type of the term Term is unified with Type.
826
827<P>
828   The types are atoms from the set: string, atom, var, integer, rational,
829   float, breal, compound, handle, goal.
830
831<P>
832"),
833	args:["Term" : "Prolog term.", "Type" : "Atom or variable."],
834	exceptions:[5 : "Type is instantiated, but not to an atom."],
835	eg:"
836Success:
837      type_of(X,T).         (gives T=var).
838      type_of([1,2],T).     (gives T=compound).
839      type_of([],atom).
840      type_of(#,atom).
841      type_of($,atom).
842      type_of(*,atom).
843      type_of(/,atom).
844      type_of(\\,atom).
845      type_of(\"a\",string).
846      type_of(1,integer).
847      type_of(123456789012345,integer).
848      type_of(1_3,rational).
849      type_of(1.0,float).
850      type_of(0.99__1.01,breal).
851      type_of(a(b),compound).
852      bag_create(B), type_of(B, handle).
853      record(k, a), recorded(k, _, R), type_of(R, handle).
854      make_suspension(true,3,S), type_of(S, goal).
855Fail:
856      type_of(2.0,integer).
857      type_of(2.0,float).
858Error:
859      type_of(2,\"atom\").  (Error 5).
860
861
862
863",
864	see_also:[atom / 1, callable/1, compound / 1, free / 1, integer / 1, meta / 1,
865	number / 1, nonground / 1, breal/1, rational / 1, float/1, float/1,
866	real / 1, string / 1, var / 1]]).
867
868:- comment(var / 1, [
869	summary:"Succeeds if Var is a variable or an attributed variable.
870
871",
872	amode:(var(?) is semidet),
873	desc:html("\
874   Used to test whether Var is a variable or an attributed variable.  The
875   difference between var/1 and free/1 is that var/1 succeeds on attributed
876   variables as well.
877
878<P>
879   var/1 could be defined as
880
881<P>
882<PRE>
883    var(X) :- free(X).
884    var(X) :- meta(X).
885</PRE>
886"),
887	args:["Var" : "Prolog term."],
888	fail_if:"Fails if Var is instantiated",
889	eg:"
890Success:
891      var(X).
892      var(_abc).
893      var(_).
894      var(X{a}).
895      suspend:(X>0), var(X).
896
897Fail:
898      var(atom).
899      var('Abc').
900
901
902
903",
904	see_also:[free / 1, meta / 1, nonground / 1, nonvar / 1, type_of / 2]]).
905
906:- comment(get_var_info / 3, [
907	summary:"Succeeds if Var is an uninstantiated variable, InfoName is a valid
908information name and the information value Value unifies with the value of
909the information.
910
911",
912	amode:(get_var_info(?,+,-) is semidet),	% range error detected
913	amode:(get_var_info(?,-,-) is semidet),
914	desc:html("   This predicate is used to test the type of a free variable or to get its
915   source name (when available).
916
917<P>
918   The possible values for InfoName are type or name.
919
920<P>
921   If InfoName unifies with name, the predicate will succeed if the source
922   name of the free variable Var is available and unifies with Value.
923
924<P>
925   If InfoName unifies with type, the predicate will succeed if Value
926   unifies with the type of the variable Var.
927
928<P>
929   The possible types are:
930
931<P>
932<PRE>
933    meta      an attributed variable (metaterm)
934    free      a free variable
935</PRE>
936"),
937	args:["Var" : "Prolog Term, usually a variable.", "InfoName" : "Atom or variable.", "Value" : "Atom or variable."],
938	fail_if:"Fails if Var is not a variable",
939	exceptions:[5 : "InfoName or Value is neither an atom nor a variable.", 6 : "InfoName is not an information name."],
940	eg:"
941Success:
942      ?- suspend:(Var1 > Var2), get_var_info(Var1, Info, Value).
943      Var2 = Var2
944      Var1 = Var1
945      Info = name
946      Value = 'Var1'
947      Delayed goals:
948       Var1 > Var2     More? (;)
949
950      Var2 = Var2
951      Var1 = Var1
952      Info = type
953      Value = meta
954
955      Delayed goals:
956       Var1 > Var2
957      yes.
958
959      ?- get_var_info(Var1, type, Type).
960      Var1 = Var1
961      Type = free
962      yes.
963
964      ?- set_flag(variable_names,off).
965      yes.
966
967      ?- get_var_info(Var1, name, Name).
968      no (more) solution.
969
970Fail:
971      get_var_info(atom, name, Name).
972      set_flag(variable_names, off),
973          get_var_info(X, name, Name).
974
975Error:
976      get_var_info(X, not_an_info, Y).    (Error 6)
977      get_var_info(X, type, 123).         (Error 5)
978
979
980
981
982",
983	see_also:[set_flag / 2, type_of / 2, var / 1]]).
984
985
986:- comment(acyclic_term / 1, [
987    summary:"Succeeds if Term is acyclic (finite)",
988    index:["occurs check","rational tree","cyclic term"],
989    amode:(acyclic_term(?) is semidet),
990    desc:html("\
991	Used to test whether Term is acyclic (a finite tree).
992	Fails if Term is cyclic (an infinite, rational tree).
993"),
994    args:["Term" :"Arbitrary term"],
995    fail_if:"Fails if Term is cyclic",
996    eg:"
997    ?- X = f(f(a)), acyclic_term(X).
998    X = f(f(a))
999    Yes (0.00s cpu)
1000
1001    ?- X = f(X), acyclic_term(X).
1002    No (0.00s cpu)
1003
1004
1005    % could be used to simulate occurs check
1006    unify_with_occurs_check(X, X) :- acyclic_term(X).
1007
1008",
1009    see_also:[]]).
1010
1011