LINUX.ORG.RU

История изменений

Исправление runtime, (текущая версия) :

Вдогонку, построение базы данных узлов и связей между ними в памяти, чтобы каждый раз не лазить вглубь дерева. Выдёргивалось кусками из существующего кода, поэтому работоспособность из коробки не гарантирую. Если что - дай знать, помогу.

/****************************
 Building DB
****************************/

:- dynamic node/4. % node(id, name, attributes, value)
:- dynamic link/2. % link(id, parent_id)

clear_db :-
	abolish(node/4),
	abolish(link/2).

build_db(DOM) :-
	build_db_aux(DOM, [-1], 0).

build_db_aux([], [], _).
build_db_aux(Elements, ParentIds, Id) :-
	% add current element to DB, generate new id
	Elements = [Element|Es],
	ParentIds = [Parent|Ps],
	add_to_db(Id, Element, Parent),
	% get children, set current id as their parent
	get_children(Element, Children),
	length(Children, ChildCount),
	length(ChildParentIds, ChildCount),
	maplist('='(Id), ChildParentIds),
	% process remaining elements
	Id2 is Id+1,
	append(Children, Es, Elements2),
	append(ChildParentIds, Ps, ParentIds2),
	build_db_aux(Elements2, ParentIds2, Id2).

add_to_db(Id, Elem, Parent) :-
	assert(link(Id, Parent)),
	(is_element(Elem) ->
		get_name(Elem, Name),
		get_attributes(Elem, Attributes),
		assert(node(Id, Name, Attributes, []))
		;
		Value = Elem, % Elem itself represents node contents
		assert(node(Id, [], [], Value))
	).

/****************************
 Node operations
****************************/

is_parent_of(Parent, Child) :-
	Parent = element(_, _, Children),
	member(Child, Children).

is_element(E) :-
	E =.. [element|_].

get_attribute(E, Name, Value) :-
	E = element(_, Attrs, _),
	member(Name=Value, Attrs).

get_name(E, Name) :-
	E = element(Name, _, _).

get_attributes(E, Attributes) :-
	E = element(_, Attributes, _).

get_children(E, Children) :-
	E = element(_, _, Children).
get_children(_, []) :- !.

Исходная версия runtime, :

Вдогонку, построение базы данных узлов и связей между ними в памяти, чтобы каждый раз не лазить вглубь дерева. Выдёргивалось кусками из существующего кода, поэтому работоспособность из коробки не гарантирую. Если что - дай знать, помогу.

/****************************
 Building DB
****************************/

:- dynamic node/4. % node(id, name, attributes, value)
:- dynamic link/2. % link(id, parent_id)

clear_db :-
	abolish(node/4),
	abolish(link/2).

build_db(DOM) :-
	build_db_aux(DOM, [-1], 0).

build_db_aux([], [], _).
build_db_aux(Elements, ParentIds, Id) :-
	% add current element to DB, generate new id
	Elements = [Element|Es],
	ParentIds = [Parent|Ps],
	add_to_db(Id, Element, Parent),
	% get children, set current id as their parent
	get_children(Element, Children),
	length(Children, ChildCount),
	length(ChildParentIds, ChildCount),
	maplist('='(Id), ChildParentIds),
	% process remaining elements
	Id2 is Id+1,
	append(Children, Es, Elements2),
	append(ChildParentIds, Ps, ParentIds2),
	build_db_aux(Elements2, ParentIds2, Id2).

add_to_db(Id, Elem, Parent) :-
	assert(link(Id, Parent)),
	%save_predicate(link(Id, Parent)),
	(is_element(Elem) ->
		get_name(Elem, Name),
		get_attributes(Elem, Attributes),
		%save_predicate(node(Id, Name, Attributes, _)),
		assert(node(Id, Name, Attributes, []))
		;
		Value = Elem, % Elem itself represents node contents
		assert(node(Id, [], [], Value))
	).

/****************************
 Node operations
****************************/

is_parent_of(Parent, Child) :-
	Parent = element(_, _, Children),
	member(Child, Children).

is_element(E) :-
	E =.. [element|_].

get_attribute(E, Name, Value) :-
	E = element(_, Attrs, _),
	member(Name=Value, Attrs).

get_name(E, Name) :-
	E = element(Name, _, _).

get_attributes(E, Attributes) :-
	E = element(_, Attributes, _).

get_children(E, Children) :-
	E = element(_, _, Children).
get_children(_, []) :- !.