Plánujeme nové API pro (nový) Treex.
Mělo by jít implementovat ve více jazycích, sami bychom chtěli implementovat asi Perl, Python, Java, C++.
Implementační poznámky jsou zde api-implementation
ref attributes:
scalar: a/lex.rf, src/tnode
list: a/aux.rf, , coref/*, align/*
get_attr
set_attr
get_bundle → bundle
remove
get_referencing_nodes
create_child
get_parent → parent
set_parent (defaultně kontroluje, aby nevznikl cyklus)
get_children
precedes($another_node)
get_next_node → next_node()
get_prev_node → prev_node()
shift_after_node($reference_node, {without_children⇒1})
shift_after_subtree($reference_node, {without_children⇒1})
shift_before_node($reference_node, {without_children⇒1})
shift_before_subtree($reference_node, {without_children⇒1})
is_nonprojective($reference_node, {without_children⇒1})
sentence – vrátí string věty, smí se volat pouze na technickém kořenu
set_sentence
language
selector
get_document
get_root
is_root
is_leaf
get_descendants → descendants
get_siblings → siblings
get_left_neighbor → prev_sibling
get_right_neighbor → next_sibling
is_descendant_of
get_depth → depth
get_address → address
[sg]et_deref_attr – budeme ukládat rovnou reference na uzel, nikoli ID
get_zone – zony zrusime
remove_reference – interní pro mazání uzlů
fix_pml_type
get_pml_type_name
get_layer
dominates
generate_new_id
following
get_attrs
add_to_listattr – nepoužívá se
to_string
equals
get_aligned_nodes
get_aligned_nodes_by_tree
get_aligned_nodes_of_type
is_aligned_to
delete_aligned_node
add_aligned_node
update_aligned_nodes
get_children()
i get_descendants()
vrací pole, které se ale musí vždy znovu alokovat (je tedy mutable, ale změny tohoto pole neovlivní původní strom). To je z hlediska rychlosti neoptimální, lepší by bylo vracet iterable objekt, jak je Javě (collection) a Pythonu zvykem.list(node.children())
). Výhodou Javy a Pythonu (oproti Perlu) je, že jde iterovat for cyklem i přes collection/iterátor (a v Pythonu je ještě efektivnější list comprehension, protože to jede celé rychlostí céčkového kódu).children
či siblings
si to lze představit, v případě descendants
ne, protože není jasné, kam ten nový uzel zavěsit).descendants()
vytvořit nové pole (aby se setřídilo perlsortem/timsortem inplace, kvůli neprojektivitám, viz dále). To pole sice je taky iterable (a lze z něj snadno vyrobit iterátor), ale když uživatel zavolá potomci = list(node.descendants())
, tak naopak vytvoří zbytečnou kopii (protože v této implementaci už node.descendants()
vrací nové pole).potomci = node.descendants
.potomci = node.descendants()
.get_children({ordered⇒1})
. To je dost nešikovné, protože na to člověk často zapomene, na většině vět to funguje (pořadí dle vložení se většinou shoduje se slovosledným), ale pak ne a těžko se to debugguje.get_descendants
a 405 z nich je ordered
(jak často se které volání používá teď neberu v potaz). Navíc 455 bloků používá process_[at]node
, která vyžaduje get_descendants({ordered⇒1})
. U get_children
je to ordered/vše=95/598 a u get_siblings
2/46. Závěr: setřídění uzlů je potřeba velmi často (byť někde mohlo být to ordered přidáno preventivně a vlastně to potřeba není, viz předchozí bod).shift_(before|after)_(node|subtree)
. Část z toho je volání hned po přidání nového uzlu. Změna slovosledu je tedy častá. Mám ale pocit, že v typickém scénáři (t-analýza, překlad) se mění slovosled mnohem méně často, než jak často se přistupuje k setříděným dětem/potomkům (chtělo by to profiling pro přesná čísla).children
a siblings
by rozumná implementace měla udržovat seznam pořád setříděný (teď se pokaždé volá sort
), takže by parametr ordered
mohl z API zmizet.descendants
je situace složitější, protože u neprojektivních stromů nejde správné pořadí potomků získat průchodem do hloubky. Viz poznámky k implementaci setřídění.