
CHR1(I,J,K):=(MODEDECLARE([I,J,K],INTEGER),
  IF %CHR1[I,J,K]#UNDEF THEN %CHR1[I,J,K] 
  ELSE %CHR1[I,J,K]:%CHR1[J,I,K]:
      RATSIMP((1/2)*(DIFF(LG[I,K],X[J])+DIFF(LG[J,K],X[I])-DIFF(LG[I,J],X[K]))) )$

CHR2(I,J,L):=(MODEDECLARE([I,J,K,L],INTEGER),
  IF %CHR2[I,J,L]#UNDEF THEN %CHR2[I,J,L]
  ELSE %CHR2[I,J,L]:%CHR2[J,I,L]:BLOCK([ANS],ANS:0,
       IF NOT INVERTED THEN (INVERTED:TRUE,LG:G^^-1),
       FOR K:1 THRU 4 DO ANS:ANS+CHR1(I,J,K)*UG[K,L],
       RATSIMP(ANS) ) )$

RIEMANN(I,J,K,L):=(MODEDECLARE([I,J,K,L],INTEGER),
  IF %RIEMANN[I,J,K,L]#UNDEF THEN %RIEMANN[I,J,K,L]
    ELSE IF (I=J) OR (L=K) THEN %RIEMANN[I,J,K,L]:0
    ELSE IF I<J THEN %RIEMANN[I,J,K,L]:-RIEMANN(J,I,K,L)
    ELSE IF K<L THEN %RIEMANN[I,J,K,L]:-RIEMANN(I,J,L,K)
    ELSE IF I+4*J<K+4*L THEN RIEMANN(K,L,I,J)
    ELSE %RIEMANN[I,J,K,L]:%RIEMANN[K,L,I,J]:RATSIMP(
        RIE1(J,L,I,K)-RIE1(J,K,I,L)+RIE2(I,L,J,K)-RIE2(I,K,J,L)))$

RIE2(I,J,K,L):=BLOCK([ANS],
    MODEDECLARE([I,J,K,L,R],INTEGER),
     ANS:0,
        FOR R:1 THRU 4 DO ANS:ANS+CHR1(I,J,R)*CHR2(K,L,R), ANS)$

RIE1(I,J,K,L):=(MODEDECLARE([I,J,K,L],INTEGER),
    DIFF(CHR1(I,J,K),X[L]))$

RICCI(I,J):=(
  MODEDECLARE([I,J,K,L],INTEGER,INVERTED,BOOLEAN),
  IF %RICCI[I,J]#UNDEF THEN %RICCI[I,J]
  ELSE %RICCI[I,J]:%RICCI[J,I]:BLOCK([ANS], ANS:0,
    IF NOT INVERTED THEN (INVERTED:TRUE,UG:G^^-1),
    FOR K:1 THRU 4 DO 
        FOR L:1 THRU 4 DO ANS:ANS+RIEMANN(I,K,J,L)*UG[K,L],
     RATSIMP(ANS))
)$

