File: prog_data.m

package info (click to toggle)
mercury 0.9-1
  • links: PTS
  • area: main
  • in suites: potato
  • size: 18,488 kB
  • ctags: 9,800
  • sloc: objc: 146,680; ansic: 51,418; sh: 6,436; lisp: 1,567; cpp: 1,040; perl: 854; makefile: 450; asm: 232; awk: 203; exp: 32; fortran: 3; csh: 1
file content (908 lines) | stat: -rw-r--r-- 27,545 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
%-----------------------------------------------------------------------------%
% Copyright (C) 1996-1999 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% File: prog_data.m.
% Main author: fjh.
%
% This module defines a data structure for representing Mercury programs.
%
% This data structure specifies basically the same information as is
% contained in the source code, but in a parse tree rather than a flat file.
% Simplifications are done only by make_hlds.m, which transforms
% the parse tree which we built here into the HLDS.

:- module prog_data.

:- interface.

% This module should NOT import hlds*.m, either directly or indirectly.
% Any types which are needed in both the parse tree and in the HLDS
% should be defined here, rather than in hlds*.m.

:- import_module (inst).
:- import_module bool, list, assoc_list, map, varset, term, std_util.

%-----------------------------------------------------------------------------%

	% This is how programs (and parse errors) are represented.

:- type message_list	==	list(pair(string, term)).
				% the error/warning message, and the
				% term to which it relates

:- type compilation_unit		
	--->	module(
			module_name,
			item_list
		).

:- type item_list	==	list(item_and_context).

:- type item_and_context ==	pair(item, prog_context).

