Run the solver and return the next solution found (if any).

Return null is one of these is true:

Property definitions

ai $ BacktrackSolver :: run
	# Run the solver and return the next solution found (if any).
	# Return null is one of these is true:
	# * `steps_limit` is reached
	# * no more reachable solution, in this case `is_running` become false.
	fun run: nullable BacktrackNode[A]
	do
		var node = self.node
		# Not yet started, of finished?
		if node == null then
			if steps > 0 then return null
			node = start
			var res = problem.is_goal(state)
			if res then return node
		end

		loop
			if steps_limit > 0 and steps > steps_limit then break
			steps += 1

			var totry = node.totry

			# It is the first visit in this state?
			if totry == null then
				var actions = problem.actions(state, node)
				if actions != null and not actions.is_empty then
					totry = actions.to_a
					node.totry = totry
				end
			end

			#print state
			#print node

			# No remaining actions?
			if totry == null or totry.is_empty then
				#print "Backtrack"
				var a = node.action
				if a == null then
					#print "no more action"
					is_running = false
					self.node = null
					return null
				end

				problem.backtrack(state, a)
				node = node.parent
				assert node != null
				continue
			end

			var a = totry.pop
			problem.apply_action(state, a)
			#print "Play {a or else ""}"
			node = new BacktrackNode[A](node, a, node.depth+1, steps)

			var res = problem.is_goal(state)
			if res then
				self.node = node
				return node
			end
		end
		self.node = node
		return null
	end
lib/ai/backtrack.nit:166,2--229,4