// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x6a50
movb $0x1, -0x1(%rbp)
jmp 0x6d10
movq -0x10(%rbp), %rax
cmpl $0x4, (%rax)
jle 0x6a62
movb $0x0, -0x1(%rbp)
jmp 0x6d10
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x6a7f
movq -0x10(%rbp), %rax
cmpl $0x2, (%rax)
jge 0x6a7f
movb $0x0, -0x1(%rbp)
jmp 0x6d10
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jge 0x6adc
movq -0x18(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq -0x1c(%rbp), %rdx
movq 0x40(%rcx,%rdx,8), %rcx
movq (%rcx), %rdi
movq -0x10(%rbp), %rcx
movl -0x1c(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movq 0x40(%rcx,%rdx,8), %rcx
movq (%rcx), %rsi
callq *%rax
cmpl $0x0, %eax
jl 0x6acf
movb $0x0, -0x1(%rbp)
jmp 0x6d10
jmp 0x6ad1
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x6a86
movq -0x10(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x6afd
movq -0x10(%rbp), %rdi
callq 0x7620
testb $0x1, %al
jne 0x6afd
movb $0x0, -0x1(%rbp)
jmp 0x6d10
movq -0x10(%rbp), %rdi
callq 0x7650
testb $0x1, %al
jne 0x6b13
movb $0x0, -0x1(%rbp)
jmp 0x6d10
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x6d0c
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq 0x10(%rax,%rcx,8), %rdi
callq 0x61b0
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq 0x10(%rax,%rcx,8), %rdi
callq 0x6130
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
cmpq $0x0, 0x10(%rax,%rcx,8)
je 0x6b9a
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq 0x10(%rax,%rcx,8), %rax
movq -0x10(%rbp), %rcx
movslq -0x20(%rbp), %rdx
movq 0x10(%rcx,%rdx,8), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movq 0x40(%rax,%rcx,8), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
jmp 0x6ba2
xorl %eax, %eax
movq %rax, -0x58(%rbp)
jmp 0x6ba2
movq -0x58(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
cmpq $0x0, 0x10(%rax,%rcx,8)
je 0x6bde
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movq 0x10(%rax,%rcx,8), %rax
movq 0x40(%rax), %rax
movq (%rax), %rax
movq %rax, -0x60(%rbp)
jmp 0x6be6
xorl %eax, %eax
movq %rax, -0x60(%rbp)
jmp 0x6be6
movq -0x60(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq 0x40(%rax,%rcx,8), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x6c27
movq -0x18(%rbp), %rax
movq -0x38(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq *%rax
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x61(%rbp)
jge 0x6ca9
cmpq $0x0, -0x40(%rbp)
je 0x6c48
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq *%rax
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x61(%rbp)
jle 0x6ca9
cmpq $0x0, -0x28(%rbp)
je 0x6c6c
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movq (%rcx), %rdi
movq -0x48(%rbp), %rsi
callq *%rax
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x61(%rbp)
jge 0x6ca9
cmpq $0x0, -0x30(%rbp)
je 0x6c90
movq -0x18(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rdi
movq -0x48(%rbp), %rsi
callq *%rax
movl %eax, %ecx
xorl %eax, %eax
cmpl $0x0, %ecx
movb %al, -0x61(%rbp)
jle 0x6ca9
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
movq 0x10(%rax,%rcx,8), %rdi
movq -0x18(%rbp), %rsi
callq 0x6a30
movb %al, -0x61(%rbp)
movb -0x61(%rbp), %al
andb $0x1, %al
movb %al, -0x49(%rbp)
movl -0x20(%rbp), %eax
movq -0x10(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x6cf0
xorl %eax, %eax
testb $0x1, -0x49(%rbp)
movb %al, -0x62(%rbp)
je 0x6ce8
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movslq (%rcx), %rcx
movq 0x10(%rax,%rcx,8), %rdi
movq -0x18(%rbp), %rsi
callq 0x6a30
movb %al, -0x62(%rbp)
movb -0x62(%rbp), %al
andb $0x1, %al
movb %al, -0x49(%rbp)
testb $0x1, -0x49(%rbp)
jne 0x6cfc
movb $0x0, -0x1(%rbp)
jmp 0x6d10
jmp 0x6cfe
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x6b1a
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)