From 77666a09c0f82b231605da463a946a5a5fcd09b6 Mon Sep 17 00:00:00 2001 From: Patrick Simianer Date: Tue, 24 Feb 2026 17:07:57 +0100 Subject: Fix reordering bug in derive and add test example derive used a sequential counter to index into the source-side NT map, which only worked for monotone rules. Now looks up tails by the target NT's own index via map.index(i.index). Adds toy-reorder example (German verb-final -> English SVO) to exercise the fix. Also updates trollop -> optimist and guards xmlsimple require. Co-Authored-By: Claude Opus 4.6 --- prototype/hypergraph.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'prototype/hypergraph.rb') diff --git a/prototype/hypergraph.rb b/prototype/hypergraph.rb index fd72393..fdaba5a 100644 --- a/prototype/hypergraph.rb +++ b/prototype/hypergraph.rb @@ -196,11 +196,9 @@ def HG::derive path, cur, carry edge = path.select { |e| e.head.symbol==cur.symbol \ && e.head.left==cur.left \ && e.head.right==cur.right }.first - j = 0 edge.rule.target.each { |i| if i.class == Grammar::NT - derive path, edge.tails[edge.rule.map[j]], carry - j += 1 + derive path, edge.tails[edge.rule.map.index(i.index)], carry else carry << i end -- cgit v1.2.3 From e76951f21263eb7010a2898b9744364e989e90b8 Mon Sep 17 00:00:00 2001 From: Patrick Simianer Date: Tue, 24 Feb 2026 17:14:37 +0100 Subject: Deduplicate all_paths by reachable edge set The Cartesian product over all nodes produces duplicate derivations when edges differ only in nodes unreachable from the top. Walk reachable edges from the top edge of each path and drop paths with identical reachable sets. Co-Authored-By: Claude Opus 4.6 --- prototype/hypergraph.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'prototype/hypergraph.rb') diff --git a/prototype/hypergraph.rb b/prototype/hypergraph.rb index fdaba5a..08d1a29 100644 --- a/prototype/hypergraph.rb +++ b/prototype/hypergraph.rb @@ -189,7 +189,21 @@ def HG::all_paths hypergraph, root paths = new_paths } - return paths + seen = Set.new + paths.select { |p| + reachable = Set.new + mark_reachable p, p.last, reachable + key = reachable.map(&:object_id).sort + !seen.include?(key) && seen.add(key) + } +end + +def HG::mark_reachable path, edge, used + used << edge + edge.tails.each { |t| + child = path.find { |e| e.head == t } + mark_reachable path, child, used if child && !used.include?(child) + } end def HG::derive path, cur, carry -- cgit v1.2.3