!MS5-RC-Concat.f95
!2025.01.17.0955cst JMS- Concatenation & Order computations
!              Computer- "T4"/HP-800-G4-Mini/i7-8700T/IntelUHD630/Win10Pro-22H2
!                         ^name  ^Mfgr.Id    ^chipset ^graphics   ^OS
!                            /AbsoftProFortran 21.0.2/OpenGL+Glut3.6
!                             ^compiler               ^Fortran graphics
!Table of Contents - ToC:
!Subroutine Concatenate(VtotL,VAnew,VAnext,VAprev,iP)-opens Data-nLAV.txt
!                                                   -opens Data-AttConcat.txt
!Subroutine AllMoves(VtotL,VAout,VAprevin,nCin,iP)  -Concatenation-based Emul. 
!Subroutine ComputeOrder(VtotL,VAin,nOrder,iP)      -order of Zone subsets
!---------------------------------------------------------------------------7 9

Subroutine Concatenate(VtotL,VAnew,VAnext,VAprev,iP)
!2025.01.17.0950cst JMS- 
!                 VAnew(1:VtotL) <- VAnext(1:VtotL) <- VAprev(1:VtotL)
!The VA's (1:VtotL) must be in natural order.

!--Globals
 use MS1Def   ,only: Ur,Us,Ut
 use MS2RCDef ,only: Asymbol   
!--End Globals
 implicit none
 !--Arguments
  integer(4)::VtotL
  integer(4)::VAnew(  27) !    The votes  [1:VtotL] 
  integer(4)::VAnext( 27)
  integer(4)::VAprev( 27)
  integer(4)::iP        !Write enable>5: write(iP,...)
 !--Internals
  integer(4)::Init,nA1,nV,nL
  integer(4)::AoutAAprev(1:24,1:24)
  integer(4)::nLAV(1:24,0:27)
  integer(4)::nVAprev(27)
  integer(4)::VAnextmod( 27)
  integer(4)::VAnewL(20) 
  !--EndDefs-----------------------------------------------

   if(Init==0) then    
     if(iP>5) write(iP,"(/'Concatenate:    Concat@L40'/)")
     write(iP,"( 'Import Data-nLAV.txt:')")
    !if(iP>5) write(iP,"('nLAV(1:24,0:27): nL = nLAV(A,V):  transposed ')")
     open(Ur, file='Data-nLAV.txt', action='read' &
                , access='sequential'      , status='old'    )
       read(Ur,"(//)")  !Skips the first 3 lines
      !if(iP>5) write(iP,"(24(2x,a1),' <-:nA')") (char(Asymbol(nV)),nV=1,24)
       do nL=0,27
         read(Ur,*) nLAV(1:24,nL)
        !if(iP>5) write(iP,"(24i3)") nLAV(1:24,nL)
       enddo!nL
      !if(iP>5) write(iP,"(' ^:V')")
     close(Ur)

    !Import AoutAAprev(1:24,1:24) = "Attitude Concatenations"
     if(iP>5) write(iP,"( 'Import Data-AttConcat.txt:')")
     open(Ur, file='Data-AttConcat.txt', action='read' &
               , access='sequential'      , status='old'    )
      read(Ur,"(//)")  !Skips the first 3 lines
      do nA1=1,24
        read(Ur,*) AoutAAprev(nA1,1:24)
       !write(iP,"(24(   i2,','))")              AoutAAprev(nA1,1:24)
      !!write(iP,"(24(1x,a1,','))") char(Asymbol(AoutAAprev(nA1,1:24)))
      enddo!nA1
      !if(iP>5) write(iP, &
      !    "('  ^:morph rotation changes to previous`s nL locations')")
     close(Ur)

     Init = 1
   endif!(Init==0)

  !Recurring processing: ----------------------------------
   VAnewL  = 0
   nVAprev = 0
   if(iP==6) write(iP,*)

  !Concatenation is accomplished in the next 7 lines of code:
   do nV = 1,VtotL 
     nVAprev(     nV)  = nLAV(VAprev(nV),nV)
     VAnextmod(   nV)  = VAnext(nVAprev(nV))
     if(VAprev(   nV) == 0) cycle
     if(VAnextmod(nV) == 0) cycle
     VAnewL(nV)        = AoutAAprev(VAnextmod(nV),VAprev(nV))
   enddo!nV

   if(iP>5) then
     write(iP,"(/'Concatenate in previous`s order: ----------')")
     write(iP,"( 'nV         :',:,20i3     )") (             nV    ,nV=1,VtotL)
     write(iP,"(/'A VAprev   :',:,20i3,'  :previous')")      VAprev(   1:VtotL)
     write(iP,"('     ""     :',:,20(2x,a1))") (char(Asymbol(VAprev(   1:VtotL))))

     write(iP,"(/'A VAnext   :',:,20i3,'  :pre-morph')")     VAnext(   1:VtotL)
     write(iP,"('     ""     :',:,20(2x,a1))") (char(Asymbol(VAnext(   1:VtotL))))

     write(iP,"(/'n nVAprev  :',:,20i3,'  :morph')")         nVAprev(  1:VtotL)
     write(iP,"(/'A VAnextmod:',:,20i3,'  :post-morphed')")VAnextmod(1:VtotL)
     write(iP,"('     ""     :',:,20(2x,a1))") (char(Asymbol(VAnextmod(1:VtotL))))

     write(iP,"(/'A VAnew    :',:,20i3 ,'  :concatenation')")VAnewL(   1:VtotL)
     write(iP,"('     ""     :',:,20(2x,a1))") (char(Asymbol(VAnewL(   1:VtotL))))
   endif!(iP>5)

   VAnew(1:VtotL) = VanewL(1:VtotL)
