# От книгата The Icon programming language, 3rd ed. (R. E. Griswold, M. T. Griswold). # Програмата намира „правилните“ разполагания на 8 дами върху шахматна дъска: никои две # да не са в един стълб, ред или диагонал. # Търсенето на правилно разполагане става, като във всяка вертикала на дъската се поставя # по една дама. Изборът на конкретно място (хоризонтала) за разполагане във вертикала с # номер j става с последователно преглеждане на местата от 1 до 8, докато се намери такова, # което не е в ред или диагонал, вече зает от някоя от разположените във вертикали < j дами. # Щом това стане, преминава се към избор на разполагане във вертикала j+1 и т.н. Ако не # съществува избираемо място във вертикала j, дамата във вертикала j-1 се разполага на # следващото възможно, с оглед на дамите във вертикали < j-1 място. Ако и това не е # възможно, търси се променяне на разполагането на дамата във вертикала j-2 и т.н. назад. # Главната процедура отпечатва резултата. За да се стигне до това е нужно да бъдат успешни # последователно всички изрази – аргументи на write(). Пресмятането на всеки от тях се състои # в изпълняване на екземпляр на процедурата q() с аргумент пореден номер на вертикала от # дъската и успява само ако дамата в тази вертикала е успешно разположена. Ако това не стане, # възобновява се изпълняването на предишния екземпляр на q() – този с по-малък аргумент. # В крайна сметка се добиват всичките (92) правилни разполагания на 8-те дами върху дъската. # Ако се премахне думата every, намира се само едно разполагане. procedure main() every write(q(1),q(2),q(3),q(4),q(5),q(6),q(7),q(8)) end # Процедурата търси успешно разполагане на дамата във вертикала j, като за всеки номер # на хоризонтала повиква place(). Ако никое от повикванията не успее, q() завършва с # неуспех и го предава на main(). Ако някое от тях завърши успешно, полученият от # place() номер на хоризонтала се предава на main(), но повикването на самата q() не # завършва, а ще бъде възобновено, ако се наложи да се търси следваща възможност за # разполагане на същата дама. procedure q(j) suspend place(1 to 8,j) end # Ако в клетката (i,j) може да бъде разположена дама, процедурата предава на повикващия # екземпляр на q() успех и номера i на реда. Възможността за разполагане се установява # с проверяване на неатакуемост на клетката. Клетката е неатакуема когато и само когато # такива са хоризонталата и двата диагонала, на които тя лежи. Съответно, всеки член на # масива row[] има или няма стойност (т.е. тя е &null) според това дали хоризонталата със # същия номер е атакуема или свободна и аналогично членовете на масивите up[] и down[] # отразяват атакуемостта на възходящите и низходящи диагонали – по 15 на брой. Ако # клетката се окаже неатакуема, place(), преди да изпрати успех и стойноста i на повикващия # екземпляр на q(), бележи съответните на клетката хоризонтала и диагонали като атакуеми. # Присвояванията, които служат за това, са условни (<-), за да могат да бъдат отменени при # евентуален по-късен неуспех на екземпляр на q() за дама в следващата вертикала. Също # заради това на place() се осигурява възможност за възобновяване, предавайки от нея към # q() със suspend вместо с return. procedure place(i,j) static up, down, row initial {up := list(15); down := list(15); row := list(8)} if /row[i] & /up[8+i-j] & /down[i+j-1] then suspend row[i] <- down[i+j-1] <- up[8+i-j] <- i end