Prolog GNU - مشغل UNIV؟ شرح ذلك
-
29-09-2019 - |
سؤال
لذلك عامل UNIV. أنا لا أفهم ذلك بالضبط.
على سبيل المثال هذا:
foo(PredList,[H|_]) :- bar(PredList,H).
foo(PredList,[_|T]) :- foo(PredList,T),!.
bar([H|_],Item) :- G =.. [H,Item],G.
bar([_|T],Item) :- bar(T,Item).
ماذا يفعل هذا؟ هذا يبدو لمعرفة ما إذا كان مسند آخر صحيح. لا أفهم ما يفعله "..".
كيف يمكنك إعادة كتابة هذا بدون مشغل UNIV؟
المحلول
الجامعة (=..
) يقسم مصطلح إلى قائمة من المكونات ، أو يبني مصطلح من هذه القائمة. محاولة:
?- f(x,y) =.. L.
L = [f, x, y].
?- f(x,y,z) =.. [f|Args].
Args = [x, y, z].
?- Term =.. [g,x,y].
Term = g(x, y).
bar
يبدو أنه يتصل بكل مسند PredList
على Item
, ، مع foo
التراجع عن Item
س. (باستخدام متغير كمسند غير محمول ؛ call
يجب أن يفضل المسند.)
يحرر: Kaarel على حق ، يمكن استبدال جامعة functor/3
و arg/3
, ، كالآتي:
bar([H|_],Item) :-
functor(Goal,H,1), % unifies Goal with H(_)
arg(1,Goal,Item), % unifies first argument of Goal with Item
call(Goal). % use this for portability
نصائح أخرى
الأنسب إعادة كتابة في رأيي هي:
bar( [H|_], Item ) :- call(H, Item).
call/n
ليست بعد جزءًا من معيار ISO Core ، لكنها قد تصبح في المستقبل القريب (*). الكثير من أنظمة المقدمة تدعمهم بالفعل.
هناك سبب واحد لماذا call/n
يجب أن تكون مفضلة على البسيط (=..)/2
و functor/3
+ arg/3
حلول. ال call/n
الحل قادر على التعامل مع الإغلاق (**).
مع البسيط (=..)/2
و functor/3
+ arg/3
الحل يمكن للمرء أن يستدعي bar/2
فقط مع الذرات في حجة القائمة الأولى. فمثلا:
p1(1).
p2(2).
?- bar( [p1, p2], 1 ).
Yes
?- bar( [p1, p2], 2 ).
Yes
?- bar( [p1, p2], 3 ).
No
مع الإغلاق ، لسنا مقيدين بالذرات ، وقد نوفر بعض جهود الترميز. على سبيل المثال ، يمكننا القيام بما يلي مباشرة:
?- bar( [=(1), =(2)], 1 ).
Yes
?- bar( [=(1), =(2)], 2 ).
Yes
?- bar( [=(1), =(2)], 3 ).
No
تحياتي الحارة
(*)
مشروع التصوير الفني 2
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dtc2#call
(**)
من إخترعها؟: call/n
المتوقع
http://www.complang.tuwien.ac.at/ulrich/prolog-inedit/naish.html