Mgamerz icon

Untitled

Mgamerz | PRO | 05/08/14 03:22:03 PM UTC | 0 ⭐ | 10220 👁️ | Never ⏰ | []
Fortran |

3.15 KB

|

None

|

0 👍

/

0 👎

MODULE the_tape
  INTEGER, ALLOCATABLE :: tape(:), transitions(:, :)
  INTEGER :: left_edge, right_edge, tape_head_position, tape_size
END MODULE
 
MODULE states_and_transitions
  INTEGER :: accept_state, current_state, current_transition, cardinality_alphabet
END MODULE  
 
 
program turing_machine_simulator
 
  USE the_tape
  USE states_and_transitions
 
  INTEGER :: next_, write_, read_  
  CHARACTER ::  move_
 
  CHARACTER(100) :: tape_prototype, arg
 
  INTEGER :: cardinality_Q
 
  external handle_sigint ! Must declare as external
 
  call get_command_argument(1, arg)
 
  OPEN(UNIT = 12, FILE=arg)
  READ(12,*) cardinality_Q
  READ(12,*) cardinality_alphabet
  cardinality_alphabet = cardinality_alphabet + 1
 
  allocate(transitions(3, cardinality_alphabet * cardinality_Q))
  do 1 i=1, cardinality_alphabet * cardinality_Q
    READ(12,*) next_, write_, move_
    transitions(1:3, i) = (/ next_ + 1, write_, merge(1, -1, move_=='R') /)
  1 continue
  
  READ(12, *) tape_prototype
  WRITE(*,*) tape_prototype
  
  CLOSE(12) 
 
  allocate(tape(len(tape_prototype)))
  do 2 i=1, len(tape_prototype)
    tape(i) = IACHAR(tape_prototype(i:i)) - IACHAR('0')
  2 continue
 
  call SIGNAL(2, handle_sigint)
 
  current_state = 1 
  accept_state = cardinality_Q + 1
  tape_head_position = 1
  
  left_edge = 1
  right_edge = len(trim(tape_prototype))
  tape_size = right_edge
  
  call run
 
  call print_tape
  
  deallocate(tape)
  deallocate(transitions)  
end program
 
 
SUBROUTINE run
  USE the_tape
  USE states_and_transitions
 
  INTEGER :: read_ 
  read_ = 0
  current_transition = 1
  
  do while(current_state .NE. accept_state)
 
    if (tape_head_position .LT. left_edge) then 
      left_edge = left_edge - 1
    elseif (tape_head_position .GT. right_edge) then
      right_edge = right_edge + 1
    endif
 
    if (left_edge .LT. 1 .OR. right_edge .GT. tape_size) call grow_tape
    read_ = tape(tape_head_position)
    
    current_transition = ((current_state - 1) * cardinality_alphabet) + 1 + read_ 
    tape(tape_head_position) = transitions(2, current_transition)
    tape_head_position = tape_head_position + transitions(3, current_transition)
    current_state = transitions(1, current_transition)
 
  end do
end SUBROUTINE
 
 
SUBROUTINE print_tape
  USE the_tape
  do 10 i=left_edge, right_edge - 1 !Index by one, and this is inclusive
    WRITE(*,*) tape(i)
  10 continue
  print *, ''
  return
end SUBROUTINE
 
 
SUBROUTINE handle_sigint
  USE the_tape
  print *, 'Received sigint--bailing.'
  call print_tape
  deallocate(tape)
  deallocate(transitions)  
  stop
end SUBROUTINE
 
 
SUBROUTINE grow_tape
  USE the_tape
  INTEGER :: offset
  INTEGER, ALLOCATABLE :: temp(:)
  
  print *, 'Growing every time', tape_size
  offset = tape_size / 2
 
  allocate(temp(tape_size * 2))
 
  temp = 0 !sets everything to zero in the array
  left_edge = left_edge + offset
  right_edge = right_edge + offset
  tape_head_position = tape_head_position + offset
  
  temp(left_edge:right_edge) = tape(1:tape_size)
  tape = temp
  tape_size = tape_size * 2
  deallocate(temp)
  return
end SUBROUTINE

Comments

  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎

    
        
  •  icon
    01/01/70 12:00:00 AM UTC
    Plain Text |

    0 B

    |

    👍

    /

    👎