:- type item		
	--->	pred_clause(prog_varset, sym_name, list(prog_term), goal)
		%      VarNames, PredName, HeadArgs, ClauseBody

	;	func_clause(prog_varset, sym_name, list(prog_term),
			prog_term, goal)
		%      VarNames, PredName, HeadArgs, Result, ClauseBody

	; 	type_defn(tvarset, type_defn, condition)
	; 	inst_defn(inst_varset, inst_defn, condition)
	; 	mode_defn(inst_varset, mode_defn, condition)
	; 	module_defn(prog_varset, module_defn)

	; 	pred(tvarset, inst_varset, existq_tvars, sym_name,
			list(type_and_mode), maybe(determinism), condition,
			purity, class_constraints)
		%       TypeVarNames, InstVarNames,
		%	ExistentiallyQuantifiedTypeVars, PredName, ArgTypes,
		%	Deterministicness, Cond, Purity, TypeClassContext

	; 	func(tvarset, inst_varset, existq_tvars, sym_name,
			list(type_and_mode), type_and_mode, maybe(determinism),
			condition, purity, class_constraints)
		%       TypeVarNames, InstVarNames,
		%	ExistentiallyQuantifiedTypeVars, PredName, ArgTypes,
		%	ReturnType, Deterministicness, Cond, Purity,
		%	TypeClassContext

	; 	pred_mode(inst_varset, sym_name, list(mode), maybe(determinism),
			condition)
		%       VarNames, PredName, ArgModes, Deterministicness,
		%       Cond

	; 	func_mode(inst_varset, sym_name, list(mode), mode,
			maybe(determinism), condition)
		%       VarNames, PredName, ArgModes, ReturnValueMode,
		%       Deterministicness, Cond

	;	pragma(pragma_type)

	;	assertion(goal, prog_varset)

	;	typeclass(list(class_constraint), class_name, list(tvar),
			class_interface, tvarset)
		%	Constraints, ClassName, ClassParams, 
		%	ClassMethods, VarNames

	;	instance(list(class_constraint), class_name, list(type),
			instance_body, tvarset)
		%	DerivingClass, ClassName, Types, 
		%	MethodInstances, VarNames

	;	nothing.
		% used for items that should be ignored (currently only
		% NU-Prolog `when' declarations, which are silently ignored
		% for backwards compatibility).

:- type type_and_mode	
	--->	type_only(type)
	;	type_and_mode(type, mode).

:- type pred_or_func
	--->	predicate
	;	function.

	% Purity indicates whether a goal can have side effects or can
	% depend on global state.  See purity.m and the "Purity" section
	% of the Mercury language reference manual.
:- type purity		--->	pure
			;	(semipure)
			;	(impure).

	% The `determinism' type specifies how many solutions a given
	% procedure may have.  Procedures for manipulating this type
	% are defined in det_analysis.m and hlds_data.m.
:- type determinism	
	--->	det
	;	semidet
	;	nondet
	;	multidet
	;	cc_nondet
	;	cc_multidet
	;	erroneous
	;	failure.

%-----------------------------------------------------------------------------%
%
% Pragmas
%

:- type pragma_type 
	--->	c_header_code(string)

	;	c_code(string)

	;	c_code(pragma_c_code_attributes, sym_name, pred_or_func,
			list(pragma_var), prog_varset, pragma_c_code_impl)
			% Set of C code attributes, eg.:
			%	whether or not the C code may call Mercury,
			%	whether or not the C code is thread-safe
			% PredName, Predicate or Function, Vars/Mode, 
			% VarNames, C Code Implementation Info
	
	;	type_spec(sym_name, sym_name, arity, maybe(pred_or_func),
			maybe(list(mode)), type_subst, tvarset)
			% PredName, SpecializedPredName, Arity,
			% PredOrFunc, Modes if a specific procedure was
			% specified, type substitution (using the variable
			% names from the pred declaration), TVarSet

	;	inline(sym_name, arity)
			% Predname, Arity

	;	no_inline(sym_name, arity)
			% Predname, Arity

	;	obsolete(sym_name, arity)
			% Predname, Arity

	;	export(sym_name, pred_or_func, list(mode),
			string)
			% Predname, Predicate/function, Modes,
			% C function name.

	;	import(sym_name, pred_or_func, list(mode),
			pragma_c_code_attributes, string)
			% Predname, Predicate/function, Modes,
			% Set of C code attributes, eg.:
			%	whether or not the C code may call Mercury,
			%	whether or not the C code is thread-safe
			% C function name.

	;	source_file(string)
			% Source file name.

	;	unused_args(pred_or_func, sym_name, arity,
			mode_num, list(int))
			% PredName, Arity, Mode number, Optimized pred name,
			% 	Removed arguments.
			% Used for inter-module unused argument
			% removal, should only appear in .opt files.

	;	fact_table(sym_name, arity, string)
			% Predname, Arity, Fact file name.

	;	aditi(sym_name, arity)
			% Predname, Arity

	;	base_relation(sym_name, arity)
			% Predname, Arity
			%
			% Eventually, these should only occur in 
			% automatically generated database interface 
			% files, but for now there's no such thing, 
			% so they can occur in user programs.

	;	aditi_index(sym_name, arity, index_spec)
			% PredName, Arity, IndexType, Attributes
			%
			% Specify an index on a base relation.

	;	naive(sym_name, arity)
			% Predname, Arity
			% Use naive evaluation.

	;	psn(sym_name, arity)
			% Predname, Arity
			% Use predicate semi-naive evaluation.

	;	aditi_memo(sym_name, arity)
			% Predname, Arity

	;	aditi_no_memo(sym_name, arity)
			% Predname, Arity

	;	supp_magic(sym_name, arity)
			% Predname, Arity

	;	context(sym_name, arity)
			% Predname, Arity

	;	owner(sym_name, arity, string)
			% PredName, Arity, String.

	;	tabled(eval_method, sym_name, int, maybe(pred_or_func), 
				maybe(list(mode)))
			% Tabling type, Predname, Arity, PredOrFunc?, Mode?
	
	;	promise_pure(sym_name, arity)
			% Predname, Arity

	;	termination_info(pred_or_func, sym_name, list(mode),
				maybe(pragma_arg_size_info),
				maybe(pragma_termination_info))
			% the list(mode) is the declared argmodes of the
			% procedure, unless there are no declared argmodes,
			% in which case the inferred argmodes are used.
			% This pragma is used to define information about a
			% predicates termination properties.  It is most
			% useful where the compiler has insufficient
			% information to be able to analyse the predicate.
			% This includes c_code, and imported predicates.
			% termination_info pragmas are used in opt and
			% trans_opt files.


	;	terminates(sym_name, arity)
			% Predname, Arity

	;	does_not_terminate(sym_name, arity)
			% Predname, Arity

	;	check_termination(sym_name, arity).
			% Predname, Arity

%
% Stuff for tabling pragmas
%

	% The evaluation method that should be used for a pred.
	% Ignored for Aditi procedures.
:- type eval_method
	--->	eval_normal		% normal mercury 
					% evaluation
	;	eval_loop_check		% loop check only
	;	eval_memo		% memoing + loop check 
	;	eval_minimal.		% minimal model 
					% evaluation 
%
% Stuff for the `aditi_index' pragma
%

	% For Aditi base relations, an index_spec specifies how the base
	% relation is indexed.
:- type index_spec
	---> index_spec(
		index_type,
		list(int)	% which attributes are being indexed on
				% (attribute numbers start at 1)
	).

	% Hash indexes?
:- type index_type
	--->	unique_B_tree
	;	non_unique_B_tree.

%
% Stuff for the `termination_info' pragma.
% See term_util.m.
%

:- type pragma_arg_size_info
	--->	finite(int, list(bool))
				% The termination constant is a finite integer.
				% The list of bool has a 1:1 correspondence
				% with the input arguments of the procedure.
				% It stores whether the argument contributes
				% to the size of the output arguments.
	;	infinite.
				% There is no finite integer for which the
				% above equation is true.

:- type pragma_termination_info
	---> 	cannot_loop	% This procedure definitely terminates for all
				% possible inputs.
	;	can_loop.	% This procedure might not terminate.


%
% Stuff for the `unused_args' pragma.
%

	% This `mode_num' type is only used for mode numbers written out in
	% automatically-generateed `pragma unused_args' pragmas in `.opt'
	% files. 
	% The mode_num gets converted to an HLDS proc_id by make_hlds.m.
	% We don't want to use the `proc_id' type here since the parse tree
	% (prog_data.m) should not depend on the HLDS.
:- type mode_num == int.

%
% Stuff for the `type_spec' pragma.
%

	% The type substitution for a `pragma type_spec' declaration.
	% Elsewhere in the compiler we generally use the `tsubst' type
	% which is a map rather than an assoc_list.
:- type type_subst == assoc_list(tvar, type).

%
% Stuff for `c_code' pragma.
%

	% This type holds information about the implementation details
	% of procedures defined via `pragma c_code'.
	%
	% All the strings in this type may be accompanied by the context
	% of their appearance in the source code. These contexts are
	% used to tell the C compiler where the included C code comes from,
	% to allow it to generate error messages that refer to the original
	% appearance of the code in the Mercury program.
	% The context is missing if the C code was constructed by the compiler.
:- type pragma_c_code_impl
	--->	ordinary(		% This is a C definition of a model_det
					% or model_semi procedure. (We also
					% allow model_non, until everyone has
					% had time to adapt to the new way
					% of handling model_non pragmas.)
			string,		% The C code of the procedure.
			maybe(prog_context)
		)
	;	nondet(			% This is a C definition of a model_non
					% procedure.
			string,
			maybe(prog_context),
					% The info saved for the time when
					% backtracking reenters this procedure
					% is stored in a C struct. This arg
					% contains the field declarations.

			string,
			maybe(prog_context),
					% Gives the code to be executed when
					% the procedure is called for the first 
					% time. This code may access the input
					% variables.

			string,	
			maybe(prog_context),
					% Gives the code to be executed when
					% control backtracks into the procedure.
					% This code may not access the input
					% variables.

			pragma_shared_code_treatment,
					% How should the shared code be
					% treated during code generation.
			string,	
			maybe(prog_context)
					% Shared code that is executed after
					% both the previous code fragments.
					% May not access the input variables.
		).

	% The use of this type is explained in the comment at the top of
	% pragma_c_gen.m.
:- type pragma_shared_code_treatment
	--->	duplicate
	;	share
	;	automatic.

%-----------------------------------------------------------------------------%
%
% Stuff for type classes
%

	% A class constraint represents a constraint that a given
	% list of types is a member of the specified type class.
	% It is an invariant of this data structure that
	% the types in a class constraint do not contain any
	% information in their prog_context fields.
	% This invariant is needed to ensure that we can do
	% unifications, map__lookups, etc., and get the
	% expected semantics.
	% Any code that creates new class constraints must
	% ensure that this invariant is preserved,
	% probably by using strip_term_contexts/2 in type_util.m.
:- type class_constraint
	---> constraint(class_name, list(type)).

:- type class_constraints
	---> constraints(
		list(class_constraint),	% ordinary (universally quantified)
		list(class_constraint)	% existentially quantified constraints
	).

:- type class_name == sym_name.

:- type class_interface  == list(class_method).	

:- type class_method
	--->	pred(tvarset, inst_varset, existq_tvars, sym_name,
			list(type_and_mode), maybe(determinism), condition,
			class_constraints, prog_context)
		%       TypeVarNames, InstVarNames,
		%	ExistentiallyQuantifiedTypeVars,
		%	PredName, ArgTypes, Determinism, Cond
		%	ClassContext, Context

	; 	func(tvarset, inst_varset, existq_tvars, sym_name,
			list(type_and_mode), type_and_mode,
			maybe(determinism), condition,
			class_constraints, prog_context)
		%       TypeVarNames, InstVarNames,
		%	ExistentiallyQuantfiedTypeVars,
		%	PredName, ArgTypes, ReturnType,
		%	Determinism, Cond
		%	ClassContext, Context

	; 	pred_mode(inst_varset, sym_name, list(mode),
			maybe(determinism), condition,
			prog_context)
		%       InstVarNames, PredName, ArgModes,
		%	Determinism, Cond
		%	Context

	; 	func_mode(inst_varset, sym_name, list(mode), mode,
			maybe(determinism), condition,
			prog_context)
		%       InstVarNames, PredName, ArgModes,
		%	ReturnValueMode,
		%	Determinism, Cond
		%	Context
	.

:- type instance_method	
	--->	func_instance(sym_name, sym_name, arity, prog_context)
				% Method, Instance, Arity, 
				% Line number of declaration
	;	pred_instance(sym_name, sym_name, arity, prog_context)
				% Method, Instance, Arity, 
				% Line number of declaration
	.

:- type instance_body
	--->	abstract
	;	concrete(instance_methods).

:- type instance_methods ==	list(instance_method).

%-----------------------------------------------------------------------------%
%
% Some more stuff for `pragma c_code'.
%

		% an abstract type for representing a set of
		% `pragma_c_code_attribute's.
:- type pragma_c_code_attributes.

:- pred default_attributes(pragma_c_code_attributes).
:- mode default_attributes(out) is det.

:- pred may_call_mercury(pragma_c_code_attributes, may_call_mercury).
:- mode may_call_mercury(in, out) is det.

:- pred set_may_call_mercury(pragma_c_code_attributes, may_call_mercury,
		pragma_c_code_attributes).
:- mode set_may_call_mercury(in, in, out) is det.

:- pred thread_safe(pragma_c_code_attributes, thread_safe).
:- mode thread_safe(in, out) is det.

:- pred set_thread_safe(pragma_c_code_attributes, thread_safe,
		pragma_c_code_attributes).
:- mode set_thread_safe(in, in, out) is det.

	% For pragma c_code, there are two different calling conventions,
	% one for C code that may recursively call Mercury code, and another
	% more efficient one for the case when we know that the C code will
	% not recursively invoke Mercury code.
:- type may_call_mercury
	--->	may_call_mercury
	;	will_not_call_mercury.

	% If thread_safe execution is enabled, then we need to put a mutex
	% around the C code for each `pragma c_code' declaration, unless
	% it's declared to be thread_safe.
:- type thread_safe
	--->	not_thread_safe
	;	thread_safe.

:- type pragma_var    
	--->	pragma_var(prog_var, string, mode).
	  	% variable, name, mode
		% we explicitly store the name because we need the real
		% name in code_gen

%-----------------------------------------------------------------------------%
%
% Goals
%

	% Here's how clauses and goals are represented.
	% a => b --> implies(a, b)
	% a <= b --> implies(b, a) [just flips the goals around!]
	% a <=> b --> equivalent(a, b)

% clause/4 defined above

:- type goal		==	pair(goal_expr, prog_context).

:- type goal_expr	
	% conjunctions
	--->	(goal , goal)	% (non-empty) conjunction
	;	true		% empty conjunction
	;	{goal & goal}	% parallel conjunction
				% (The curly braces just quote the '&'/2.)

	% disjunctions
	;	{goal ; goal}	% (non-empty) disjunction
				% (The curly braces just quote the ';'/2.)
	;	fail		% empty disjunction

	% quantifiers
	;	{ some(prog_vars, goal) }
				% existential quantification
				% (The curly braces just quote the 'some'/2.)
	;	all(prog_vars, goal)	% universal quantification

	% implications
	;	implies(goal, goal)	% A => B
	;	equivalent(goal, goal)	% A <=> B

	% negation and if-then-else
	;	not(goal)
	;	if_then(prog_vars, goal, goal)
	;	if_then_else(prog_vars, goal, goal, goal)

	% atomic goals
	;	call(sym_name, list(prog_term), purity)
	;	unify(prog_term, prog_term).

:- type goals		==	list(goal).

	% These type equivalences are for the type of program variables
	% and associated structures.

:- type prog_var_type	--->	prog_var_type.
:- type prog_var	==	var(prog_var_type).
:- type prog_varset	==	varset(prog_var_type).
:- type prog_substitution ==	substitution(prog_var_type).
:- type prog_term	==	term(prog_var_type).
:- type prog_vars	==	list(prog_var).

	% A prog_context is just a term__context.

:- type prog_context	==	term__context.

	% Describe how a lambda expression is to be evaluated.
	%
	% `normal' is the top-down Mercury execution algorithm.
	%
	% `lambda_eval_method's other than `normal' are used for lambda
	% expressions constructed for arguments of the builtin Aditi
	% update constructs.
	%
	% `aditi_top_down' expressions are used by `aditi_delete'
	% goals (see hlds_goal.m) to determine whether a tuple
	% should be deleted.
	%
	% `aditi_bottom_up' expressions are used as database queries to
	% produce a set of tuples to be inserted or deleted.
:- type lambda_eval_method
	--->	normal
	;	(aditi_top_down)
	;	(aditi_bottom_up)
	.

%-----------------------------------------------------------------------------%
%
% Types
%

	% This is how types are represented.

			% one day we might allow types to take
			% value parameters as well as type parameters.

% type_defn/3 define above

:- type type_defn	
	--->	du_type(sym_name, list(type_param), list(constructor),
			maybe(equality_pred)
		)
	;	uu_type(sym_name, list(type_param), list(type))
	;	eqv_type(sym_name, list(type_param), type)
	;	abstract_type(sym_name, list(type_param)).

:- type constructor	
	--->	ctor(
			existq_tvars,
			list(class_constraint),	% existential constraints
			sym_name,
			list(constructor_arg)
		).

:- type constructor_arg	==	pair(string, type).

	% An equality_pred specifies the name of a user-defined predicate
	% used for equality on a type.  See the chapter on them in the
	% Mercury Language Reference Manual.
:- type equality_pred	==	sym_name.

	% probably type parameters should be variables not terms.
:- type type_param	==	term(tvar_type).

	% Module qualified types are represented as ':'/2 terms.
	% Use type_util:type_to_type_id to convert a type to a qualified
	% type_id and a list of arguments.
	% type_util:construct_type to construct a type from a type_id 
	% and a list of arguments.
:- type (type)		==	term(tvar_type).
:- type type_term	==	term(tvar_type).

:- type tvar_type	--->	type_var.
:- type tvar		==	var(tvar_type).
					% used for type variables
:- type tvarset		==	varset(tvar_type).
					% used for sets of type variables
:- type tsubst		==	map(tvar, type). % used for type substitutions

	% existq_tvars is used to record the set of type variables which are
	% existentially quantified
:- type existq_tvars	==	list(tvar).

	% Types may have arbitrary assertions associated with them
	% (eg. you can define a type which represents sorted lists).
	% Similarly, pred declarations can have assertions attached.
	% The compiler will ignore these assertions - they are intended
	% to be used by other tools, such as the debugger.

:- type condition	
	--->	true
	;	where(term).

%-----------------------------------------------------------------------------%
%
% insts and modes
%

	% This is how instantiatednesses and modes are represented.
	% Note that while we use the normal term data structure to represent 
	% type terms (see above), we need a separate data structure for inst 
	% terms. 

	% The `inst' data type itself is defined in the module `inst.m'.

:- type inst_var_type	--->	inst_var_type.
:- type inst_var	==	var(inst_var_type).
:- type inst_term	==	term(inst_var_type).
:- type inst_varset	==	varset(inst_var_type).

% inst_defn/3 defined above

:- type inst_defn	
	--->	eqv_inst(sym_name, list(inst_param), inst)
	;	abstract_inst(sym_name, list(inst_param)).

	% probably inst parameters should be variables not terms
:- type inst_param	==	inst_term.

	% An `inst_name' is used as a key for the inst_table.
	% It is either a user-defined inst `user_inst(Name, Args)',
	% or some sort of compiler-generated inst, whose name
	% is a representation of it's meaning.
	%
	% For example, `merge_inst(InstA, InstB)' is the name used for the
	% inst that results from merging InstA and InstB using `merge_inst'.
	% Similarly `unify_inst(IsLive, InstA, InstB, IsReal)' is
	% the name for the inst that results from a call to
	% `abstractly_unify_inst(IsLive, InstA, InstB, IsReal)'.
	% And `ground_inst' and `any_inst' are insts that result
	% from unifying an inst with `ground' or `any', respectively.
	% `typed_inst' is an inst with added type information.
	% `typed_ground(Uniq, Type)' a equivalent to
	% `typed_inst(ground(Uniq, no), Type)'.
	% Note that `typed_ground' is a special case of `typed_inst',
	% and `ground_inst' and `any_inst' are special cases of `unify_inst'.
	% The reason for having the special cases is efficiency.
	
:- type inst_name	
	--->	user_inst(sym_name, list(inst))
	;	merge_inst(inst, inst)
	;	unify_inst(is_live, inst, inst, unify_is_real)
	;	ground_inst(inst_name, is_live, uniqueness, unify_is_real)
	;	any_inst(inst_name, is_live, uniqueness, unify_is_real)
	;	shared_inst(inst_name)
	;	mostly_uniq_inst(inst_name)
	;	typed_ground(uniqueness, type)
	;	typed_inst(type, inst_name).

	% Note: `is_live' records liveness in the sense used by
	% mode analysis.  This is not the same thing as the notion of liveness
	% used by code generation.  See compiler/notes/glossary.html.
:- type is_live		--->	live ; dead.

	% Unifications of insts fall into two categories, "real" and "fake".
	% The "real" inst unifications correspond to real unifications,
	% and are not allowed to unify with `clobbered' insts (unless
	% the unification would be `det').
	% Any inst unification which is associated with some code that
	% will actually examine the contents of the variables in question
	% must be "real".  Inst unifications that are not associated with
	% some real code that examines the variables' values are "fake".
	% "Fake" inst unifications are used for procedure calls in implied
	% modes, where the final inst of the var must be computed by
	% unifying its initial inst with the procedure's final inst,
	% so that if you pass a ground var to a procedure whose mode
	% is `free -> list_skeleton', the result is ground, not list_skeleton.
	% But these fake unifications must be allowed to unify with `clobbered'
	% insts. Hence we pass down a flag to `abstractly_unify_inst' which
	% specifies whether or not to allow unifications with clobbered values.

:- type unify_is_real
	--->	real_unify
	;	fake_unify.

% mode_defn/3 defined above

:- type mode_defn	
	--->	eqv_mode(sym_name, list(inst_param), mode).

:- type (mode)		
	--->	((inst) -> (inst))
	;	user_defined_mode(sym_name, list(inst)).

% mode/4 defined above

%-----------------------------------------------------------------------------%
%
% Module system
%

	% This is how module-system declarations (such as imports
	% and exports) are represented.

:- type module_defn	
	--->	module(module_name)
	;	end_module(module_name)

	;	interface
	;	implementation

	;	private_interface
		% This is used internally by the compiler,
		% to identify items which originally
		% came from an implementation section
		% for a module that contains sub-modules;
		% such items need to be exported to the
		% sub-modules.

	;	imported(section)
		% This is used internally by the compiler,
		% to identify declarations which originally
		% came from some other module imported with 
		% a `:- import_module' declaration, and which
		% section the module was imported.
	;	used(section)
		% This is used internally by the compiler,
		% to identify declarations which originally
		% came from some other module and for which
		% all uses must be module qualified. This
		% applies to items from modules imported using
		% `:- use_module', and items from `.opt'
		% and `.int2' files. It also records from which
		% section the module was imported.
	;	opt_imported
		% This is used internally by the compiler,
		% to identify items which originally
		% came from a .opt file.

	;	external(sym_name_specifier)

	;	export(sym_list)
	;	import(sym_list)
	;	use(sym_list)

	;	include_module(list(module_name)).

:- type section
	--->	implementation
	;	interface.

:- type sym_list	
	--->	sym(list(sym_specifier))
	;	pred(list(pred_specifier))
	;	func(list(func_specifier))
	;	cons(list(cons_specifier))
	;	op(list(op_specifier))
	;	adt(list(adt_specifier))
	;	type(list(type_specifier))
	;	module(list(module_specifier)).

:- type sym_specifier	
	--->	sym(sym_name_specifier)
	;	typed_sym(typed_cons_specifier)
	;	pred(pred_specifier)
	;	func(func_specifier)
	;	cons(cons_specifier)
	;	op(op_specifier)
	;	adt(adt_specifier)
	;	type(type_specifier)
	;	module(module_specifier).
:- type pred_specifier	
	--->	sym(sym_name_specifier)
	;	name_args(sym_name, list(type)).
:- type func_specifier	==	cons_specifier.
:- type cons_specifier	
	--->	sym(sym_name_specifier)
	;	typed(typed_cons_specifier).
:- type typed_cons_specifier 
	--->	name_args(sym_name, list(type))
	;	name_res(sym_name_specifier, type)
	;	name_args_res(sym_name, list(type), type).
:- type adt_specifier	==	sym_name_specifier.
:- type type_specifier	==	sym_name_specifier.
:- type op_specifier	
	--->	sym(sym_name_specifier)
	% operator fixity specifiers not yet implemented
	;	fixity(sym_name_specifier, fixity).
:- type fixity		
	--->	infix 
	; 	prefix 
	; 	postfix 
	; 	binary_prefix 
	; 	binary_postfix.
:- type sym_name_specifier 
	--->	name(sym_name)
	;	name_arity(sym_name, arity).
:- type sym_name 	
	--->	unqualified(string)
	;	qualified(module_specifier, string).
:- type sym_name_and_arity
	--->	sym_name / arity.

:- type module_specifier ==	sym_name.
:- type module_name 	== 	sym_name.
:- type arity		==	int.

	% Describes whether an item can be used without an 
	% explicit module qualifier.
:- type need_qualifier
	--->	must_be_qualified
	;	may_be_unqualified.

%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%

:- implementation.

:- type pragma_c_code_attributes
	--->	attributes(
			may_call_mercury,
			thread_safe
		).

default_attributes(attributes(may_call_mercury, not_thread_safe)).

may_call_mercury(Attrs, MayCallMercury) :-
	Attrs = attributes(MayCallMercury, _).

thread_safe(Attrs, ThreadSafe) :-
	Attrs = attributes(_, ThreadSafe).

set_may_call_mercury(Attrs0, MayCallMercury, Attrs) :-
	Attrs0 = attributes(_, ThreadSafe),
	Attrs  = attributes(MayCallMercury, ThreadSafe).

set_thread_safe(Attrs0, ThreadSafe, Attrs) :-
	Attrs0 = attributes(MayCallMercury, _),
	Attrs  = attributes(MayCallMercury, ThreadSafe).

%-----------------------------------------------------------------------------%