Prolog에 오신 것을 환영합니다! 네가 한 번 해보니 기쁘다. 네가 많이 가진 것처럼 보이기 때문에 그것이 상상력을 잘 발휘할 수 있기를 바란다.
여기 Prolog에는 많은 이상한 용어가 사용됩니다. "프레임"또는 "노드"또는 "추출"이란 의미가 무엇인지 명확하게 알지 못합니다. 저는 여러분이 "consult"를 사용하고 있다고 확신합니다. 이 튜토리얼이 SICStus 용으로 작성되었거나 보통의 혼동 일 뿐이 기 때문에 이것이 맞는지는 모르겠습니다. 나는 또한 Prolog에서 상속을하는 것을 보통 생각하지 않을 것이지만,이 부분은 내가 실제로 이해한다고 생각한다. 그래서 나는 당신이 따라 놀 것이고 어쨌든 내가 당신의 질문에 대답 할 수 있는지를 알게 될 것입니다.
첫 번째 사항부터 큰 문제는 아니지만 평균 점수는 다음과 같이 구현해야합니다.
avg_score(Z) :-
student(jack, X),
student(jill, Y),
Z is (X + Y)/2. % <-- note the use of 'is' instead of '='
이것은 일반적인 초보자 실수입니다. Prolog는 기본적으로 대수를 평가하지 않으므로 (X + Y)/2
과 같은 것을 말하면 실제로하는 것은 표현식을 작성하는 것입니다 (div(plus(X, Y), 2)
과 다를 수 없음). 한 가지 차이점은 실제로 is
이 (X + Y)/2
과 같은 대수 식을 계산하는 방법을 알고 있지만 div(plus(X, Y), 2)
이 아닌 것을 알고 있다는 것입니다. (난 당신이 처음부터 clpfd
을 사용하기 시작하면 프롤로그가 더 많은 의미가 찾아 #=
대신 is
를 사용할 것이다 당신을-경고 사전 수 있습니다.)
아니, avg_score
에 대해 도움이되지 않는 것입니다, 물론, jack
및 jill
이 포함되어 있습니다. 언젠가는 모든 학생들의 평균 점수를 계산하고 싶을 것입니다.
average(L, Average) :-
sum(L, Sum),
length(L, Length),
Average is Sum/Length.
% this is overly complex because I wanted to show you
% the tail recursive version
sum(L, Sum) :- sum(L, 0, Sum).
sum([], Sum, Sum).
sum([X|Xs], Acc, Sum) :- Acc1 is X + Acc, sum(Xs, Acc1, Sum).
이제 우리는 다음과 같이 모든 학생들의 평균을 얻을 수 있습니다 :이 무엇을 요구하거나하고 관련 있는지 알고 발생하지 않는
avg_score(Z) :-
findall(X, student(_, X), Scores),
average(Scores, Z).
우선의 평균을 계산하자 아니,하지만 그것이 도움이 될 것 같아 보이네.
물론 다른 것들은 매개 변수화하는 것입니다. 우리는 원래의 코드를 가지고 학생을 매개 변수화 할 수 있습니다 : 그것은 동물 우화집를 쿼리에 더 적절한 수 있습니다처럼
avg_score(Student1, Student2, Z) :-
student(Student1, X),
student(Student2, Y),
Z is (X + Y)/2.
이 보인다. attack(X)
을 묻기보다는 attack(fire_warrior, X)
을 물어볼 것입니다.
Prolog를 처음 접했을 때 Logtalk로 연결되는 것을 싫지만 의심되는 답변이있을 수 있습니다. 바닐라 프롤로그가 그렇지 않은 방식으로 상속을 처리하는 것이 특히 좋습니다. 하지만 큰 전환이 될 수 있습니다.예를 들어, 다음과 같이 공격 합계 쿼리에 대한 상속 체인을 처리 할 수있는 :이 동작을 원하는 경우
?- calc_attack_bonus(fire_warrior, Bonus).
Bonus = 1.5.
?- calc_attack_bonus(character, Bonus).
Bonus = 0.
나도 몰라 :
% this is the inheritance tree
parent_class(character, base).
parent_class(npc, character).
parent_class(enemy, npc).
parent_class(red_faction, enemy).
parent_class(blue_faction, enemy).
parent_class(fire_warrior, red_faction).
parent_class(water_consort, blue_faction).
% these are the attack bonuses
attack_bonus(base, 0).
attack_bonus(red_faction, 1.5).
attack_bonus(blue_faction, 1).
calc_attack_bonus(X, Bonus) :-
attack_bonus(X, Bonus), !.
calc_attack_bonus(X, Bonus) :-
\+ attack_bonus(X, Bonus),
parent_class(X, Parent),
calc_attack_bonus(Parent, Bonus).
이 몇 가지 기본적인 쿼리 작업이 나타납니다 여부 : 그것은 (parent_class
이 실패 할 경우, 그렇지 않으면 0 보너스를 통합 재발)하지 않을 경우 해결하기 위해 쉽게
?- calc_attack_bonus(tree, Bonus).
false.
.
그러나 이것은 모두 확장 할 수있는 것은 아닙니다.
calc_attribute(X, Attribute, Value) :-
attribute(X, Attribute, Value), !.
calc_attribute(X, Attribute, Value) :-
\+ attribute(X, Attribute, Value),
parent_class(X, Parent),
calc_attribute(Parent, Attribute, Value).
그리고 지금은 공격이 쉽게된다 :
% these are the attack bonuses
attribute(attack_bonus, base, 0).
attribute(attack_bonus, red_faction, 1.5).
attribute(attack_bonus, blue_faction, 1).
% base stats
attribute(base_stat, character, 8.0).
attribute(level, fire_warrior, 1.0).
이제 우리는 우리가 많은 고통없이 필요한 규칙을 작성할 수 있습니다 더 확장 방법이 될 수
attack(X, Value) :-
calc_attribute(X, attack_bonus, Bonus),
calc_attribute(X, base_stat, Base),
calc_attribute(X, level, Level),
Value is (Level + Base) * Bonus.
우리 이상적으로는 compute(fire_warrior, attack, Value)
과 같은 것을 말하고 싶기 때문에 compute
을 쓸 수있는 곳으로 가려면 좀 더 일반화해야합니다. 그런 일이 일어나기 위해서는 attack_bonus
이 attack
과 관련이 있다는 것을 알아야합니다.
% these are the attack bonuses
attribute(base, bonus(attack), 0).
attribute(red_faction, bonus(attack), 1.5).
attribute(blue_faction, bonus(attack), 1).
% base stats
attribute(character, base_stat, 8.0).
attribute(fire_warrior, level, 1.0).
이제 우리는 요리하고 있습니다 :
compute(X, Attribute, Value) :-
calc_attribute(X, bonus(Attribute), Bonus),
calc_attribute(X, base_stat, Base),
calc_attribute(X, level, Level),
Value is (Level + Base) * Bonus.
을 보라 : 이제 attribute
약간의 구조 조정을 보자
?- compute(fire_warrior, attack, Value).
Value = 13.5.
을 나는 그게 당신이 원하는 무엇 바랍니다. :)
큰 편집 재미를 들어
은 내가이 Logtalk, 프롤로그를위한 객체 지향 확장 언어 어떨까 볼 수있을 거라고 생각했다. 나는 매우 Logtalk를 처음 사용하기 때문에 이것이 좋은 접근 방법 일 수도 있고 그렇지 않을 수도 있지만 "속임수"를 했으므로 원하는 것을 선택하는 것이 더 많은지 알아 보겠습니다. 첫째, 기본 오브젝트 :
:- object(base).
:- public(base_stat/1).
:- public(attack/1).
:- public(bonus/2).
:- public(level/1).
:- public(compute/2).
bonus(attack, 0).
base_stat(0).
level(0).
compute(Attribute, Value) :-
::bonus(Attribute, Bonus),
::base_stat(Base),
::level(Level),
Value is (Level + Base) * Bonus.
:- end_object.
이것은 기본적으로 우리는 각각의 일에 대해 저장하는거야 사실을 정의하는 방법과 관심있는 속성을 계산하는 것이다 다음으로 우리가 객체 계층 구조를 확립 :.
:- object(character, extends(base)).
base_stat(8.0).
:- end_object.
:- object(npc, extends(character)).
:- end_object.
:- object(enemy, extends(npc)).
:- end_object.
:- object(red_faction, extends(enemy)).
bonus(attack, 1.5).
bonus(speed, 1.25).
bonus(defense, 0.25).
:- end_object.
:- object(blue_faction, extends(enemy)).
bonus(attack, 1).
bonus(speed, 1).
bonus(defense, 1).
:- end_object.
:- object(fire_warrior, extends(red_faction)).
level(1.0).
holding(nothing).
:- end_object.
:- object(water_consort, extends(blue_faction)).
level(1.0).
holding(nothing).
:- end_object.
이제이 꽤 많이 간단합니다 사용 :
?- fire_warrior::compute(attack, X).
X = 13.5.
?- water_consort::compute(attack, X).
X = 9.0.
내가 희망이 도움이!
와우, 처음에는 "predicate (list [], Variables, Variable)"쿼리가보다 세련된 쿼리를 작성하는 방법을 알아보기 위해 추적을 실행하는 흥미로운 읽기가있었습니다. –
Logtalk의 권장 사항을 살펴보면 오늘 밤 읽어 볼 수 있습니다.당신의 예제를 보았을 때, 그것은 내가 필요한 애드온과 프로그래밍 스타일임을 알 수 있습니다. 당신은 관계를 명확하게 볼 수 있습니다. 그리고 의미 론적 다이어그램을 보면, 어떻게 보일지 이미 이해할 수 있습니다. 프레임이 무엇인지 이해하지 못할 수도 있지만 Logtalk은 시각적 인면을 코드로 변환하는 데 적합합니다. 나는 오늘 밤 이것을 보게되어 정말 기쁩니다. –
이 설명이 없으면 관련성을 보지 못했기 때문에 당신은 잘 마시는 음료를 마셔야합니다. –