// File: /workspace/github_c_makefile_star2_O1/chatziko-k08[P]lecture-code/tests/../modules/UsingBTree/ADTSet.c
// Function: node_is_btree
static bool node_is_btree(BTreeNode node, CompareFunc compare) {
	if (node == NULL)
		return true;

	// Ο κόμβος έχει περισσότερες τιμές από όσες πρέπει.
	if (node->count > MAX_VALUES)
		return false;

	// Ο κόμβος *δεν* είναι η ρίζα και έχει λιγότερες τιμές από όσες πρέπει.
	if (node->parent != NULL && node->count < MIN_VALUES)
		return false;

	// Όλες οι τιμές του κόμβου είναι σε σωστή διάταξη.
	for (int i = 0; i < node->count-1; i++) {
		if (compare(node->set_nodes[i]->value, node->set_nodes[i+1]->value) >= 0)
			return false;
	}

	// Έλεγξε ότι όλα τα παιδιά του δέντρου έχουν έγκυρο ύψος.
	if (node->parent == NULL && !is_valid_height(node))
		return false;

	// Έλεγξε ότι όλα τα παιδιά του node έχουν τον ίδιο πατέρα.
	if (!is_valid_parent(node))
		return false;

	// Για όλες τις τιμές του κόμβου.
	for (int i = 0; i < node->count; i++) {

		SetNode left_max = node_find_max(node->children[i]);  // Μέγιστο παιδί αριστερού υποδέντρου.
		SetNode right_min = node_find_min(node->children[i+1]);  // Ελάχιστο παιδί δεξιού υποδέντρου.

		Pointer left_last  = (node->children[i] != NULL)  // Μεγαλύτερο στοιχείο αριστερού παιδιού.
			? node->children[i]->set_nodes[ node->children[i]->count-1 ]->value
			: NULL;

		Pointer right_first = (node->children[i+1] != NULL)  // Μικρότερο στοιχείο δεξιού παιδιού.
			? node->children[i+1]->set_nodes[0]->value 
			: NULL;

		Pointer val = node->set_nodes[i]->value;  // Τιμή που ελέγχεται.

		bool correct = 
			(left_last   == NULL || compare(left_last, val)   < 0) &&  // Μεγαλύτερη από την μεγαλύτερη τιμή του αριστερού παιδιού.
			(right_first == NULL || compare(right_first, val) > 0) &&  // Μικρότερη από την μικρότερη του δεξιού παιδιού.
			(left_max  == NULL || compare(left_max->value, val) < 0) &&  // Μεγαλύτερη από τη μέγιστη του αριστερού υποδέντρου
			(right_min == NULL || compare(right_min->value, val) > 0) &&  // Μικρότερη από τη ελάχιστη του δεξιού υποδέντρου
			node_is_btree(node->children[i], compare);  // Έλεγξε και το αριστερό υποδέντρο.

		if (i == node->count-1)  // Εαν είναι η τελευταία διαχωριστική τιμή, έλεγξε και το δεξί υποδέντρο.
			correct = correct && node_is_btree(node->children[node->count], compare);

		if (!correct)
			return false;
	}

	return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
testq %rdi, %rdi
je 0x558b
movq %rdi, %r14
movl (%rdi), %eax
cmpl $0x4, %eax
jg 0x5587
movq %rsi, %rbx
cmpl $0x1, %eax
jg 0x559f
cmpq $0x0, 0x8(%r14)
je 0x559f
xorl %ebp, %ebp
jmp 0x558e
movb $0x1, %bpl
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %r13d, %r13d
movslq (%r14), %r12
decq %r12
cmpq %r12, %r13
jge 0x55ce
movq %r13, %r15
movq 0x40(%r14,%r13,8), %rax
movq 0x48(%r14,%r13,8), %rcx
movq (%rax), %rdi
incq %r13
movq (%rcx), %rsi
callq *%rbx
testl %eax, %eax
js 0x55a2
cmpq %r12, %r15
jl 0x5587
cmpq $0x0, 0x8(%r14)
jne 0x55ef
leaq 0x7(%rsp), %r15
movb $0x1, (%r15)
movq %r14, %rdi
movq %r15, %rsi
callq 0x5c2d
cmpb $0x1, (%r15)
jne 0x5587
cmpq $0x0, 0x10(%r14)
je 0x563e
movslq (%r14), %rax
testq %rax, %rax
js 0x5633
movq 0x10(%r14), %rcx
cmpq %r14, 0x8(%rcx)
jne 0x5587
leal 0x1(%rax), %ecx
decq %rcx
xorl %esi, %esi
movq %rsi, %rdx
cmpq %rsi, %rcx
je 0x562b
movq 0x18(%r14,%rdx,8), %rdi
leaq 0x1(%rdx), %rsi
cmpq %r14, 0x8(%rdi)
je 0x5614
cmpq %rax, %rdx
setae %al
jmp 0x5636
shrl $0x1f, %eax
testb %al, %al
je 0x5587
xorl %r12d, %r12d
movslq (%r14), %rax
cmpq %rax, %r12
setge %bpl
jge 0x558e
movq 0x10(%r14,%r12,8), %r13
movq %r13, %rdi
callq 0x5099
movq %rax, 0x10(%rsp)
movq 0x18(%r14,%r12,8), %r15
movq %r15, %rdi
callq 0x507c
movq %rax, 0x8(%rsp)
testq %r13, %r13
je 0x5688
movslq (%r13), %rax
movq 0x38(%r13,%rax,8), %rax
movq (%rax), %rdi
jmp 0x568a
xorl %edi, %edi
testq %r15, %r15
je 0x5698
movq 0x40(%r15), %rax
movq (%rax), %r15
jmp 0x569b
xorl %r15d, %r15d
movq 0x40(%r14,%r12,8), %rax
movq (%rax), %r13
testq %rdi, %rdi
je 0x56b1
movq %r13, %rsi
callq *%rbx
testl %eax, %eax
jns 0x56fd
testq %r15, %r15
je 0x56c2
movq %r15, %rdi
movq %r13, %rsi
callq *%rbx
testl %eax, %eax
jle 0x56fd
movq 0x10(%rsp), %rax
testq %rax, %rax
je 0x56d8
movq (%rax), %rdi
movq %r13, %rsi
callq *%rbx
testl %eax, %eax
jns 0x56fd
movq 0x8(%rsp), %rax
testq %rax, %rax
je 0x56ee
movq (%rax), %rdi
movq %r13, %rsi
callq *%rbx
testl %eax, %eax
jle 0x56fd
movq 0x10(%r14,%r12,8), %rdi
movq %rbx, %rsi
callq 0x555b
jmp 0x56ff
xorl %eax, %eax
movslq (%r14), %rdx
leal -0x1(%rdx), %esi
cmpq %rsi, %r12
setne %cl
andb %al, %cl
cmpq %rsi, %r12
jne 0x5725
testb %al, %al
je 0x5725
movq 0x10(%r14,%rdx,8), %rdi
movq %rbx, %rsi
callq 0x555b
movl %eax, %ecx
incq %r12
testb %cl, %cl
jne 0x5641
jmp 0x558e