Косвенная рекурсия не работает

В этой теме 9 ответов, 2 участника, последнее обновление  aleator 2 года/лет назад.

  • Автор
    Сообщения
  • #2449

    aleator
    Участник

    Предикат осуществляет поиск в БД и получение найденных значений.
    Пример записи БД: list(stm32f407,[uart_bus/0/proc_txd/e15,uart_bus/0/proc_txd/b6,uart_bus/0/proc_rxd/d15]).
    Рекурсивный предикат parser вызывает рекурсивный предикат parser2. При этом каждый раз ряд переменных очищается.
    То есть внутри рекурсии предиката parser2 всё работает, а внутри рекурсии parser нет.
    Result выводиться пустым списком, хотя значения при выполнении предиката parser2 (writeln(H)) выводятся. После выполнения parser2 третий и седьмой список пустые (результат и вспомогательный список).
    Пример запроса: requirement(stm32f407 ,[i2c_bus,i2c_bus,i2c_bus,ulpi_bus,mii_bus]).

    :- dynamic list/2.
    :- consult('processor_mux.pl').
    
    requirement(X,Y):- parser(X,Y,Result,[],_,[]), write(Result). requirement(_,[]).
    
    parser(X,[H|T],Z,Q, Index,PinNumbers):- (member(H,Q), NewIndex is Index+1; NewIndex is 0),
    	list(X, PinList),
    	parser2(X,H,Z,Q,NewIndex,PinList,PinNumbers), !,
    	parser(X,T,Z,[H|Q], NewIndex,PinNumbers).
    parser(_,[],I,_,_,_).
    
    parser2(X,Y,Z,Q,Index,[H|T],PinNumbers):- 
    	[Y/Index/N/P]=[H],
    	% [Y/Index/N/P]=[uart_bus/0/proc_txd/e15]
    	not(member(N,Q)),
    	not(member(P,PinNumbers)), !,
    	writeln(H),
    	parser2(X,Y,[N|Z],[N|Q],Index,T,[P|PinNumbers]). 
    parser2(X,Y,Z,Q,Index,[_|T],PinNumbers):- parser2(X,Y,Z,Q,Index,T,PinNumbers). 	
    parser2(_,_,_,_,_,[],_).

  • #2450

    Здравствуйте. Сразу сказать почему у вас не работает программа очень тяжело. Косвенная рекурсия – это всегда очень сложно и запутанно, вы можете проверить это отладчиком (посмотрите по шагам что делает программа). Еще, я могу попробовать помочь вам составить более простой алгоритм если вы подробнее опишите решаемую задачу.

  • #2455

    aleator
    Участник

    БД: list(stm32f407,[uart_bus/0/proc_txd/e15,uart_bus/0/proc_txd/b6,uart_bus/0/proc_rxd/d15,uart_bus/0/proc_rxd/b5,uart_bus/0/proc_rts/b15,uart_bus/0/proc_cts/c15,uart_bus/1/proc_txd/p2,uart_bus/1/proc_txd/c11,uart_bus/1/proc_rxd/r2,uart_bus/1/proc_rxd/b11,uart_bus/1/proc_rts/n2,uart_bus/1/proc_rts/d10,uart_bus/1/proc_cts/n3,uart_bus/1/proc_cts/d11,uart_bus/2/proc_txd/r12,uart_bus/2/proc_txd/p15,uart_bus/2/proc_txd/b14,uart_bus/2/proc_rxd/r13,uart_bus/2/proc_rxd/p14,uart_bus/2/proc_rxd/b13,uart_bus/2/proc_rts/r14,uart_bus/2/proc_rts/r15,uart_bus/2/proc_rts/n13,uart_bus/2/proc_cts/p13,uart_bus/2/proc_cts/n14,uart_bus/3/proc_txd/n3,uart_bus/3/proc_txd/b14,uart_bus/3/proc_rxd/n2,uart_bus/3/proc_rxd/p2,uart_bus/3/proc_rxd/b13,uart_bus/4/proc_txd/a12,uart_bus/4/proc_rxd/d12,uart_bus/5/proc_txd/h15,uart_bus/5/proc_txd/a7,uart_bus/5/proc_rxd/g15,uart_bus/5/proc_rxd/c10,uart_bus/5/proc_rts/h14,uart_bus/5/proc_rts/b8,uart_bus/5/proc_cts/a8,uart_bus/5/proc_cts/b7,i2c_bus/0/scl/b6,i2c_bus/0/scl/a5,i2c_bus/0/sda/b5,i2c_bus/0/sda/b4,i2c_bus/1/scl/h3,i2c_bus/1/scl/h4,i2c_bus/1/scl/r12,i2c_bus/1/sda/e2,i2c_bus/1/sda/j4,i2c_bus/1/sda/r13,i2c_bus/2/scl/n12,i2c_bus/2/scl/f15,i2c_bus/2/sda/m12,i2c_bus/2/sda/f14,async_nor_bus/0/data(0)/m14,async_nor_bus/0/data(1)/l14,async_nor_bus/0/data(2)/b12,async_nor_bus/0/data(3)/c12,async_nor_bus/0/data(4)/r8,async_nor_bus/0/data(5)/p8,async_nor_bus/0/data(6)/p9,async_nor_bus/0/data(7)/r9,async_nor_bus/0/data(8)/p10,async_nor_bus/0/data(9)/r10,async_nor_bus/0/data(10)/n11,async_nor_bus/0/data(11)/p11,async_nor_bus/0/data(12)/r11,async_nor_bus/0/data(13)/p15,async_nor_bus/0/data(14)/p14,async_nor_bus/0/data(15)/n15,async_nor_bus/0/address(0)/e2,async_nor_bus/0/address(1)/h3,async_nor_bus/0/address(2)/h2,async_nor_bus/0/address(3)/j2,async_nor_bus/0/address(4)/j3,async_nor_bus/0/address(5)/k3,async_nor_bus/0/address(6)/p6,async_nor_bus/0/address(7)/n6,async_nor_bus/0/address(8)/r7,async_nor_bus/0/address(9)/p7,async_nor_bus/0/address(10)/n7,async_nor_bus/0/address(11)/m7,async_nor_bus/0/address(12)/l15,async_nor_bus/0/address(13)/k15,async_nor_bus/0/address(14)/k14,async_nor_bus/0/address(15)/k13,async_nor_bus/0/address(16)/n14,async_nor_bus/0/address(17)/n13,async_nor_bus/0/address(18)/m15,async_nor_bus/0/address(19)/a1,async_nor_bus/0/address(20)/b1,async_nor_bus/0/address(21)/b2,async_nor_bus/0/address(22)/b3,async_nor_bus/0/address(23)/a2,async_nor_bus/0/address(24)/a8,async_nor_bus/0/address(25)/a7,async_nor_bus/0/chip_select(0)/a11,async_nor_bus/0/chip_select(1)/c10,async_nor_bus/0/chip_select(2)/b10,async_nor_bus/0/chip_select(3)/b8,async_nor_bus/0/byte_enable0/a4,async_nor_bus/0/byte_enable1/a3,async_nor_bus/0/byte_enable1/c6,async_nor_bus/0/oe/d10,async_nor_bus/0/we/c11,async_nor_bus/0/wait/b11,async_nor_bus/0/avd/b5,sync_nor_bus/0/clk/d11,sync_nor_bus/0/address(16)/n14,sync_nor_bus/0/address(17)/n13,sync_nor_bus/0/address(18)/m15,sync_nor_bus/0/address(19)/a1,sync_nor_bus/0/address(20)/b1,sync_nor_bus/0/address(21)/b2,sync_nor_bus/0/address(22)/b3,sync_nor_bus/0/address(23)/a2,sync_nor_bus/0/address(24)/a8,sync_nor_bus/0/address(25)/a7,sync_nor_bus/0/data(0)/m14,sync_nor_bus/0/data(1)/l14,sync_nor_bus/0/data(2)/b12,sync_nor_bus/0/data(3)/c12,sync_nor_bus/0/data(4)/r8,sync_nor_bus/0/data(5)/p8,sync_nor_bus/0/data(6)/p9,sync_nor_bus/0/data(7)/r9,sync_nor_bus/0/data(8)/p10,sync_nor_bus/0/data(9)/r10,sync_nor_bus/0/data(10)/n11,sync_nor_bus/0/data(11)/p11,sync_nor_bus/0/data(12)/r11,sync_nor_bus/0/data(13)/p15,sync_nor_bus/0/data(14)/p14,sync_nor_bus/0/data(15)/n15,sync_nor_bus/0/chip_select(0)/a11,sync_nor_bus/0/chip_select(1)/c10,sync_nor_bus/0/chip_select(2)/b10,sync_nor_bus/0/chip_select(3)/b8,sync_nor_bus/0/oe/d10,sync_nor_bus/0/we/c11,sync_nor_bus/0/avd/b5,sync_nor_bus/0/wait/b11,nand_bus/0/data(0)/m14,nand_bus/0/data(1)/l14,nand_bus/0/data(2)/b12,nand_bus/0/data(3)/c12,nand_bus/0/data(4)/r8,nand_bus/0/data(5)/p8,nand_bus/0/data(6)/p9,nand_bus/0/data(7)/r9,nand_bus/0/data(8)/p10,nand_bus/0/data(9)/r10,nand_bus/0/data(10)/n11,nand_bus/0/data(11)/p11,nand_bus/0/data(12)/r11,nand_bus/0/data(13)/p15,nand_bus/0/data(14)/p14,nand_bus/0/data(15)/n15,nand_bus/0/cle/n14,nand_bus/0/ale/n13,nand_bus/0/chip_select(0)/a11,nand_bus/0/chip_select(1)/c10,nand_bus/0/oe_b/d10,nand_bus/0/we_b/c11,nand_bus/0/rdybsy_b/b11,async_sram_bus/0/clk/d11,async_sram_bus/0/address(16)/n14,async_sram_bus/0/address(17)/n13,async_sram_bus/0/address(18)/m15,async_sram_bus/0/address(19)/a1,async_sram_bus/0/address(20)/b1,async_sram_bus/0/address(21)/b2,async_sram_bus/0/address(22)/b3,async_sram_bus/0/address(23)/a2,async_sram_bus/0/address(24)/a8,async_sram_bus/0/address(25)/a7,async_sram_bus/0/data(0)/m14,async_sram_bus/0/data(1)/l14,async_sram_bus/0/data(2)/b12,async_sram_bus/0/data(3)/c12,async_sram_bus/0/data(4)/r8,async_sram_bus/0/data(5)/p8,async_sram_bus/0/data(6)/p9,async_sram_bus/0/data(7)/r9,async_sram_bus/0/data(8)/p10,async_sram_bus/0/data(9)/r10,async_sram_bus/0/data(10)/n11,async_sram_bus/0/data(11)/p11,async_sram_bus/0/data(12)/r11,async_sram_bus/0/data(13)/p15,async_sram_bus/0/data(14)/p14,async_sram_bus/0/data(15)/n15,async_sram_bus/0/chip_select(0)/a11,async_sram_bus/0/chip_select(1)/c10,async_sram_bus/0/chip_select(2)/b10,async_sram_bus/0/chip_select(3)/b8,async_sram_bus/0/oe/d10,async_sram_bus/0/we/c11,async_sram_bus/0/wait/b11,async_sram_bus/0/byte0_lower/a4,async_sram_bus/0/byte1_upper/a3,async_sram_bus/0/byte1_upper/c6,spi_bus/0/mosi/r3,spi_bus/0/mosi/a6,spi_bus/0/miso/p3,spi_bus/0/miso/a9,spi_bus/0/clock/p4,spi_bus/0/clock/a10,spi_bus/0/cs(0)/n4,spi_bus/0/cs(0)/a13,spi_bus/1/mosi/m5,spi_bus/1/mosi/r15,spi_bus/1/mosi/c13,spi_bus/1/miso/m4,spi_bus/1/miso/r14,spi_bus/1/miso/c14,spi_bus/1/clock/r12,spi_bus/1/clock/r13,spi_bus/1/clock/p13,spi_bus/1/clock/d14,spi_bus/1/cs(0)/p12,spi_bus/1/cs(0)/e14,spi_bus/1/cs(0)/b4,spi_bus/2/mosi/a12,spi_bus/2/mosi/a6,spi_bus/2/miso/b13,spi_bus/2/miso/a9,spi_bus/2/clock/b14,spi_bus/2/clock/a10,spi_bus/2/cs(0)/n4,spi_bus/2/cs(0)/a13,mdc_bus/0/mdc/m3,mdc_bus/0/mdio/p2,rmii_bus/0/txd(1)/p13,rmii_bus/0/txd(1)/a7,rmii_bus/0/txd(0)/p12,rmii_bus/0/txd(0)/a8,rmii_bus/0/txen/r13,rmii_bus/0/txen/b9,rmii_bus/0/rxd(1)/p5,rmii_bus/0/rxd(0)/n5,rmii_bus/0/crs_dv/r3,mii_bus/0/txd(3)/a2,mii_bus/0/txd(3)/a5,mii_bus/0/txd(2)/m4,mii_bus/0/txd(1)/p13,mii_bus/0/txd(1)/a7,mii_bus/0/txd(0)/p12,mii_bus/0/txd(0)/a8,mii_bus/0/txen/r13,mii_bus/0/txen/b9,mii_bus/0/col/g4,mii_bus/0/col/r2,mii_bus/0/crs/n3,mii_bus/0/crs/f4,mii_bus/0/txclk/m5,mii_bus/0/rxd(3)/r4,mii_bus/0/rxd(3)/n12,mii_bus/0/rxd(2)/r5,mii_bus/0/rxd(2)/m11,mii_bus/0/rxd(1)/p5,mii_bus/0/rxd(0)/n5,mii_bus/0/rxdv/r3,mii_bus/0/rxer/e3,mii_bus/0/rxer/r12,mii_bus/0/rxclk/n2,ulpi_bus/0/data(7)/a6,ulpi_bus/0/data(6)/p13,ulpi_bus/0/data(5)/p12,ulpi_bus/0/data(4)/r13,ulpi_bus/0/stp/m2,ulpi_bus/0/usbclk/p4,ulpi_bus/0/data(3)/r12,ulpi_bus/0/data(2)/r4,ulpi_bus/0/data(1)/r5,ulpi_bus/0/data(0)/r2,ulpi_bus/0/dir/e4,ulpi_bus/0/dir/m4,ulpi_bus/0/nxt/m5,ulpi_bus/0/nxt/h4,usb2_differential_bus/0/diff_dp/b15,usb2_differential_bus/0/diff_dm/c15,usb2_differential_bus/0/id/d15,usb2_differential_bus/0/vbus/e15,usb2_differential_bus/0/diff_dp/r15,usb2_differential_bus/0/diff_dm/r14,usb2_differential_bus/0/id/p12,usb2_differential_bus/0/vbus/p13,i2s_bus/0/proc_sck/r12,i2s_bus/0/proc_sck/p13,i2s_bus/0/proc_sck/d14,i2s_bus/0/proc_dout/m5,i2s_bus/0/proc_dout/r15,i2s_bus/0/proc_dout/c13,i2s_bus/0/proc_ws/p12,i2s_bus/0/proc_ws/e14,i2s_bus/0/proc_ws/b4,i2s_bus/0/proc_din/m4,i2s_bus/0/proc_din/r14,i2s_bus/0/proc_din/c14,i2s_bus/0/master_clk/h15,i2s_bus/1/proc_sck/b14,i2s_bus/1/proc_sck/a10,i2s_bus/1/proc_dout/a12,i2s_bus/1/proc_dout/a6,i2s_bus/1/proc_ws/a13,i2s_bus/1/proc_din/b13,i2s_bus/1/proc_din/a9,i2s_bus/1/master_clk/g15,sdhc_bus/0/cmd/d12,sdhc_bus/0/data(0)/g14,sdhc_bus/0/data(1)/f14,sdhc_bus/0/data(2)/b14,sdhc_bus/0/data(3)/b13,sdhc_bus/0/clk/a12,jtag_bus/0/tck/a14,jtag_bus/0/tms/a15,jtag_bus/0/tdi/a13,jtag_bus/0/tdo/a10,swd_bus/0/swclk/a14,swd_bus/0/swdio/a15,swd_bus/0/swclk/a14,swd_bus/0/swdio/a15,camera_bus/0/data0/m13,camera_bus/0/data0/h15,camera_bus/0/data0/e15,camera_bus/0/data1/l13,camera_bus/0/data1/g15,camera_bus/0/data1/d15,camera_bus/0/data2/l12,camera_bus/0/data2/g14,camera_bus/0/data2/a4,camera_bus/0/data3/k12,camera_bus/0/data3/f14,camera_bus/0/data3/a3,camera_bus/0/data3/c6,camera_bus/0/data4/b1,camera_bus/0/data4/e13,camera_bus/0/data4/b13,camera_bus/0/data5/b6,camera_bus/0/data5/d4,camera_bus/0/data6/b2,camera_bus/0/data6/a5,camera_bus/0/data6/c3,camera_bus/0/data7/b3,camera_bus/0/data7/b4,camera_bus/0/data7/c2,camera_bus/0/data8/d14,camera_bus/0/data8/b14,camera_bus/0/data9/c14,camera_bus/0/data9/a12,camera_bus/0/data10/c13,camera_bus/0/data10/a6,camera_bus/0/data11/d13,camera_bus/0/data11/d12,camera_bus/0/data12/r6,camera_bus/0/data13/e14,camera_bus/0/data13/b7,camera_bus/0/hysnc/n4,camera_bus/0/hysnc/m12,camera_bus/0/vsync/b5,camera_bus/0/vsync/c4,camera_bus/0/pixelclk/p3,can_bus/0/proc_tx/b15,can_bus/0/proc_tx/e12,can_bus/0/proc_tx/c12,can_bus/0/proc_tx/b4,can_bus/0/proc_rx/d3,can_bus/0/proc_rx/c15,can_bus/0/proc_rx/b12,can_bus/0/proc_rx/a5,can_bus/1/proc_tx/p13,can_bus/1/proc_tx/b6,can_bus/1/proc_rx/p12,can_bus/1/proc_rx/a6]). – это только одна запись.
    Пример вызова: requirement(stm32f407 ,[i2c_bus,i2c_bus,i2c_bus,ulpi_bus,mii_bus]).

    Программа должна найти все записи из БД по следующим критериям:
    1. Запись бд берётся с первым аргументом равным первой переменной вызова. В этом случае это “stm32f407”.
    2. Ищутся значения в списке из записи бд (вида А/Б/В/Г), где В равна значению из списка в вызове. При этом последнее значение должно быть уникальным – Г. Если значения в списке повторяются (i2c_bus,i2c_bus,i2c_bus), то параметр Б инкрементируется (добавляется 1)

    Для моего примера вывод будет таким:

    requirement(stm32f407 ,[i2c_bus,i2c_bus,i2c_bus,ulpi_bus,mii_bus]). 
    
    List=[i2c_bus/0/scl/b6,i2c_bus/0/sda/b5,
    i2c_bus/1/scl/h3,i2c_bus/1/sda/e2,
    i2c_bus/2/scl/f15,i2c_bus/2/sda/m12,
    ulpi_bus/0/data(7)/a6,
    ulpi_bus/0/data(6)/p13,
    ulpi_bus/0/data(5)/p12,
    ulpi_bus/0/data(4)/r13,
    ulpi_bus/0/stp/m2,
    ulpi_bus/0/usbclk/p4,
    ulpi_bus/0/data(3)/r12,
    ulpi_bus/0/data(2)/r4,
    ulpi_bus/0/data(1)/r5,
    ulpi_bus/0/data(0)/r2,
    ulpi_bus/0/dir/e4,
    ulpi_bus/0/nxt/h4,
    mii_bus/0/txd(3)/a2,mii_bus/0/txd(3)/a5,mii_bus/0/txd(2)/m4,mii_bus/0/txd(1)/a7,mii_bus/0/txd(0)/a8,mii_bus/0/txen/b9,mii_bus/0/col/g4,mii_bus/0/crs/n3,mii_bus/0/txclk/m5,mii_bus/0/rxd(3)/n12,mii_bus/0/rxd(2)/m11,mii_bus/0/rxd(1)/p5,mii_bus/0/rxd(0)/n5,mii_bus/0/rxdv/r3,mii_bus/0/rxer/e3].

    Объяснил как мог, получилось сумбурно, но я думаю пример вызова и результата Вам помогут.

  • #2457

    aleator
    Участник

    Более упрощённо: необходимо создать предикат по поиску значений из списка в другом списке.

    • #2458

      Более упрощённо: необходимо создать предикат по поиску значений из списка в другом списке.

      Более детально я посмотрю Вашу тему завтра, но если “упрощенно” – то посмотрите тут: поиск значений из списка в другом списке. При такой формулировке задача решается двумя вызовами nth0 и никакая косвенная рекурсия не нужна.

    • #2459

      Прочитал более детально что именно Вы пытаетесь сделать. На мой взгляд, сам подход не верен. По теме можно почитать статьи:

      • Рекурсия в программировании – описан анализ рекурсивных алгоритмов, при этом можно заметить, что анализу поддаются только алгоритмы записанные определенным образом. Для всех более сложных вариантов, включая косвенную рекурсию нет способов даже оценить трудоемкость, поэтому их строго не рекомендуется использовать;
      • SOLID принципы – описаны наиболее общие 5 принципов хорошего кода и способов рефакторинга. Надо обратить внимание на принципы, призванные снизить сложность, т.к. у вас она зашкаливает из-за сильных связей между функциями и попыткой решить сразу несколько задач.

      Я бы сначала обработал второй список и на его основе сформировал новый, при этом каждому элементу приписал бы количество повторений (параметр Б), а затем – отфильтровал бы записи БД:

      requirement(Model, Buses, Requirement):-
        count_repeat(Buses, RepeatBuses),
        filter_buses(Model, RepeatBuses, Requirement).

      Для формирования списка Б с повторениями можно использовать готовую функцию подсчета повторений:

      count_repeat([], []):-!.
      count_repeat([Head|Tail], [(Head, Count)|CountTail]):-
        count(Tail, Head, Count),
        count_repeat(Tail, CountTail).

      Такая функция реализуется очень просто, не менее легко тестируется, не зависит от других функций и значительно упрощает задачу.

  • #2462

    aleator
    Участник

    Спасибо. Я справился сам. Пришлось отказаться от косвенной рекурсии вообще. Пришлось “расписать” все варианты одного предиката.
    PS. Извините, что не по теме, Вы не порекомендуете что-нибудь русскоязычное по DCG?

    • #2464

      Пришлось отказаться от косвенной рекурсии вообще. Пришлось “расписать” все варианты одного предиката.

      То, что отказались от косвенной рекурсии – хорошо. Что там пришлось расписать – не понятно. Мне кажется, мое решение гораздо проще исходного. При этом оно понятное, очень быстро и легко кодируется. Мне не понятно в этом контексте слово “пришлось” (как будто косвенная рекурсия могла помочь сделать то же самое еще проще).

      Хороший раздел по DCG есть в книге Сергиевский Г. М. Функциональное и логическое программирование, но там не совсем то, что пишут обычно по этой теме. Если Вы зададите более конкретные вопросы – я может быть помогу. Только проставляйте самостоятельно теги, ключевые слова, выбирайте правильно раздел (на этом форуме строгая структура) и т.п.

  • #2463

    Дальше не совсем понятно. Вы пишите

    Ищутся значения в списке из записи бд (вида А/Б/В/Г), где В равна значению из списка в вызове

    Однако, фактически я вижу, что в записи БД параметры из списка вызова стоят на позиции А.

    При этом последнее значение должно быть уникальным – Г.

    Не понятно какая уникальность имеется ввиду (среди чего). Если имеется ввиду уникальность среди результатов – то необходимо выбрать все нужные элементы, а затем отфильтровать их еще раз с требованием уникальности. Если же имеется ввиду уникальность среди исходных данных (полученных прямо из БД) – то фильтровать надо до обработки (сразу после извлечения данных из БД).

    Кроме того, что не ясно, выборку нужных данных можно организовать следующим образом:

    filter_buses_model(_Buses, [], []):-!.
    filter_buses_model(Buses, [(HeadBus, Count)|RepeatBusesTail], Requirement):-
      findall(HeadBus/Count/C/D, member(HeadBus/Count/C/D, Buses), HeadRequirementBuses), 
      filter_buses_model(Buses, RepeatBusesTail, RequirementTail),
      append(HeadRequirementBuses, RequirementTail, Requirement).

  • #2465

    aleator
    Участник

    Что-то с порядком вывода сообщений…
    Вот моё решение:

    % *************************************************************
    
    first([X|_],X).
    % *************************************************************
    
    writeL([]):-!.
        writeL([H|T]):-write(H),nl,writeL(T).
    % *************************************************************
    
    requirement(X,Y):- list(X, PinList), my_parser(Y,PinList,PinList,[],0,[],[],[]).
    
    my_parser([],_,_,Result,_,_,_,_):- writeL(Result).
    
    my_parser([_|T],[],PinList,Result,Index,BusPropertysList,PinNumbersList,_):- 
    	(first(T,X), 
    	member(X,BusPropertysList), NewIndex is Index+1; NewIndex is 0),	
    	my_parser(T,PinList,PinList,Result,NewIndex,BusPropertysList,PinNumbersList,[]).
    
    my_parser([H|T1],[H/Index/N/P|T2],PinList,Result,Index,BusPropertysList,PinNumbersList,List):-
    	not(member(N,List)),
    	not(member(P,PinNumbersList)),
    	my_parser([H|T1],T2,PinList,[H/Index/N/P|Result],Index,[H|BusPropertysList],[P|PinNumbersList], [N|List]).
    
    my_parser([H1|T1],[_/_/_/_|T2],PinList,Result,Index,BusPropertysList,PinNumbersList, List):- 
    	my_parser([H1|T1],T2,PinList,Result,Index,BusPropertysList,PinNumbersList, List).
    
    % *************************************************************

    1. Насчёт не понятности задания – Вы правы. Объяснил плохо.
    2. Насчёт “пришлось” – в начале, решение в виде косвенной рекурсии мне казалось более понятным (если не единственным).

Для ответа в этой теме необходимо авторизоваться.