简体   繁体   English

比较事实值的Prolog谓词

[英]Prolog predicate that compares values in facts

This is my first time using Prolog 这是我第一次使用Prolog

I have employees 我有员工

employee(eID,firstname,lastname,month,year) 

example : 例如:

employee(1,liz,white,4,2000).
employee(2,ted,johnson,5,1998).

I want to make a predicate senior(X,Y) that will return true if the first employee is older in the company. 我想做一个谓词senior(X,Y) ,如果第一个员工在公司中年长,它将返回true。

I have this: 我有这个:

senior(X,Y) : -
  employee(X,firstname,lastname,month,year),
  employee(Y,firstname,lastname,month,year),
  X.year < Y.year.

but this always return false. 但这总是返回false。 I can't understand the reason. 我不明白原因。

How can I make this predicate work? 如何使该谓词起作用?

In Prolog, variables start with either an underscore or an upper case letter. 在Prolog中,变量以下划线或大写字母开头。 Eg firstname is an atom , ie a constant, but FirstName is a variable . 例如, firstname是一个原子 ,即一个常数,但是FirstName是一个变量 But, in your specific question, you don't care about the employee names. 但是,在您的特定问题中,您无需关心员工姓名。 Thus, you can replace those arguments by the anonymous variable: 因此,您可以将这些参数替换为匿名变量:

senior(X,Y) : -
  employee(X, _, _, Xmonth, Xyear),
  employee(Y, _, _, Ymonth, Yyear),
  ...

Can you now complete the code by writing the necessary comparisons using the Xmonth , Xyear , Ymonth , and Yyear variables? 您现在可以通过使用XmonthXyearYmonthYyear变量编写必要的比较来完成代码吗?

Is it mandatory that you do this with one rule? 用一条规则来执行此操作是强制性的吗? You could use one rule for comparing employees who were hired in different years, and a second rule for comparing employees who were hired in the same year. 您可以使用一个规则比较不同年份的雇员,使用第二个规则比较相同年份的雇员。 To expand on this, let's say you have employees listed this way: 为了对此进行扩展,假设您以这种方式列出了员工:

employee(eid,year,month,day)

and, of course, a list of employees. 当然还有雇员名单。 You could use the following three rules: 您可以使用以下三个规则:

% For employees that were hired in different years.
senior(Eid1,Eid2) :-
    employee(Eid1,X,_,_),
    employee(Eid2,Y,_,_),
    X<Y.

% For employees that were hired in the same year, different month.
senior(Eid1,Eid2) :-
    employee(Eid1,Year,X,_);
    employee(Eid2,Year,Y,_);    % Notice how one common variable "Year" is used
    X<Y.

% For employees that were hired in the same year, same month, different day,
% the rule is "expanded" from the previous one.
senior(Eid1,Eid2) :-
    employee(Eid1,Year,Month,X);
    employee(Eid2,Year,Month,Y);
    X<Y.

Make sure you don't forget and replace "Year" and/or "Month" with underscores, because then somebody hired on 2010-01-01 (ISO 8601) would be shown as senior to someone hired on 2005-12-12 . 确保您不要忘记并用下划线代替“ Year”和/或“ Month”,因为这样,在2010-01-01(ISO 8601)雇用的人员将比在2005-12-12雇用的人员显示为高级。

Then again, perhaps you should catalogue all dates in ISO 8601:2004 . 再说一次,也许您应该在ISO 8601:2004中对所有日期进行分类。 No matter how big your employee list, you could write a small script to convert 无论您的员工人数多大,都可以编写一个小的脚本进行转换

employee(eID,firstname,lastname,month,year)

to

employee(eID,firstname,lastname,yyyymm)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM