Вы получаете сообщение об ошибке
ValueError: setting an array element with a sequence.
, потому что вы пытаетесь установить элемент массива с последовательностью. Я не пытаюсь быть симпатичным, там - сообщение об ошибке пытается рассказать вам, в чем проблема. Не думайте об этом как о загадочной ошибке, это просто фраза. Какая строка задает проблему?
kOUT[i]=func(TempLake[i],Z)
Эта строка пытается установить элемент ith
из kOUT
на то, что возвращает func(TempLAke[i], Z)
. Глядя на случай i=0
:
In [39]: kOUT[0]
Out[39]: 0.0
In [40]: func(TempLake[0], Z)
Out[40]: array([ 0., 0., 0., 0.])
Вы пытаетесь загрузить 4-элементный массив в kOUT[0]
, который имеет только float. Следовательно, вы пытаетесь установить элемент массива (левая сторона, kOUT[i]
) с последовательностью (правая сторона, func(TempLake[i], Z)
).
Вероятно, func
не делает что вы хотите, но я не уверен, что вы действительно хотели этого сделать (и не забывайте, что вы обычно можете использовать векторизованные операции, такие как A * B, а не цикл в numpy.) В любом случае это должно объяснить проблему.
Глядя на ответ этого поста , вы можете использовать предикат flatten_term/2
, немного модифицированный для обработки свободных переменных, чтобы решить вашу проблему. Вот код для базового решения:
flatten_term(Term,[Term]):-
(atomic(Term);var(Term)),!.
flatten_term(Term,Flat):-
Term =.. TermList,
flatten_term_list(TermList,Flat),!.
flatten_term_list([],[]):-!.
flatten_term_list([H|T],List):-
flatten_term(H,HList),
flatten_term_list(T,TList),
append(HList,TList,List),!.
occurrences(_,[],N,N):-!.
occurrences(A,[H|T],N,Tot):-
A \== H,!,
occurrences(A,T,N,Tot).
occurrences(A,[H|T],N,Tot):-
A == H,!,
N1 is N+1,
occurrences(A,T,N1,Tot).
count(A,Term,N):-
flatten_term(Term,Flatten),
occurrences(A,Flatten,0,N).
?- count(a,f(a,g(X,a),d),T).
T = 2.
?- count(X,f(a,g(X,a),d),T).
T = 1
Прежде всего вы сгладьте термин, используя flatten_term/2
. Затем просто посчитайте вхождения элемента, который вы хотите найти, используя occurrences/4
. Вы можете, если хотите, изменить flatten_term/2
, чтобы избежать использования occurrences/4
и, таким образом, сканировать термин (список) только один раз ... Что-то вроде: flatten_term(Term,Flatten,ElementToFind,Counter,Total)
.
Это хорошо? Довольно? Или я что-то пропустил?
blockquote>Предикат Пролога
=../2
[swi-doc] может «упаковать» и «распаковать» список, содержащий Имя функтора и его аргументы в термине и наоборот. Таким образом, можно использовать это для построения термина или для анализа термина. Например:?- f(a,g(b,a)) =.. L. L = [f, a, g(b, a)].
Здесь
f
- имя функтора, аa
иg(b, a)
- аргументы. Эти аргументы также могут быть терминами, и тогда нам нужно распаковать эти аргументы дальше.Например, мы можем получить все подтермы терма с помощью:
subterms(T, T) :- \+ var(T). subterms(T, ST) :- \+ var(T), T =.. [_|As], member(A, As), subterms(A, ST).
Например:
?- subterms(f(a,g(X,a)),N). N = f(a, g(X, a)) ; N = a ; N = g(X, a) ; N = a ; false.
Теперь, когда мы получили все (под) термины, мы можем немного переписать предикат, чтобы подсчитать количество подходящих элементов:
subterm_query(Q, T) :- Q == T. subterm_query(Q, T) :- \+ var(T), T =.. [_|As], member(A, As), subterm_query(Q, A).
, поэтому мы получим, если запросим
a
:?- subterm_query(a, f(a,g(X,a))). true ; true ; false.
Если мы сможем используя библиотеку
aggregate
, мы можем использовать предикатaggregate_all/3
для подсчета количества раз, предикат был успешным:?- aggregate_all(count, subterm_query(a, f(a,g(X,a))), Count). Count = 2.
Если нет, вам нужно реализовать механизм, который возвращает
1
для совпадения и рекурсивно суммирует совпадения дочерних терминов. Я оставляю это как упражнение.
Начните с решения более общей задачи подсчета членов в списке . В конце концов, обработка термина - это обработка одноэлементного списка, содержащего этот термин:
count(A,T,N):- count(A, [T|Z],Z, 0,N).
count(_, [], [], C,N):- N is C, !.
count(A, [T|B],Z, C,N):- ?=(A,T), A=T, !, count(A, B,Z, C+1,N).
count(A, [T|B],Z, C,N):- ?=(A,T), T=..[_|S], !, append(S,Y,Z), count(A, B,Y, C,N).
count(A, [_|B],Z, C,N):- count(A, B,Z, C,N).
Это открывает каждый главный термин в списке подряд и добавляет к нему свои аргументные термины [116 ] list , таким образом используя его как очередь ... таким образом обрабатывая второй аргумент предиката T
способом в ширину .
Предполагается, что аргумент A
является атомом, а ?=
используется, чтобы избежать создания экземпляров свободных переменных, с которыми мы можем столкнуться, и вместо этого пропустить их, как, кажется, указывают ваши примеры.