глубина вложенности термина

Я пытаюсь написать предикат, чтобы найти глубину вложенности в термин пролога. например: для атома или переменной глубина равна нулю. для f(a,b,1,2) глубина равна 1. для f(a,b(7,a),1,2) глубина равна 2 и т. д. вот что у меня есть до сих пор.

% base cases.

 get_depth(Term,0):-
  non_compound(Term),!.
 get_depth(Term,1):-
   Term =.. [_|T],
   all_basic(T),!. % no compound terms in list.
 get_depth(Term,Depth):-
 % this is where I need help.

 % helper prdeicates
  all_basic([T]):-
    non_compound(T),!.
  all_basic([H|T]):-
   non_compound(H),
   all_basic(T).

% term is non compound, either atomic or non instantiated variable.
non_compound(Term):-
 atomic(Term),!;
 var(Term).  

max(X,Y,X):-
 X >= Y,!.
max(_,Y,Y).

person Benny Abramovici    schedule 26.11.2020    source источник
comment
Почему бы не использовать term_string/2, а затем отслеживать открытие и закрытие скобка? например ?- term_string(a(b(C,D),e(F),g),String). String = "a(b(_10232,_10234),e(_10238),g)" Другими словами, не рассматривайте ввод как определенные типы терминов Пролога, а вместо этого последовательность символов.   -  person Guy Coder    schedule 26.11.2020
comment
@GuyCoder: вопрос в том, какова глубина 1+1, например, я бы сказал 1, поскольку это компактная форма +(1, 1).   -  person Willem Van Onsem    schedule 26.11.2020
comment
@GuyCoder: или элементы с нулевой арностью, например a()?   -  person Willem Van Onsem    schedule 26.11.2020
comment
@WillemVanOnsem Хорошие вопросы, я не знаю. Вот почему мой комментарий задал вопрос. Нужно будет посмотреть, ответит ли ОП.   -  person Guy Coder    schedule 26.11.2020
comment
любое соединение имеет глубину 1 или выше, зависит от уровня вложенности, в противном случае, если оно атомарное или переменное, то глубина равна 0.   -  person Benny Abramovici    schedule 26.11.2020
comment
Я бы предпочел не использовать какой-либо специальный встроенный пролог, такой как term_string, просто обычный ванильный пролог.   -  person Benny Abramovici    schedule 26.11.2020
comment
@BennyAbramovici Так какова глубина 1+1? Какова глубина a()? Также, если кто-то преобразует список в точечную нотацию, например. ?- write_term([a,b,c], [dotlists(true)]). .(a,.(b,.(c,[]))) true. Итак, следует ли преобразовывать входные данные в AST перед обработкой?   -  person Guy Coder    schedule 26.11.2020
comment
Я даю этому близкое голосование, потому что вопрос нуждается в большей ясности. ОП добавляет больше условий, например. not use any specific prolog built in с течением времени.   -  person Guy Coder    schedule 26.11.2020
comment
нет списка, только термины в формате: t(a,1,f(12,a),5) и т.д.   -  person Benny Abramovici    schedule 26.11.2020


Ответы (1)


depth(Term, D) :-
    Term =.. [_|Args],
    (  Args = []
    -> D = 0
    ;  maplist(depth, Args, Ds),
       max_list(Ds, D1), D is D1 + 1
    ).

Если вам не нужны maplist и max_list

depth(Term, D) :-
    Term =.. [_|Args],
    (  Args = []
    -> D = 0
    ;  max_depth(Args, D1), D is D1 + 1
    ).

max_depth([Term], Max) :- depth(Term, Max).
max_depth([T1, T2| Rest], Max) :-
    depth(T1, D1), max_depth([T2 | Rest], M1),
    (D1 > M1 -> Max = D1; Max = M1).
person rajashekar    schedule 26.11.2020
comment
возможно ли это без maplist и max_list, поскольку они зависят от реализации. - person Benny Abramovici; 26.11.2020
comment
Вы можете достаточно легко определить свои собственные maplist и max_list, если хотите. На самом деле вам на самом деле не нужны оба, я думаю, вам подойдет ваше собственное foldl. - person rajashekar; 26.11.2020