Tabling round 2 [2/2]

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Mar 18 17:34:19 AEDT 1998


On 13-Mar-1998, Oliver Hutchison <ohutch at students.cs.mu.OZ.AU> wrote:
> +#define NON_TABLE(T)  (*((NondetTable **)T))

You should document that macro.

I'd define it as

	#define NON_TABLE(T)  (*(NondetTable **)T)

The extra parentheses in your original version
just make it harder to parse, IMHO.

> +:- pragma c_code(table_setup(T0::in, T::out), will_not_call_mercury, "
> +	/* Init the table if this is the first time me see it */
> +	if (NON_TABLE(T0) == NULL) {
> +		NON_TABLE(T0) = (NondetTable *) table_allocate(
> +			sizeof(NondetTable));
> +		NON_TABLE(T0)->status = have_no_ans;
> +		NON_TABLE(T0)->answer_table = 0;

Is that `0' supposed to represent a null pointer?
If so, `NULL' (or if necessary `(Word) NULL') would be
a better way of writing it.

> +		NON_TABLE(T0)->num_ans = 0;
> +		NON_TABLE(T0)->answer_list = list_empty();
> +		NON_TABLE(T0)->ans_list_tail =
> +			&NON_TABLE(T0)->answer_list;
> +		NON_TABLE(T0)->suspend_list = list_empty();
> +		NON_TABLE(T0)->suspend_list_tail =
> +			&NON_TABLE(T0)->suspend_list;
> +		NON_TABLE(T0)->non_stack_bottom = curprevfr;
> +		NON_TABLE(T0)->det_stack_bottom = MR_sp;
> +	}
> +	T = T0;
> +").
> +
> +
> +table_return_all_ans(T, A) :-
> +	semipure table_return_all_ans_list(T, AnsList),
> +	list__member(Node, AnsList),
> +	semipure table_return_all_ans_2(Node, A).
> +
> +:- semipure pred table_return_all_ans_list(table, list(table)).
> +:- mode table_return_all_ans_list(in, out) is det.
> +
> +:- pragma c_code(table_return_all_ans_list(T::in, A::out),
> +		 will_not_call_mercury, "
> +	A = NON_TABLE(T)->answer_list;
> +").
> +
> +:- semipure pred table_return_all_ans_2(table, table).
> +:- mode table_return_all_ans_2(in, out) is det.
> +
> +:- pragma c_code(table_return_all_ans_2(P::in, A::out), 
> +		will_not_call_mercury, "
> +	A = (Word) &((AnswerListNode*) P)->ans;
> +").

Why do you cast P to AnswerListNode* instead of casting to NondetTable*
(via the NON_TABLE macro)?

Perhaps you should change the types of the arguments in the
type declaration.

> +:- pragma c_code(table_suspend(T::in, A::out), will_not_call_mercury, "

Some more documentation about the code for this predicate
would be helpful.

Why is it declared as `nondet'?

> +	A = 0;
> +	fail();	

Why assign to A if you're only going to immediately fail anyway?

According to the nonexistant documentation for nondet pragma C ;-),
the `fail()' here should be `FAIL()'.

> +typedef struct {
> +	NondetTable *table;
> +	Word non_stack_block_size;
> +	Word *non_stack_block;
> +	Word det_stack_block_size;
> +	Word *det_stack_block;
> +	
> +	Code *succ_ip;
> +	Word *s_p;
> +	Word *cur_fr;
> +	Word *max_fr;
> +
> +	Word changed;
> +	Word num_ans, new_num_ans;
> +	Word suspend_list;
> +	SuspendListNode *suspend_node;
> +	Word ans_list;
> +	AnswerListNode *ansNode;
> +} ResumeStackNode;

You should document this structure.

> +Integer ML_resumption_sp = -1;
> +Word ML_resumption_stack_size = 256;	/* Half the initial size of 
> +						the stack */

In units of words? bytes? megabytes?

> +Define_extern_entry(mercury__table_resume_1_0);

You need much more documentation about the implementation
of this predicate.

Instead of using r1 directly, you should define
macros in runtime/mercury_type_info.h
similar to the `unify_input1', etc. macros,
so that it works without -DCOMPACT_ARGS.

> +Declare_label(mercury__table_resume_1_0_ChangeLoop);
> +Declare_label(mercury__table_resume_1_0_ChangeLoopDone);
> +Declare_label(mercury__table_resume_1_0_SolutionsListLoop);
> +Declare_label(mercury__table_resume_1_0_AnsListLoop);
> +Declare_label(mercury__table_resume_1_0_AnsListLoopDone);
> +Declare_label(mercury__table_resume_1_0_SkipAns);
> +Declare_label(mercury__table_resume_1_0_RedoPoint);
> +
> +MR_MAKE_STACK_LAYOUT_ENTRY(mercury__table_resume_1_0);
> +
> +BEGIN_MODULE(table_module)
> +	init_entry(mercury__table_resume_1_0);
> +	init_label(mercury__table_resume_1_0_ChangeLoop);
> +	init_label(mercury__table_resume_1_0_ChangeLoopDone);
> +	init_label(mercury__table_resume_1_0_SolutionsListLoop);
> +	init_label(mercury__table_resume_1_0_AnsListLoop);
> +	init_label(mercury__table_resume_1_0_AnsListLoopDone);
> +	init_label(mercury__table_resume_1_0_SkipAns);
> +	init_label(mercury__table_resume_1_0_RedoPoint);
> +BEGIN_CODE
> +
> +Define_entry(mercury__table_resume_1_0);
...
> +	bt_redoip(maxfr) = LABEL(mercury__table_resume_1_0_RedoPoint);

I don't understand what is going on here,
but it seems that you are clobbering the value of
bt_redoip(maxfr) without saving the previous value stored there.
Is that a bug?

> +Define_label(mercury__table_resume_1_0_AnsListLoop);
> +	r1 = (Word) &ML_RESUME_VAR->ansNode->ans;
> +
> +	succeed();

Here you are calling succeed() from a procedure with determinism
`failure', i.e. code model model_semi.  This looks very suspicious.

> +	SUCCESS_INDICATOR = 0;

s/0/FALSE/

> +:- pragma c_code(table_new_ans_slot(T::in, Slot::out), 
> +		will_not_call_mercury, "
...
> +	Slot = (Word)&n->ans;

s/(Word)/(Word) /
               ^

(Likewise in lots of other places.)

runtime/mercury_string.h:
>  #define HASH_STRING_FUNC_BODY				\
> -	   int hash;					\
> -	   do_hash_string(hash, s);			\
> -	   return hash;
> +	   int _hash;					\
> +	   do_hash_string(_hash, s);			\
> +	   return _hash;

s/_hash/hash_string_result/g

> --- mercury_type_info.h	1998/03/11 05:58:46	1.5
> +++ mercury_type_info.h	1998/03/12 01:49:05
> @@ -779,5 +779,10 @@
>  
>  #define MR_make_array(sz) ((MR_ArrayType *) make_many(Word, (sz) + 1))
>  
> +
> +Word * MR_create_type_info(Word *, Word *);
> +int MR_compare_type_info(Word, Word);
> +Word MR_collapse_equivalences(Word);

It would be useful to add a pointer to the documentation:

	/* These functions are documented in mercury_type_info.c */

Perhaps the documentation should be moved, but I think just
adding a pointer is good enough.

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.



More information about the developers mailing list