End Subroutine Concatenate
!---------------------------------------------------------------------------7 9

Subroutine AllMoves(VtotL,VAout,VAprevin,nCin,iP)
!2024.12.22.2130cst JMS-
!For nCin>0: Adds      / Appends   moves to the  left end of VAprevin
!              VAout(1:VtotL) <- VA(nCin)          <- VAprevin(1:VtotL) 
!For nCin<0: Subtracts / Removes moves from the right end of VAprevin
!              VAout(1:VtotL) <- VAprevin(1:VtotL) <- VA(inverse of +nCin)
!The first implementation uses concatenation.

!--Globals
 use MS1Def   ,only: Ur,Us,Ut
 use MS2RCDef ,only: Asymbol,Csymbol  
!--End Globals
 implicit none
 !--Arguments
  integer(4)::VtotL
  integer(4)::VAout(20) !votes- out  [1:VtotL] 
  integer(4)::VAprevin(20) !     - in
  integer(4)::nCin              !move choice- [-18,18]
  integer(4)::iP                !Write enable>5: write(iP,...)
 !--Internals
  integer(4)::Init,nC
  integer(4)::VAll(20,-18:18)
  integer(4)::nCinv(0:19)=(/0,2,1,4,3,6,5,8,7,10,9,12,11,13,14,15,16,17,18,19/)
  integer(4)::VAprev(20)

  !--EndDefs-----------------------------------------------

   if(Init==0) then    
     if(iP>5) write(iP,"(/'AllMoves():    Concat@L134'/)")
      !Positive nC's add moves to the left/scramble side of VAprev:         
       VAll(1:20, 0) = & !"aaaaaaaaaaaaaaaaaaaa ", 0
         (/ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1/)          
       VAll(1:20, 1) = & !"babababaabaababaabaa ", 1
         (/ 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1/)
       VAll(1:20, 2) = & !"cacacacaacaacacaacaa ", 2
         (/ 3, 1, 3, 1, 3, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 1, 1, 3, 1, 1/)
       VAll(1:20, 3) = & !"ababababaabaababaaba ", 3
         (/ 1, 2, 1, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 2, 1/)
       VAll(1:20, 4) = & !"acacacacaacaacacaaca ", 4
         (/ 1, 3, 1, 3, 1, 3, 1, 3, 1, 1, 3, 1, 1, 3, 1, 3, 1, 1, 3, 1/)          
       VAll(1:20, 5) = & !"ddaaddaadaaaddaadaaa ", 5
         (/ 4, 4, 1, 1, 4, 4, 1, 1, 4, 1, 1, 1, 4, 4, 1, 1, 4, 1, 1, 1/)          
       VAll(1:20, 6) = & !"eeaaeeaaeaaaeeaaeaaa ", 6
         (/ 5, 5, 1, 1, 5, 5, 1, 1, 5, 1, 1, 1, 5, 5, 1, 1, 5, 1, 1, 1/)          
       VAll(1:20, 7) = & !"aaddaaddaaadaaddaaad ", 7
         (/ 1, 1, 4, 4, 1, 1, 4, 4, 1, 1, 1, 4, 1, 1, 4, 4, 1, 1, 1, 4/)          
       VAll(1:20, 8) = & !"aaeeaaeeaaaeaaeeaaae ", 8
         (/ 1, 1, 5, 5, 1, 1, 5, 5, 1, 1, 1, 5, 1, 1, 5, 5, 1, 1, 1, 5/)          
       VAll(1:20, 9) = & !"ffffaaaaffffaaaaaaaa ", 9
         (/ 6, 6, 6, 6, 1, 1, 1, 1, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1/)
       VAll(1:20,10) = & !"ggggaaaaggggaaaaaaaa ",10
         (/ 7, 7, 7, 7, 1, 1, 1, 1, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1/)
       VAll(1:20,11) = & !"aaaaffffaaaaaaaaffff ",11
         (/ 1, 1, 1, 1, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1, 1, 1, 6, 6, 6, 6/)
       VAll(1:20,12) = & !"aaaaggggaaaaaaaagggg ",12", _
         (/ 1, 1, 1, 1, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7/)
       VAll(1:20,13) = & !"hahahahaahaahahaahaa ",13
         (/ 8, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 1, 8, 1, 8, 1, 1, 8, 1, 1/)
       VAll(1:20,14) = & !"ahahahahaahaahahaaha ",14
         (/ 1, 8, 1, 8, 1, 8, 1, 8, 1, 1, 8, 1, 1, 8, 1, 8, 1, 1, 8, 1/)
       VAll(1:20,15) = & !"iiaaiiaaiaaaiiaaiaaa ",15
         (/ 9, 9, 1, 1, 9, 9, 1, 1, 9, 1, 1, 1, 9, 9, 1, 1, 9, 1, 1, 1/)
       VAll(1:20,16) = & !"aaiiaaiiaaaiaaiiaaai ",16
         (/ 1, 1, 9, 9, 1, 1, 9, 9, 1, 1, 1, 9, 1, 1, 9, 9, 1, 1, 1, 9/)
       VAll(1:20,17) = & !"jjjjaaaajjjjaaaaaaaa ",17
         (/10,10,10,10, 1, 1, 1, 1,10,10,10,10, 1, 1, 1, 1, 1, 1, 1, 1/)
       VAll(1:20,18) = & !"aaaajjjjaaaaaaaajjjj ",18
         (/ 1, 1, 1, 1,10,10,10,10, 1, 1, 1, 1, 1, 1, 1, 1,10,10,10,10/)
      !Nagative nC's undo moves from the right/solved side of VAprev:         
       do nC = 1,18
         VAll(1:20,-nC) = VAll(1:20,nCinv(nC))
       enddo
       if(iP>5) then
         do nC = -18,18
           if(nC==-18) write(iP,"(/'Undo moves from the right/solved side:')")
           if(nC< 0) write(iP,"('-',a1,2x,20a1)") &
             char(Csymbol(abs(nC))), char(Asymbol(VAll(1:20,nC)))

           if(nC==  0) write(iP,"(/'No change:   VAout=VAprevin')")
           if(nC==0) write(iP,"(' ',a1,2x,20a1)") &
             char(Csymbol(abs(nC))), char(Asymbol(VAll(1:20,nC)))

           if(nC==  1) write(iP,"(/'Add moves to the  left/scrambled side:')")
           if(nC> 0) write(iP,"('+',a1,2x,20a1)") &
             char(Csymbol(abs(nC))), char(Asymbol(VAll(1:20,nC))) 
         enddo!nC       
       endif!(iP>5) 
     Init = 1
   endif!(Init==0)

  !Recurring processing: ----------------------------------
   VAprev          = 0
   VAprev(1:VtotL) = VAprevIn(1:VtotL)

   select case(nCin)
    case(:-19,19:) !nCin out of range
     stop "Concat@L204  Allmoves: nCin out of range. Halt"

    case( -18:-1) !Undo moves from the right/solved side:'
     call Concatenate(VtotL,VAout,VAprev,VAll(1,nCin), 0)

    case(    0  ) !No change:   VAout=VAprevin
     call Concatenate(VtotL,VAout,VAll(1,nCin),VAprev, 0) 

    case(   1:18) !Add moves to the  left/scrambled side: 
     call Concatenate(VtotL,VAout,VAll(1,nCin),VAprev, 0)
   end select!(nCin)
   if(iP>5) write(iP,"( i2,2x,:,20(2x,a1))") nCin,char(Asymbol(VAout(1:VtotL)))
                                                                          return
