123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444 |
- module spaces; % definition and general properties
- % of spaces.
- lisp remflag(list 'minus,'intfn);
- global '(dimex!* sgn!* signat!* spaces!* numindxl!* pair_id_num!*) ;
- lisp (pair_id_num!*:= '((!0 . 0) (!1 . 1) (!2 . 2) (!3 . 3) (!4 . 4)
- (!5 . 5) (!6 . 6) (!7 . 7) (!8 . 8) (!9 . 9)
- (!10 . 10) (!11 . 11) (!12 . 12) (!13 . 13)));
- fluid('(dummy_id!* g_dvnames epsilon!*));
- % g_dvnames is a vector.
- switch onespace;
- !*onespace:=t; % working inside a unique space is the default.
- fluid('(indxl_tens!* dummy_id!* g_dvnames)); % g_dvnames is a vector.
- % dimex!* = global space dimension. Standard form.
- % sgn!* = Choice of "global sign". Equals 1 or -1.
- % 1 for high energy physicists, -1 for astrophysicists.
- % !*onespace = when OFF allows to introduce a space
- % which is the direct product of two or more spaces.
- % numindxl!* := nil initially. Contains all indexranges: ((sp min max) ..)
- dimex!*:= !*k2f 'dim;
- sgn!* := 1; % Global sign: determine the convention (+---) ou (-+++)
- % High energy physicists convention is chosen by default.
- signat!* :=0; % number of time-like coordinates.
- fluid '(alglist!*);
- smacro procedure get_prop_space u;
- % To get properties of a given space (subspace).
- subla(spaces!*,u);
- symbolic procedure charnump!: x;
- if x memq
- list('!0,'!1,'!2,'!3,'!4,'!5,'!6,'!7,'!8,'!9,'!10,'!11,'!12,'!13)
- then t ;
- symbolic procedure get_dim_space u;
- if null u then nil
- else
- (if not atom x then car x)where x=subla(spaces!*,u);
- symbolic procedure get_sign_space u;
- % To get the signature of a given space (subspace).
- % result is nil if space is 'affine'
- if null u then nil else
- (if atom cadr x and null cddr x then
- if cadr x eq 'euclidian then 0
- else nil
- else caddr x)where x=subla(spaces!*,u);
- symbolic procedure affinep u;
- % u is a tensor kernel
- % returns T if the the tensor belongs to an affine space.
- (if x then null get_sign_space x)where x=get(car u,'belong_to_space);
- symbolic procedure get_indexrange_space u;
- % To get the signature of a given space (subspace).
- if null spaces!* then nil
- else
- (if x then
- if not atom x and cddr x and cdddr x then cadddr x
- else
- if cddr x and not atom caddr x then caddr x)
- where x=if spaces!* then subla(spaces!*,u);
- symbolic procedure onespace u;
- % Defined specifically for the user. tells if
- % one or several spaces are active.
- % By default, a UNIQUE space is supposed.
- if u eq '? then
- if !*onespace then symb_to_alg 'YES else symb_to_alg 'NO
- else nil;
-
- symbolic procedure wholespace_dim u;
- % if u is ? gives the space-dimension. else sets the space-dim.
- begin
- if u eq '? then return
- prepsq!* !*f2q dimex!*
- else
- if null get('wholespace,'spacedef) then
- <<dimex!* := !*q2f simp u ;
- return prepsq!* !*f2q dimex!*>>;
- end;
- symbolic procedure global_sign u;
- % if u is ? gives the global sign else sets it.
- begin
- if u eq '? then return sgn!*
- else return
- sgn!* := u
- end;
- symbolic procedure signature u;
- % if u is ? gives the number of time-like coordinates else sets it.
- if u eq '? then signat!*
- else
- if !*onespace and fixp u then signat!*:=u
- else "non-active in OFF ONESPACE";
- flag({'onespace,'show_spaces,'wholespace_dim ,
- 'global_sign ,'signature},'opfn);
- % The notion of indexrange for numeric indices is now implemented:
-
- % taken from INEQ
- newtok '( (!. !.) !*interval!*);
- % first, introduction of interval through the command a .. b
- if null get('!*interval!*,'simpfn) then
- <<precedence .., or;
- algebraic operator ..;
- put('!*interval!*,'prtch,'! !.!.! );
- >>;
- symbolic procedure mkinterval(u,v);
- % u et v sont des entiers
- % utility function not yet used for the algebraic mode
- symb_to_alg list('!*interval!*,u,v);
- symbolic procedure lst_belong_interval(lst,int);
- if null lst then t
- else
- if idx_belong_interval(car lst,int) then lst_belong_interval(cdr lst,int)
- else nil;
- symbolic procedure idx_belong_interval(idx,int);
- % t if numeric index 'idx' belongs to the interval 'int'.
- if null int or atom int then t
- else idx geq car int and idx leq cadr int;
- symbolic procedure numids2_belong_same_space(i1,i2,tens);
- % basic function to determine if two numeric indices
- % belong or not to the same space. Boolean.
- % tens is the name of the tensor
- (if x and y then
- begin scalar ind,sp;
- if null numindxl!* then return t;
- ind:=if (sp:=get(tens,'belong_to_space)) then
- list subla(numindxl!*,sp)
- else for each x in numindxl!* collect cdr x;
- loop: if null ind then return nil
- else
- if idx_belong_interval(x,car ind)
- and idx_belong_interval(y,car ind)
- then return t
- else ind:=cdr ind;
- go to loop;
- end)where x=!*id2num i1,y=!*id2num i2;
- symbolic procedure num_ids_belong_same_space(u,tens);
- % u is a list of numeric indices
- % tens is the name of a tensor
- << if oddp length u then u:= car u . u;
- while u and numids2_belong_same_space(car u,cadr u,tens)
- do u:=cddr u; if null u then t else nil>>;
- symbolic procedure symb_ids_belong_same_space(u,v);
- % u is a list of indices.
- % nil is the current starting value for v but may be the
- % name of one space. In that case, it verifies that all indices
- % in u belong to the v space.
- if null u or v = 'wholespace then t
- else
- if null get(car u,'space) or get(car u,'space) = v
- then symb_ids_belong_same_space(cdr u,v)
- else
- if null v then symb_ids_belong_same_space(cdr u,get(car u,'space))
- else
- if get(car u,'space) neq v then nil;
- symbolic procedure symb_ids_belong_same_space!:(u,v);
- % This is a variant of the previous procedure.
- % needed for DEL-like tensors when working in OFF onespace
- % u is a list of indices.
- % nil is the current starting value for v but may be the
- % name of one space. In that case, it verifies that all indices
- % in u belong to the v space.
- if null u then t
- % v = 'wholespace then t NOT VALID in general since some indices
- % may have a restricted range while BELONGING to a
- % WELL DEFINED space. Should most probably replace it.
- else
- if null get(car u,'space) or get(car u,'space) = v
- then symb_ids_belong_same_space!:(cdr u,v)
- else
- if null v then symb_ids_belong_same_space!:(cdr u,get(car u,'space))
- else
- if get(car u,'space) neq v then nil;
- symbolic procedure ind_same_space_tens(u,tens);
- % u are the indices of tens.
- % verify that they belong to the same space
- % !!! if some indices belong to no space or to the
- % wholespace it does not take them into account.
- begin scalar lst,lstnum;
- lst := clean_numid u;
- lstnum:=extract_num_id u;
- return
- if num_ids_belong_same_space(lstnum,tens) and
- symb_ids_belong_same_space(lst,get(tens,'belong_to_space))
- then t
- else nil;
- end;
- rlistat ('(define_spaces rem_spaces));
- symbolic procedure define_spaces u;
- % Define subspaces by the commands:
- % define_spaces s={ds,affine}
- % or
- % define_spaces s={ds,euclidean}
- % or
- % define_spaces s={ds,signature=<number>,indexrange=a .. b}
- if !*onespace then nil
- else
- if not fixp sgn!* then rederr "set the global sign please" else
- begin scalar sp;rmsubs();
- for each j in u do
- if not eqexpr j then errpri2(j,'hold)
- else
- if get(sp:=cadr j,'spacedef) or
- flagp(sp,'reserved) or getrtype sp or gettype sp
- then
- lpri{"*** Warning:",sp,
- " cannot be (or is already) defined as space identifier"}
- else <<(put(sp,'spacedef,
- if eqexpr caddr y then sp . cadr y . whole_space(sp,y)
- else sp . whole_euclid_space(sp,y)))where y=caddr j;
- spaces!*:=if null assoc(sp,spaces!*) then
- union(list get(sp,'spacedef),spaces!*);
- numindxl!* := if space_index_range sp then
- union( list (sp . space_index_range sp),numindxl!*);>>;
- return t
- end;
- symbolic procedure whole_euclid_space(sp,u);
- % u is the y of define_spaces
- % {ds,euclidean,indexrange=a .. b}
- (if sp eq 'wholespace then
- <<dimex!*:=!*k2f car w; signat!*:=0; w>> else w)where w=cdr u;
- symbolic procedure whole_space(sp, u);
- % u is y of define_spaces
- % {ds,signature=<number>,indexrange=a .. b}
- (if sp eq 'wholespace then
- <<dimex!*:=!*k2f car w; signat!*:=caddr cadr w;
- if cddr w then cadadr w . cadr cdadr w . list caddr w
- else cdadr w
- >>
- else
- if cddr w then cadadr w . cadr cdadr w . list caddr w
- else cdadr w )where w=cdr u;
- %symbolic procedure whole_space(sp, u);
- % In case of emergency, I keep it!
- % u is y of define_spaces
- % {ds,signature=<number>,indexrange=a .. b}
- % (if sp eq 'wholespace then
- % <<dimex!*:=!*k2f car w; signat!*:=caddr cadr w;cdadr w>>
- % else
- % if cddr w then cadadr w . cadr cdadr w . list caddr w
- % else cdadr w )where w=cdr u;
- symbolic procedure space_index_range u;
- % u is the name of a given space
- % result is
- begin scalar x;
- x:=get_indexrange_space u;
- return
- if null x then nil
- else bubblesort1( caddr cadr x . caddr x . nil)
- end;
- symbolic procedure rem_spaces u;
- <<for each j in u do
- <<remprop(j,'spacedef);
- spaces!*:=delete(assoc(j, spaces!*),spaces!*);
- numindxl!*:=delete(assoc(j,numindxl!*),numindxl!*);
- remflag(list j,'reserved);
- if j eq 'wholespace then
- <<dimex!*:=!*k2f 'dim; signat!*:=0;>>
- >>;
- t>>;
- symbolic procedure mkequal u;
- % u is an element of spaces!*
- {'equal,'signature,cadr u};
- symbolic procedure insert_sign_equal u;
- % u is an element of spaces!*
- begin scalar l;
- loop: if null u then return reverse l ;
- if car u neq 'signature then <<l:=car u . l; u:=cdr u>>
- else <<l:=mkequal u . l; u:=cddr u>>;
- go to loop;
- end;
- symbolic procedure show_spaces();
- % Gives the properties of already defined spaces
- begin scalar x;
- x:=for each i in spaces!* collect insert_sign_equal i;
- x:=for each y in x collect 'list .
- for each z in y collect if pairp z then z else mk!*sq !*k2q z;
- return 'list . reverse x
- end;
- flag(list 'mk_ids_belong_space,'opfn);
- symbolic procedure mk_ids_belong_space(u,v);
- % u is a list of identifiers which are indices
- % v is the name of an already defined (sub)space
- % Make all indices belong to v.
- % Works ONLY when the swith onespace is OFF.
- if !*onespace then nil
- else
- if idp u then <<put(u,'space,v),t>>
- else <<for each x in u do put(x,'space,v),t>>;
- rlistat('(mk_ids_belong_anyspace));
- symbolic procedure mk_ids_belong_anyspace u;
- % makes all x in u belong to the global space.
- <<for each x in u do remprop(x,'space); t>>;
- symbolic procedure space_of_idx u;
- % try to detect the space to which an index belongs to.
- begin scalar sp;
- return
- if sp:=get(u,'space) then sp
- else
- if assoc('wholespace,spaces!*) then 'wholespace
- else if length spaces!* = 1 then
- if yesp list("Does ",u," belong to ",caar spaces!*,"?")
- then put(u,'space,caar spaces!*)
- else rerror(cantensor,4,list("Space of index ",u," unknown"))
- else
- % it is not clear that this error message should be maintained:
- msgpri(nil,nil,u, "MUST belong to a (sub)space",t);
- end;
- symbolic procedure space_dim_of_idx u;
- % u is the name of an index
- % result is the dimension of the space to which it belongs
- % or an error message.
- if null !*onespace then
- begin scalar sp;
- sp:=get(u,'space);
- if null sp then return mvar dimex!*
- else return get_dim_space sp
- end;
- symbolic procedure extract_dummy_ids u;
- % extracts the dummy indices from a given list
- if null u then nil
- else if car u memq dummy_id!* then
- car u . extract_dummy_ids cdr u
- else extract_dummy_ids cdr u;
- rlistat('(rem_dummy_indices));
- symbolic procedure rem_dummy_indices u ;
- % remove property 'dummy' of all indices in u.
- % redefines g_dvnames.
- <<for each x in u do
- <<dummy_id!* := delete(x,dummy_id!*);
- remprop(x,'space);
- remflag(list x,'dummy); remflag(list x,'reserved)>>;
- dummy_nam dummy_id!*; t>>;
- symbolic procedure dummy_indices;
- symb_to_alg dummy_id!*;
- flag(list('dummy_indices),'opfn);
- symbolic procedure mk_dummy_ids u;
- % u is the output of split_cov_cont_ids
- % constructs the 'dummy_id!*' and the g_dvnames globals
- % variable.
- begin scalar y;
- y:=clean_numid intersection(car u,cadr u);
- flag(y,'dummy);
- flag(y,'reserved);
- dummy_id!*:= union(y,dummy_id!*);
- % dummy_nam(dummy_id!*)
- end;
- symbolic procedure mk_lst_for_dummy u;
- % u is the output of index_list
- % It eliminates the minus sign
- for each x in u collect
- if atom x then x
- else
- if cadr x memq dummy_id!* then cadr x
- else x;
- symbolic procedure multiplicity_elt(ob,l);
- % ob is an arbitrary index, l is a list of indices
- % returns the multiplicity of ob in l.
- begin integer n;
- while l:=memq(ob,l) do <<l:=cdr l;n:=n+1>>;
- return n
- end;
- symbolic procedure mult_leq_onep u;
- % u is a list of indices
- if null u then t else
- if multiplicity_elt(car u,u) leq 1 then
- mult_leq_onep(cdr u);
-
- symbolic procedure eqn_indices(u,v);
- % verify if two indices are fixed (pseudo-numbers) and equal.
- (x and y and eqn(x,y))where x=!*id2num u, y=!*id2num v;
-
- endmodule;
- end;
|