I have written a simple set of predicates to “tag” elements in a term according to their “type”.
Efficiency is not a factor, the goal was to keep to the “decision tree of types” and not use cuts.
So you can ask things like:
?- once(tag(X,S)).
S = var(X). % X is a variable
?- once(tag(100,S)).
S = int(100). % Yup, 100 is an integer
?- once(tag(100.1,S)).
S = float(100.1). % That's a float
?- once(tag(1/3,S)).
S = compound(/, [gnd], [int(1), int(3)]). % Evidently a compound term, ground, with two integers
?- once(tag(d{x:1,y:1,z:Z},S)).
S = dict(d, [nongnd], [atom(x)-int(1), atom(y)-int(1), atom(z)-var(Z)]).
?- once(tag([1,X,2],S)).
S = lbox([list, nongnd], int(1), lbox([list, nongnd], var(X), lbox([list, gnd], int(2), emptylist))).
?- once(tag(p(X,[1,2]),S)).
S = compound(p, [nongnd], [var(X), lbox([list, gnd], int(1), lbox([list, gnd], int(2), emptylist))]).
Two questions:
- Is there a way to write down the dict functor? Currently I retrieve one for comparison purposes. For example, in case I want to detect a dict:
dict_functor(F) :- compound_name_arity(_{},F,_Arity).
tag_nonzero_arity_compound(T,dict(DictTag,Marks,TgDictArgs)) :-
dict_functor(F), % retrieve
compound_name_arguments(T,F,[DictTag|DictArgs]), % is it a dict?
marks(T,Marks), % find out about non-local properties, like ground-ess, cyclic-ness,...
re_pair(DictArgs,TgDictArgsUnsorted), % transform key-vals into pairs
keysort(TgDictArgsUnsorted,TgDictArgs). % impose order!
- Is there a way to find out when a cycle has been traversed when going down a cyclic structure? One would have to label the terms somehow and stop traversel when a labeled term is encountered. Otherwise, how to know when to stop?
Umm… yeah, that’s it for today. On to reading Indexing dif/2
.