End Subroutine AllMoves
!--------------------------------------
!AllMoves():    Concat@223
!Undo moves from the right/solved side:
!-I  aaaajjjjaaaaaaaajjjj
!-H  aaaajjjjaaaaaaaajjjj
!-G  aaiiaaiiaaaiaaiiaaai
!-F  iiaaiiaaiaaaiiaaiaaa
!-E  ahahahahaahaahahaaha
!-D  hahahahaahaahahaahaa
!-C  aaaaffffaaaaaaaaffff
!-B  aaaaggggaaaaaaaagggg
!-A  ffffaaaaffffaaaaaaaa
!-9  ggggaaaaggggaaaaaaaa
!-8  aaddaaddaaadaaddaaad
!-7  aaeeaaeeaaaeaaeeaaae
!-6  ddaaddaadaaaddaadaaa
!-5  eeaaeeaaeaaaeeaaeaaa
!-4  ababababaabaababaaba
!-3  acacacacaacaacacaaca
!-2  babababaabaababaabaa
!-1  ababababaabaababaaba!
!No change:   VAout=VAprevin
! 0  aaaaaaaaaaaaaaaaaaaa
!Add moves to the  left/scrambled side:
!+1  babababaabaababaabaa
!+2  ababababaabaababaaba
!+3  ababababaabaababaaba
!+4  acacacacaacaacacaaca
!+5  ddaaddaadaaaddaadaaa
!+6  eeaaeeaaeaaaeeaaeaaa
!+7  aaddaaddaaadaaddaaad
!+8  aaeeaaeeaaaeaaeeaaae
!+9  ffffaaaaffffaaaaaaaa
!+A  ggggaaaaggggaaaaaaaa
!+B  aaaaffffaaaaaaaaffff
!+C  aaaaggggaaaaaaaagggg
!+D  hahahahaahaahahaahaa
!+E  ahahahahaahaahahaaha
!+F  iiaaiiaaiaaaiiaaiaaa
!+G  aaiiaaiiaaaiaaiiaaai
!+H  jjjjaaaajjjjaaaaaaaa
!+I  aaaajjjjaaaaaaaajjjj
 !---------------------------------------------------------------------------7 9

