Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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
Advertisement
Add Comment
Please, Sign In to add comment