- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I get a puzzling error message at line #54.
It says: error #6366: The shapes of the array expressions do not conform. [MOVEOK]
I had to use an IF statement to get around this. Apparently it does not like .AND. .NOT.
in the logical expression, but that conforms with Fortran standards, doesn't it?
Here is the source code:
subroutine appmove2(level,movno)
implicit NONE
integer*2 level,irow,icol,idig,irow2,icol2,idig2,isq,isq2,&
nmove,imove,i,j,movno,nrej,nmove2,nrej2,kk
integer*1 b(9,9),b2(9,9),levelp1,getsqno,deadsq(9,9),ndeadsq,&
ii,jj,b2s(9,9),moves2(3,300)
character*3 reason/" "/
logical*1 same_row,same_col,same_digit,same_3x3,same_1x1,check_board,&
reject(300),moveok,cused(9,9),rused(9,9),sused(9,9),&
board_ok,dbg/.false./,same_move
include "sud004.cmn"
include "sud006.cmn"
include "sud008.cmn"
! copy to scratch board
print *,"* * * App move: level=",level
irow=moves(1,movno,level)
icol=moves(2,movno,level)
idig=moves(3,movno,level)
call kopyb(brec(level).b,b)
call kopyb(brec(level).b,b2)
if(b(irow,icol).ne.0)then
pause "square is not emply"
endif
! fill the square
b(irow,icol)=idig
board_ok=check_board(b)
if(.not.board_ok)then
pause "board 1 not OK"
endif
b2(irow,icol)=idig
! Sq no of incoming move
isq=getsqno(irow,icol)
print *,nomoves(level)," incoming moves"
print 115,irow,icol,isq,idig
115 format("inc move row",i2," col",i2," squ",i2," digit",i2)
! examine each move, see if it fits
nmove=0;nrej=0
levelp1=level+1
do 10 imove=1,nomoves(level)
idig2=moves(3,imove,level)
irow2=moves(1,imove,level)
icol2=moves(2,imove,level)
isq2=getsqno(irow2,icol2)
same_move=moveno(level).eq.movno
same_row=irow.eq.irow2
same_col=icol.eq.icol2
same_digit=idig.eq.idig2
same_3x3=isq.eq.isq2
same_1x1=same_row.and.same_col
moveok =.not. same_move
reject=same_digit.and.same_row .or. &
same_digit.and.same_col .or. &
same_digit.and.same_3x3
moveok = moveok .and. .not. reject
if( moveok )then
nmove=nmove+1
moves(1,nmove,levelp1)=irow2
moves(2,nmove,levelp1)=icol2
moves(3,nmove,levelp1)=idig2
if(dbg)then
print 111,"mov acc:",imove,irow2,icol2,idig2
111 format(A,i3,":",4i2)
endif
else
! move rejected
if(dbg)then
print 112,"mov rej:",imove,irow2,icol2,idig2
print *,"same_row=",same_row
print *,"same col=",same_col
print *,"same_digit=",same_digit
print *,"same_1x1=",same_1x1
print *,"same_3x3=",same_3x3
endif
nrej=nrej+1
endif
112 format(a,4i2)
10 end do
if(nmove+nrej.ne.nomoves(level))then
print *,nmove,nrej,nomoves(level)
pause "no moves not consistent"
endif
! now do it another way
nmove2=0;nrej2=0
call kopyb(b2,b2s)
do 25 imove=1,nomoves(level)
! always skip the incoming move
if(imove.eq.movno)cycle
irow2=moves(1,imove,level)
icol2=moves(2,imove,level)
idig2=moves(3,imove,level)
isq2=getsqno(irow2,icol2)
call kopyb(b2s,b2)
b2(irow2,icol2)=idig2
board_ok=check_board(b2)
if(board_ok)then
nmove2=nmove2+1
moves2(1,nmove2)=irow2
moves2(2,nmove2)=icol2
moves2(3,nmove2)=idig2
else
nrej2=nrej2+1
print *,"method2 rej: imove=",imove
endif
25 end do
if(nmove.ne.nmove2)then
print *,"# of input moves:",nomoves(level)
print *,"accepted:",nmove,nmove2
print *,"rejected:",nrej,nrej2
do 80 imove=1,nomoves(level)
print 116,imove,&
(moves(kk,imove,level),kk=1,3),&
(moves(kk,imove,levelp1),kk=1,3),&
(moves2(kk,imove),kk=1,3)
116 format("move",I5,":",3I2,",",3I2,",",3I2)
80 enddo
pause "two methods dont agree"
end if
nomoves(levelp1)=nmove
print *,nmove," moves copied out"
! copy the modified board back
call kopyb(b,brec(levelp1).b)
end subroutine
******************************************************************************
BTW, how do I make the TAB indent just 2 xcolumns instead of the default 4 columns?
It says: error #6366: The shapes of the array expressions do not conform. [MOVEOK]
I had to use an IF statement to get around this. Apparently it does not like .AND. .NOT.
in the logical expression, but that conforms with Fortran standards, doesn't it?
Here is the source code:
subroutine appmove2(level,movno)
implicit NONE
integer*2 level,irow,icol,idig,irow2,icol2,idig2,isq,isq2,&
nmove,imove,i,j,movno,nrej,nmove2,nrej2,kk
integer*1 b(9,9),b2(9,9),levelp1,getsqno,deadsq(9,9),ndeadsq,&
ii,jj,b2s(9,9),moves2(3,300)
character*3 reason/" "/
logical*1 same_row,same_col,same_digit,same_3x3,same_1x1,check_board,&
reject(300),moveok,cused(9,9),rused(9,9),sused(9,9),&
board_ok,dbg/.false./,same_move
include "sud004.cmn"
include "sud006.cmn"
include "sud008.cmn"
! copy to scratch board
print *,"* * * App move: level=",level
irow=moves(1,movno,level)
icol=moves(2,movno,level)
idig=moves(3,movno,level)
call kopyb(brec(level).b,b)
call kopyb(brec(level).b,b2)
if(b(irow,icol).ne.0)then
pause "square is not emply"
endif
! fill the square
b(irow,icol)=idig
board_ok=check_board(b)
if(.not.board_ok)then
pause "board 1 not OK"
endif
b2(irow,icol)=idig
! Sq no of incoming move
isq=getsqno(irow,icol)
print *,nomoves(level)," incoming moves"
print 115,irow,icol,isq,idig
115 format("inc move row",i2," col",i2," squ",i2," digit",i2)
! examine each move, see if it fits
nmove=0;nrej=0
levelp1=level+1
do 10 imove=1,nomoves(level)
idig2=moves(3,imove,level)
irow2=moves(1,imove,level)
icol2=moves(2,imove,level)
isq2=getsqno(irow2,icol2)
same_move=moveno(level).eq.movno
same_row=irow.eq.irow2
same_col=icol.eq.icol2
same_digit=idig.eq.idig2
same_3x3=isq.eq.isq2
same_1x1=same_row.and.same_col
moveok =.not. same_move
reject=same_digit.and.same_row .or. &
same_digit.and.same_col .or. &
same_digit.and.same_3x3
moveok = moveok .and. .not. reject
if( moveok )then
nmove=nmove+1
moves(1,nmove,levelp1)=irow2
moves(2,nmove,levelp1)=icol2
moves(3,nmove,levelp1)=idig2
if(dbg)then
print 111,"mov acc:",imove,irow2,icol2,idig2
111 format(A,i3,":",4i2)
endif
else
! move rejected
if(dbg)then
print 112,"mov rej:",imove,irow2,icol2,idig2
print *,"same_row=",same_row
print *,"same col=",same_col
print *,"same_digit=",same_digit
print *,"same_1x1=",same_1x1
print *,"same_3x3=",same_3x3
endif
nrej=nrej+1
endif
112 format(a,4i2)
10 end do
if(nmove+nrej.ne.nomoves(level))then
print *,nmove,nrej,nomoves(level)
pause "no moves not consistent"
endif
! now do it another way
nmove2=0;nrej2=0
call kopyb(b2,b2s)
do 25 imove=1,nomoves(level)
! always skip the incoming move
if(imove.eq.movno)cycle
irow2=moves(1,imove,level)
icol2=moves(2,imove,level)
idig2=moves(3,imove,level)
isq2=getsqno(irow2,icol2)
call kopyb(b2s,b2)
b2(irow2,icol2)=idig2
board_ok=check_board(b2)
if(board_ok)then
nmove2=nmove2+1
moves2(1,nmove2)=irow2
moves2(2,nmove2)=icol2
moves2(3,nmove2)=idig2
else
nrej2=nrej2+1
print *,"method2 rej: imove=",imove
endif
25 end do
if(nmove.ne.nmove2)then
print *,"# of input moves:",nomoves(level)
print *,"accepted:",nmove,nmove2
print *,"rejected:",nrej,nrej2
do 80 imove=1,nomoves(level)
print 116,imove,&
(moves(kk,imove,level),kk=1,3),&
(moves(kk,imove,levelp1),kk=1,3),&
(moves2(kk,imove),kk=1,3)
116 format("move",I5,":",3I2,",",3I2,",",3I2)
80 enddo
pause "two methods dont agree"
end if
nomoves(levelp1)=nmove
print *,nmove," moves copied out"
! copy the modified board back
call kopyb(b,brec(levelp1).b)
end subroutine
******************************************************************************
BTW, how do I make the TAB indent just 2 xcolumns instead of the default 4 columns?
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes and yes - this was in Fortran 90. If you have an expression where one operand is a scalar and the other is an array, the scalar is "promoted" to an array with the same shape as the other operand, and the value replicated. Yes, you can do operations on whole arrays as long as the shapes match. So your C=A+B is sort of equivalent to using a DO loop. The "sort of" is that the semantics are that the right-side is COMPLETELY evaluated before anything on the left is changed. So really, C=A+B is equivalent to:
temp = A+B
C = temp
The compiler tries hard to eliminate the temp, but doesn't always.
I will caution also that Intel Fortran does not do "shape checking", so if you have two arrays with bounds that are not known at compile-time (allocatable, for example), the compiler doesn't check to make sure the shapes match. If they don't, you can get bizarre errors.
temp = A+B
C = temp
The compiler tries hard to eliminate the temp, but doesn't always.
I will caution also that Intel Fortran does not do "shape checking", so if you have two arrays with bounds that are not known at compile-time (allocatable, for example), the compiler doesn't check to make sure the shapes match. If they don't, you can get bizarre errors.
Link Copied
3 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The statement I think is the issue (without the include files I can't completely compile this source) is:
moveok = moveok .and. .not. reject
moveok is a LOGICAL scalar but reject is a logical array of dimension (300). The expression gets converted to an array of dimension 300 with the .and. .not. operation applied to each element of reject. This is not assignment compatible with the scalar moveok.
Did you really intend reject to be an array? I think some of your other usages have possibly surprising effects because of this.
As for tabs, this is Tools > Options > Text Editor > Fortran > Tabs
moveok = moveok .and. .not. reject
moveok is a LOGICAL scalar but reject is a logical array of dimension (300). The expression gets converted to an array of dimension 300 with the .and. .not. operation applied to each element of reject. This is not assignment compatible with the scalar moveok.
Did you really intend reject to be an array? I think some of your other usages have possibly surprising effects because of this.
As for tabs, this is Tools > Options > Text Editor > Fortran > Tabs
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Quoting - Steve Lionel (Intel)
The statement I think is the issue (without the include files I can't completely compile this source) is:
moveok = moveok .and. .not. reject
moveok is a LOGICAL scalar but reject is a logical array of dimension (300). The expression gets converted to an array of dimension 300 with the .and. .not. operation applied to each element of reject. This is not assignment compatible with the scalar moveok.
Did you really intend reject to be an array? I think some of your other usages have possibly surprising effects because of this.
As for tabs, this is Tools > Options > Text Editor > Fortran > Tabs
moveok = moveok .and. .not. reject
moveok is a LOGICAL scalar but reject is a logical array of dimension (300). The expression gets converted to an array of dimension 300 with the .and. .not. operation applied to each element of reject. This is not assignment compatible with the scalar moveok.
Did you really intend reject to be an array? I think some of your other usages have possibly surprising effects because of this.
As for tabs, this is Tools > Options > Text Editor > Fortran > Tabs
Thanks for your response.
I think what confused me is that it mentions MOVEOK, which is NOT an array, but of course REJECT is.
I didn't know Fortran allows a mulitple assignment like that.
So if A, B, and C are logical arrays, and I say
C = A .or. B
it will actually do an element by element logical operation without requiring a DO loop? Was that in a revised standard anywhere? Of course they would have to be the same size....
What if A, B, and C are integer arrays, and I say:
C = A + B
will it then do an element by element addition without a DO loop?
I guess I could experiment, but I must confess, this is a new one on me - - -
Yours; Bill
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes and yes - this was in Fortran 90. If you have an expression where one operand is a scalar and the other is an array, the scalar is "promoted" to an array with the same shape as the other operand, and the value replicated. Yes, you can do operations on whole arrays as long as the shapes match. So your C=A+B is sort of equivalent to using a DO loop. The "sort of" is that the semantics are that the right-side is COMPLETELY evaluated before anything on the left is changed. So really, C=A+B is equivalent to:
temp = A+B
C = temp
The compiler tries hard to eliminate the temp, but doesn't always.
I will caution also that Intel Fortran does not do "shape checking", so if you have two arrays with bounds that are not known at compile-time (allocatable, for example), the compiler doesn't check to make sure the shapes match. If they don't, you can get bizarre errors.
temp = A+B
C = temp
The compiler tries hard to eliminate the temp, but doesn't always.
I will caution also that Intel Fortran does not do "shape checking", so if you have two arrays with bounds that are not known at compile-time (allocatable, for example), the compiler doesn't check to make sure the shapes match. If they don't, you can get bizarre errors.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page