Используя FsCheck в C #, мне нужно сгенерировать список значений, где определенные значения могут не появляться рядом друг с другом.Это список токенов для лексера.Так, например, мне не нужно генерировать два идентификатора рядом друг с другом или ключевое слово рядом с идентификатором, потому что, когда они превращаются в строку, лексер будет видеть их как один токен.Я не могу просто сделать что-то вроде:
Gen.ListOf(Gen.Elements("fizz", "buzz", "bazz", "+", " ", "if")).Where(list => ...);
В списке разумной длины очень вероятно, что рядом друг с другом есть два токена, которых не должно быть.Таким образом, фильтр отбрасывает слишком много значений, и генерация будет очень медленной.Я рассмотрел добавление или удаление токенов, чтобы попытаться исправить список, но это кажется очень сложным, и я боюсь, что это приведет к тому, что списки будут слишком короткими или слишком длинными.
То, что я хочу иметь возможностьсделать, это создать список «один элемент за один раз».Поэтому я выбирал случайным образом длину, а затем произвольно выбирал каждый элемент в зависимости от того, разрешено ли ему следовать за предыдущим элементом, пока у меня не будет полного списка.Кажется, что это должно быть выполнимо рекурсивно, но я не могу понять, как выразить это с помощью комбинаторов генератора.Есть способ сделать это?Я бы хотел написать произвольную лямбду, которая могла бы напрямую вызывать генераторы внутри нее, а не составлять их.Возможно ли что-то подобное?
Примечание. Я упростил пример.Генерация токенов намного сложнее.