Language: C++

equire 'set'

class Graph
	def initialize
		@nodes = Set.new
		@edges = Set.new
	end

	def add_node(label = nil)
		Node.new(label)
	end

	def add_edge(u, v)
		e = Edge.new(u, v)
		u.outgoings << e
		v.incomings << e
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.outgoings.delete(e)
		v.incomings.delete(e)
		e
	end

	class Node
		def initialize(label)
			@label = label
			@outgoings = Set.new
			@incomings = Set.new
		end
		
		def to_s
			@label
		end
		attr_accessor :incomings, :outgoings
		attr_reader :label
	end

	class Edge
		def initialize(u, v)
			@from = u	
			@to = v
		end
		attr_reader :from, :to
	end

	def Graph::get_path_bfs(s, t)
		path_edge = {}
		reached = Set[s]
		queue = [s]
		while !queue.empty? 
			u = queue.shift
			u.outgoings.each{|e|
				v = e.to
				next if reached.include?(v)	
				reached << v
				queue << v
				path_edge[v] = e

				if v == t
					path = []
					while e = path_edge[v]
						path.unshift e
						v = e.from
					end
					return path
				end
			}
		end	
		return nil
	end

	def Graph::get_path_dfs(s, t, reached = Set.new)
		reached << s	
		s.outgoings.each{|e|
			v = e.to
			next if reached.include?(v)
			return [e] if v == t
			
			path = get_path_dfs(v, t, reached) 
			return [e] + path if path
		}
		nil
	end

	def make_layer_graph(s, t) #nodes:copy, edges:alias
		lg = Graph.new
		correspond = {}

		path_edge = {}
		reached = Set[s]
		current_queue = [s]

		correspond[s] = lg.add_node

		while 0
			next_queue = []
			while !current_queue.empty? 
				u = current_queue.shift
				u.outgoings.each{|e|
					v = e.to
					next if reached.include?(v)

					correspond[v] ||= lg.add_node 
					correspond[e] = lg.add_edge(correspond[u], correspond[v])

					next_queue << v unless reached.include?(v)	
				}
			end	

			break if next_queue.empty?
			next_queue.each{|v| reached << v}
			current_queue = next_queue
		end

		nil
	end
end

def get_integers
	gets.split(" ").map(&:to_i)
end

loop {
	n, m = get_integers
	break if n == 0

	g = Graph.new

	indent = -1
	stack = []
	name_to_node = {}
	n.times {
		gets =~ /^(\s*)(\w+)$/
		indent = $1.size
		stack.pop until stack.size <= indent
		v = g.add_node($2)
		g.add_edge(stack.last, v) if stack.size > 0
		stack << v
		name_to_node[v.label] = v
	}

	m.times {
		gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
		u = name_to_node[$1]
		relation = $2
		v = name_to_node[$3]
		
		bool = false
		case relation
		when "descendant"
			bool = Graph::get_path_bfs(v, u)
		when "ancestor"
			bool = Graph::get_path_bfs(u, v)
		when "child"
			bool = !u.incomings.empty? && u.incomings.all?{|e| e.from == v}
		when "parent"
			bool = !v.incomings.empty? && v.incomings.all?{|e| e.from == u}
		when "sibling"
			bool = u.incomings == v.incomings
		end
		puts bool ? "True" : "No"
	}
	puts
}

Compiler output:
a.cc:1:8: warning: multi-character character constant [-Wmultichar]
    1 | equire 'set'
      |        ^~~~~
a.cc:5:17: error: stray '@' in program
    5 |                 @nodes = Set.new
      |                 ^
a.cc:6:17: error: stray '@' in program
    6 |                 @edges = Set.new
      |                 ^
a.cc:29:25: error: stray '@' in program
   29 |                         @label = label
      |                         ^
a.cc:30:25: error: stray '@' in program
   30 |                         @outgoings = Set.new
      |                         ^
a.cc:31:25: error: stray '@' in program
   31 |                         @incomings = Set.new
      |                         ^
a.cc:35:25: error: stray '@' in program
   35 |                         @label
      |                         ^
a.cc:43:25: error: stray '@' in program
   43 |                         @from = u
      |                         ^
a.cc:44:25: error: stray '@' in program
   44 |                         @to = v
      |                         ^
a.cc:88:36: error: stray '#' in program
   88 |         def make_layer_graph(s, t) #nodes:copy, edges:alias
      |                                    ^
a.cc:136:28: error: stray '\' in program
  136 |                 gets =~ /^(\s*)(\w+)$/
      |                            ^
a.cc:136:33: error: stray '\' in program
  136 |                 gets =~ /^(\s*)(\w+)$/
      |                                 ^
a.cc:146:28: error: stray '\' in program
  146 |                 gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
      |                            ^
a.cc:146:36: error: stray '\' in program
  146 |                 gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
      |                                    ^
a.cc:146:41: error: stray '\' in program
  146 |                 gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
      |                                         ^
a.cc:146:50: error: stray '\' in program
  146 |                 gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
      |                                                  ^
a.cc:146:54: error: stray '\' in program
  146 |                 gets =~ /^(\w+) is \w+ (\w+) of (\w+)\.$/
      |                                                      ^
a.cc:1:1: error: 'equire' does not name a type
    1 | equire 'set'
      | ^~~~~~
a.cc:51:17: error: 'reached' does not name a type
   51 |                 reached = Set[s]
      |                 ^~~~~~~
a.cc:71:17: error: 'end' does not name a type
   71 |                 end
      |                 ^~~
a.cc:85:17: error: 'nil' does not name a type
   85 |                 nil
      |                 ^~~
a.cc:92:17: error: 'path_edge' does not name a type
   92 |                 path_edge = {}
      |                 ^~~~~~~~~
a.cc:93:17: error: 'reached' does not name a type
   93 |                 reached = Set[s]
      |                 ^~~~~~~
a.cc:111:25: error: 'end' does not name a type
  111 |                         end
      |                         ^~~
a.cc:115:25: error: 'current_queue' does not name a type
  115 |                         current_queue = next_queue
      |                         ^~~~~~~~~~~~~