Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
class(nfa_graph_t), | intent(inout) | :: | self | |||
type(cube_t), | intent(inout) | :: | cube |
pure subroutine nfa_graph__disjoin(self, cube) use :: forgex_priority_queue_m, only : priority_queue_t use :: forgex_segment_m, only: SEG_INIT, segment_t, operator(/=) use :: forgex_segment_disjoin_m, only: disjoin implicit none class(nfa_graph_t), intent(inout) :: self type(cube_t), intent(inout) :: cube type(nfa_transition_t) :: node type(priority_queue_t) :: queue type(nfa_transition_t) :: tra integer :: i, j, k enqueue : block do i = NFA_STATE_BASE, self%top do j = 1, self%graph(i)%forward_top-1 node = self%graph(i)%forward(j) if (node%dst /= NFA_NULL_TRANSITION) then if (allocated(node%c%sps)) then do k = 1, size(node%c%sps, dim=1) if (node%c%sps(k) /= SEG_INIT) then call queue%enqueue(self%graph(i)%forward(j)%c%sps(k)) end if end do end if end if end do end do end block enqueue dequeue: block integer :: m, n type(segment_t) :: cache n = queue%number allocate(cube%sps(n)) m = 0 do j = 1, n if (j == 1) then m = m + 1 call queue%dequeue(cube%sps(j)) cycle end if call queue%dequeue(cache) if (cube%sps(m) /= cache) then m = m + 1 cube%sps(m) = cache end if end do if (m > 0) cube%sps(1:m) = cube%sps(1:m) ! reallocation implicitly end block dequeue call disjoin(cube%sps) if (.not. allocated(cube%sps)) then error stop "ERROR: Array that should have been disjoined is not allocated." end if ! Apply disjoining to all transitions over the NFA graph. do i = NFA_STATE_BASE, self%top if (allocated(self%graph(i)%forward)) then do j = 1, self%graph(i)%forward_top call disjoin_nfa_each_transition(self%graph(i)%forward(j), cube%sps) end do end if end do call queue%clear() end subroutine nfa_graph__disjoin