:- dynamic touch/7.
:- discontiguous touch/7.
:- index(touch(1,0,0,0,0,0,1,0)).

term_expansion(type X,L) :- 
    findall(Y,def1(X,Y),L).

type1(X,touch(Functor, Field, Type,Old,New, Term0,Term)) :-
	c2l(X,L),
    type2(L,Functor,Fields,Arity,Term0),
    nth1(N,Fields,Spec),
	once(spec(Functor,Spec,Field,Type)),
    Term0=..[_|L0],
    functor(Term,Functor,Arity),  
    Term=.. [_|L],
    joinArgs(1,N,L0,Old,New,L).

spec(F,value,value,F).
spec(_,X,X,X)    :- atomic(X).
spec(_,X,Field,Type) :- X  =.. [Type,Field].

joinArgs(N,N,[Old|Rest],Old,New,[New|Rest]).
joinArgs(N0,N1,[X|L0],Old,New,[X|L]) :- 
    N0 < N1, 
    N2 is N0 + 1,
    joinArgs(N2,N1,L0,Old,New,L).
        
type2(X,Functor,Fields,Arity,Term) :-
    X =.. [Functor|Fields],
    length(Fields,Arity),
    functor(Term,Functor,Arity).

c2l((X,Y),[X|Z]) :- !,c2l(Y,Z).
c2l(X,[X]).

blank(Functor,Term) :- 
	once(touch(Term,_,_,_,_,_,Functor)).
