Recursive derivation on ordered-graph

Hi, in the following code I’m trying to skip sales agreements that have no product sales when giving out invoice numbers. I’m trying to write a recursive piece of code that will stop when it finds either the first sales agreement or a sales agreement with product sales. However I can’t seem to find a recursive way for this. Is this even at all possible?

'Sales Agreements': collection ['ID']
	'Ordered Sales Agreements': ordered-graph .'First Sales Agreement' ( ?'Yes' || ?'No'>'Previous Sales Agreement' )
{
	'ID': text
	'First Sales Agreement': stategroup (
		'Yes' { }
		'No' {
			'Previous Sales Agreement': text -> ^ sibling in ( 'Ordered Sales Agreements' )
		}
	)
	'Has Product Sale': stategroup = switch .'Sales'* .'Line Type'?'Product' ^ (
		| none  => 'No' ( )
		| nodes => 'Yes' ( )
	) (
		'Yes' {
			'Invoice Number': number positive 'index' = ( recurse ^ 'Ordered Sales Agreements' ) switch ^ .'First Sales Agreement' (
				| 'Yes' => ^ ^ ^ ^ ^ .'Administration'.'Accounting'>'Current Accounting Year'.'Next Available Invoice Number'
				| 'No' as $ => switch $ >'Previous Sales Agreement' .'Has Product Sale' (
					| 'Yes' as $ => sum ( $ .'Invoice Number', 1 )
					| 'No' as $ => switch $ ^ .'First Sales Agreement' (
						| 'Yes' => ^ ^ ^ ^ ^ .'Administration'.'Accounting'>'Current Accounting Year'.'Next Available Invoice Number'
						| 'No' as $ => switch $ >'Previous Sales Agreement' .'Has Product Sale' (
							| 'Yes' as $ => sum ( $ .'Invoice Number', 1 )
							| 'No' => 9999
						)
					)
				)
			)
		}
		'No' { }
	)

It is certainly possible; there are in fact multiple different ways to express it. The trick is to ensure that a recursive expression can unconditionally reference itself after a sibling reference step. For example, the expression for 'Available Invoice Number' can unconditionally reference 'Available Invoice Number' after >'Previous Sales Agreement':

'Sales Agreements': collection ['ID']
	'Ordered Sales Agreements': ordered-graph .'First Sales Agreement' ( ?'Yes' || ?'No'>'Previous Sales Agreement' )
{
	'ID': text
	'First Sales Agreement': stategroup (
		'Yes' { }
		'No' {
			'Previous Sales Agreement': text -> ^ sibling in ( 'Ordered Sales Agreements' )
		}
	)
	'Available Invoice Number': number positive 'index' = ( recurse 'Ordered Sales Agreements' ) switch .'First Sales Agreement' (
		| 'Yes' => ^ ^ ^ ^ ^ .'Administration'.'Accounting'>'Current Accounting Year'.'Next Available Invoice Number'
		| 'No' as $ => switch $ >'Previous Sales Agreement'.'Has Product Sale' (
			|'No' => $ >'Previous Sales Agreement'.'Available Invoice Number' // number was not used by Previous Sales Agreement
			|'Yes' => sum ( $ >'Previous Sales Agreement'.'Available Invoice Number', 1 ) //number was used by Previous Sales Agreement
		)
	) @hidden
	'Has Product Sale': stategroup = switch .'Sales'* .'Line Type'?'Product' ^ (
		| none  => 'No' ( )
		| nodes => 'Yes' ( )
	) (
		'Yes' {
			'Invoice Number': number positive 'index' = ^ .'Available Invoice Number'
		}
		'No' { }
	)
}

Note that your approach did not work because the existence of Invoice Number is conditional according to your code sample: it only exists for state 'Has Product Sale'?'Yes'.