Subroutine ComputeOrder(VtotL,VAin,nOrder,iP)
!2025.01.17.1745cst JMS- Computes the order of scramble VAin(20)
!Testcase:
! Ein%cVAtest     = "tdtfbdkadtffbdkadbaa"
! Ein%VA(1: 8)    = 20, 4,20, 6, 2, 4,11, 1,
! Ein%VA(9:20)    =  4,20, 6, 6, 2, 4,11, 1, 4, 2, 1, 1,
!                   "aiaqwlsaiaqjhisalwaa"   !:self-concat  visually confirmed.

!--Globals
 use MS1Def   ,only: Ur,Us,Ut
 use MS2RCDef ,only: Asymbol,Ztot,Z,EinW,cZrFilename,iDiscord !,nOrder    
!--End Globals
 implicit none
 !--Arguments
  integer(4)::VtotL

  integer(4)::VAin(27)!    The votes  [1:VtotL] 
  integer(4)::nOrder(0:9)
  integer(4)::iP      !Write enable>5: write(iP,...)
 !--Internals
  integer(4)::VAroot(27)
  integer(4)::nOrd(0:9),VAorder(27),VAnext(27)
  integer(4)::nV,iZ,nZ

  !--EndDefs-----------------------------------------------
   if(iP>5) write(iP,"(/'ComputeOrder:    Concat@L297'/)")
   VAroot          =   0
   VAroot(1:VtotL) = VAin(1:VtotL)
   VAorder         =   0
   VAorder         = VAroot
   nOrd            = (/ 1,0,0,0,0,0,0,0,0,0 /)

10 continue
   do iZ = 1,Ztot; nZ = Z(iZ)
     if(nOrd(nZ)==0) then
       do nV = 1,EinW(nZ)%Vtot
         if(VAorder(EinW(nZ)%V(nV))/=1) goto 22
       enddo!nV
       nOrd(nZ) = nOrd(0)
     endif!(nOrd(nZ)==0)
22   continue
   enddo!nZ

  !if(nOrd(0)>5) goto 30
   do iZ = 1,Ztot; nZ = Z(iZ)
     if(nOrd(nZ)==0) goto 40
   enddo!nV
   if(iP>5) write(iP,"(10i5,2x,:,20a1)") nOrd, char(Asymbol(VAorder(1:VtotL)))
   call SaveOutFile
30 nOrder =     nOrd                                                    ;return

40 if(iP>5) write(iP,"(10i5,2x,:,20a1)") nOrd, char(Asymbol(VAorder(1:VtotL)))
   call Concatenate(VtotL,VAorder,VAroot,VAorder, 0)

   nOrd(0) = nOrd(0) + 1
   if(nOrd(0)>2000) stop'Computed order exceeded 2000.  Stopping.' 
   goto 10
End Subroutine ComputeOrder
!---------------------------------------------------------------------------7 9

