This site contains older material on Eiffel. For the main Eiffel page, see http://www.eiffel.com.

EiffelBase class
(HTML page generated by ISE Eiffel 4.2)

Eiffel Class
indexing
	description: "Trees, without commitment to a particular representation";
	status: "See notice at end of class";
	names: tree;
	access: cursor, membership;
	representation: recursive;
	contents: generic;
	date: "$Date: 2007-03-30 19:10:11 +0000 (Fri, 30 Mar 2007) $";
	revision: "$Revision: 95354 $"

deferred class TREE [G]

inherit
	CONTAINER [G]

feature -- Access

	parent: TREE [G];
			-- Parent of current node

	child: like parent is
			-- Current child node
		require
			readable: readable_child
		deferred
		end;

	item: G is
			-- Item in current node
		deferred
		end;

	child_item: like item is
			-- Item in current child node
		require
			readable: child_readable
		do
			Result := child.item
		end;

	child_cursor: CURSOR is
			-- Current cursor position
		deferred
		end;

	child_index: INTEGER is
			-- Index of current child
		deferred
		ensure
			valid_index: Result >= 0 and Result <= arity + 1
		end;

	first_child: like parent is
			-- Leftmost child
		require
			is_not_leaf: notis_leaf
		deferred
		end;

	last_child: like first_child is
			-- Right most child
		require
			is_not_leaf: notis_leaf
		deferred
		end;

	left_sibling: like parent is
			-- Left neighbor (if any)
		require
			is_not_root: notis_root
		deferred
		ensure
			is_sibling: is_sibling (Result);
			right_is_current: (Result /= void) implies (Result.right_sibling = Current)
		end;

	right_sibling: like parent is
			-- Right neighbor (if any)
		require
			is_not_root: notis_root
		deferred
		ensure
			is_sibling: is_sibling (Result);
			left_is_current: (Result /= void) implies (Result.left_sibling = Current)
		end;

	has (v: G): BOOLEAN is
			-- Does subtree include v?
			-- (Reference or object equality,
			-- based on object_comparison.)
		do
			if object_comparison then
				Result := (v /= void) and then (item /= void) and then (v.is_equal (item) or else subtree_has (v))
			else
				Result := v = item or else subtree_has (v)
			end
		end;

	is_sibling (other: like parent): BOOLEAN is
			-- Are current node and other siblings?
		do
			Result := notis_root and other.parent = parent
		ensure
			not_root: Result implies notis_root;
			other_not_root: Result implies notother.is_root;
			same_parent: Result = notis_root and other.parent = parent
		end;

feature -- Measurement

	arity: INTEGER is
			-- Number of children
		deferred
		end;

	count: INTEGER is
			-- Number of items
		do
			Result := subtree_count + 1
		end;

feature -- Status report

	Readable: BOOLEAN is true;

	child_readable: BOOLEAN is
			-- Is there a current child_item to be read?
		do
			Result := notchild_off and then (child /= void)
		end;

	readable_child: BOOLEAN is
			-- Is there a current child to be read?
		do
			Result := notchild_off
		end;

	Writable: BOOLEAN is true;
			-- Is there a current item that may be modified?

	child_writable: BOOLEAN is
			-- Is there a current child_item that may be modified?
		do
			Result := notchild_off and then (child /= void)
		end;

	writable_child: BOOLEAN is
			-- Is there a current child that may be modified?
		do
			Result := notchild_off
		end;

	child_off: BOOLEAN is
			-- Is there no current child?
		do
			Result := child_before or child_after
		end;

	child_before: BOOLEAN is
			-- Is there no valid child position to the left of cursor?
		do
			Result := child_index = 0
		end;

	child_after: BOOLEAN is
			-- Is there no valid child position to the right of cursor?
		do
			Result := child_index = arity + 1
		end;

	empty: BOOLEAN is
			-- Is structure empty of items?
		do
			Result := false
		end;

	is_leaf: BOOLEAN is
			-- Are there no children?
		do
			Result := arity = 0
		end;

	is_root: BOOLEAN is
			-- Is there no parent?
		do
			Result := parent = void
		end;

	child_isfirst: BOOLEAN is
			-- Is cursor under first child?
		do
			Result := notis_leaf and child_index = 1
		ensure
			not_is_leaf: Result implies notis_leaf
		end;

	child_islast: BOOLEAN is
			-- Is cursor under last child?
		do
			Result := notis_leaf and child_index = arity
		ensure
			not_is_leaf: Result implies notis_leaf
		end;

	valid_cursor_index (i: INTEGER): BOOLEAN is
			-- Is i correctly bounded for cursor movement?
		do
			Result := (i >= 0) and (i <= arity + 1)
		ensure
			valid_cursor_index_definition: Result = (i >= 0) and (i <= arity + 1)
		end;

feature -- Cursor movement

	child_go_to (p: CURSOR) is
			-- Move cursor to position p.
		deferred
		end;

	child_start is
			-- Move cursor to first child.
		deferred
		ensure
			is_first_child: notis_leaf implies child_isfirst
		end;

	child_finish is
			-- Move cursor to last child.
		deferred
		ensure
			is_last_child: notis_leaf implies child_islast
		end;

	child_forth is
			-- Move cursor to next child.
		deferred
		end;

	child_back is
			-- Move cursor to previous child.
		deferred
		end;

	child_go_i_th (i: INTEGER) is
			-- Move cursor to i-th child.
		require
			valid_cursor_index: valid_cursor_index (i)
		deferred
		ensure
			position: child_index = i;
			is_before: (i = 0) implies child_before;
			is_after: (i = arity + 1) implies child_after
		end;

feature -- Element change

	sprout is
			-- Make current node a root.
		do
			if parent /= void then
				parent.prune (Current)
			end
		end;

	put (v: like item) is
			-- Replace element at cursor position by v.
			-- Was declared in TREE as synonym of put and replace.
		require
			is_writable: writable
		deferred
		ensure
			item_inserted: item = v
		end;

	replace (v: like item) is
			-- Replace element at cursor position by v.
			-- Was declared in TREE as synonym of put and replace.
		require
			is_writable: writable
		deferred
		ensure
			item_inserted: item = v
		end;

	child_put (v: like item) is
			-- Put v at current child position.
			-- Was declared in TREE as synonym of child_put and child_replace.
		require
			child_writable: child_writable
		deferred
		ensure
			item_inserted: child_item = v
		end;

	child_replace (v: like item) is
			-- Put v at current child position.
			-- Was declared in TREE as synonym of child_put and child_replace.
		require
			child_writable: child_writable
		deferred
		ensure
			item_inserted: child_item = v
		end;

	replace_child (n: like parent) is
			-- Put n at current child position.
		require
			writable_child: writable_child;
			was_root: n.is_root
		deferred
		ensure
			child_replaced: child = n
		end;

	prune (n: like parent) is
			-- Remove n from the children
		require
			is_child: n.parent = Current
		deferred
		ensure
			n_is_root: n.is_root
		end;

	fill (other: TREE [G]) is
			-- Fill with as many items of other as possible.
			-- The representations of other and current node
			-- need not be the same.
		do
			replace (other.item);
			fill_subtree (other)
		end;

feature -- Conversion

	linear_representation: LINEAR [G] is
			-- Representation as a linear structure
		local
			al: ARRAYED_LIST [G]
		do
			create al.make (count);
			al.start;
			al.extend (item);
			fill_list (al);
			Result := al
		end;

	binary_representation: BINARY_TREE [G] is
			-- Convert to binary tree representation:
			-- first child becomes left child,
			-- right sibling becomes right child.
		local
			current_sibling: BINARY_TREE [G]
		do
			create Result.make (item);
			if notis_leaf then
				Result.put_left_child (first_child.binary_representation);
				from
					child_start;
					child_forth;
					current_sibling := Result.left_child
				until
					child_after
				loop
					current_sibling.put_right_child (child.binary_representation);
					current_sibling := current_sibling.right_child;
					child_forth
				end
			end
		ensure
			result_is_root: Result.is_root;
			result_has_no_right_child: notResult.has_right
		end;

feature -- Duplication

	duplicate (n: INTEGER): like Current is
			-- Copy of sub-tree beginning at cursor position and
			-- having min (n, arity - child_index + 1)
			-- children.
		require
			not_child_off: notchild_off;
			valid_sublist: n >= 0
		deferred
		end;

feature {TREE} -- Implementation

	subtree_has (v: G): BOOLEAN is
			-- Do children include v?
			-- (Reference or object equality,
			-- based on object_comparison.)
		local
			cursor: CURSOR
		do
			cursor := child_cursor;
			from
				child_start
			until
				child_off or else Result
			loop
				if child /= void then
					if object_comparison then
						Result := (v /= void) and then (child_item /= void) and then v.is_equal (child_item)
					else
						Result := v = child_item
					end
				end;
				child_forth
			end;
			from
				child_start
			until
				child_off or else Result
			loop
				if child /= void then
					Result := child.subtree_has (v)
				end;
				child_forth
			end;
			child_go_to (cursor)
		end;

	subtree_count: INTEGER is
			-- Number of items in children
		local
			pos: CURSOR
		do
			Result := arity;
			from
				pos := child_cursor;
				child_start
			until
				child_off
			loop
				if child /= void then
					Result := Result + child.subtree_count
				end;
				child_forth
			end;
			child_go_to (pos)
		end;

	fill_list (al: ARRAYED_LIST [G]) is
			-- Fill al with all the children's items.
		do
			from
				child_start
			until
				child_off
			loop
				if child /= void then
					al.extend (child_item);
					child.fill_list (al)
				end;
				child_forth
			end
		end;

	attach_to_parent (n: like parent) is
			-- Make n parent of current node.
		do
			parent := n
		ensure
			new_parent: parent = n
		end;

	fill_subtree (s: TREE [G]) is
			-- Fill children with children of other.
		deferred
		end;

feature {NONE} -- Implementation

	remove is
			-- Remove current item
		do
		end;

	child_remove is
			-- Remove item of current child
		do
		end;

invariant

	leaf_definition: is_leaf = (arity = 0);
	child_off_definition: child_off = child_before or child_after;
	child_before_definition: child_before = (child_index = 0);
	child_isfirst_definition: child_isfirst = (notis_leaf and child_index = 1);
	child_islast_definition: child_islast = (notis_leaf and child_index = arity);
	child_after_definition: child_after = (child_index >= arity + 1);
	child_consistency: child_readable implies child.parent = Current;

end -- class TREE