Recursion Prolog中的递归等

Recursion Prolog中的递归等,recursion,prolog,transitive-closure,Recursion,Prolog,Transitive Closure,我在一家航空公司及其航班的序言中有一个知识库: flight(departure,arrive,day). flight(london,paris,monday). flight(paris,barcelona,thursday). flight(paris,madrid,sunday). flight(madrid,lisbon,saturday). 递归规则: connection(Departure,Arrive):-flight(Departure,Arrive,Day). conn

我在一家航空公司及其航班的序言中有一个知识库:

flight(departure,arrive,day).

flight(london,paris,monday).
flight(paris,barcelona,thursday).
flight(paris,madrid,sunday).
flight(madrid,lisbon,saturday).
递归规则:

connection(Departure,Arrive):-flight(Departure,Arrive,Day).
connection(Departure,Arrive):-flight(Departure,X,Day),connection(X,Arrive).
有了这一点,我可以问一个问题:伦敦和巴塞罗那之间是否存在联系

问题:
连接(伦敦,巴塞罗那)。

答案将是令人愤怒的。 但是我能做些什么规则/问题,它能给我更多的细节吗

例如:伦敦和巴塞罗那之间的联系是直接的还是间接的

其他问题:我想知道航班什么时候是间接的,哪个城市在中间?(在上面的例子中,它将是“巴黎”


有人能帮我弄明白吗?

我创建了一个使用天的简单程序。 在示例程序中,我假设三天

等待天数(3)。/*获取一周中指定的日期。例如,从周一开始的3天->周一、周二、周三*/

请调整等待天数。 我还做了其他更正

我用SWI-Prolog和LPA-Prolog检查了以下程序

/* flight_city(london,barcelona, monday). */

weekday( [sunday, monday, tuesday, wednesday, thursday, friday, saturday] ).
waiting_days( 3 ).   /* acquire the specified day of the week.  For example 3 day monday -> monday, tuesday, wednesday */


flight_city( Departure, Arrive, Day ) :-
        connection(Departure, Arrive, Day, []).

connection(Departure, Arrive, Day, City_list) :-
        flight(Departure, Arrive, Flight_Day),

        not( member( Departure, City_list ) ),

        waiting_days_get( Day, Days ),

        member( Flight_Day, Days ),
%       !,
        append( [Arrive, Departure], City_list, City_list2 ),
        reverse( City_list2, City_list3 ),

        write_city_list( City_list3 ),

        fail.

connection(Departure,Arrive, Day, City_list ) :-
        flight(Departure,X,Flight_Day),

        /* Prevention of an infinite loop */
        not( member( Departure, City_list ) ),

        waiting_days_get( Day, Days ),

        member( Flight_Day, Days ),

        append( [Departure], City_list, City_list2 ),

        connection(X, Arrive, Flight_Day, City_list2 ).


direct_check( 2, _, [] ) :- !.

direct_check( Citys_number, [_ | Result], Middle ) :-
        2 < Citys_number, !,
        middle_get( Result, Middle ).

direct_check( _, _, _ ) :- fail.


middle_get( [_], [] ) :- !.

middle_get( [First | Result], [First | Result2] ) :-
        middle_get( Result, Result2 ).


waiting_days_get( Today, Days ) :-
        weekday( Weekday ),
        waiting_days( Count ),
        ( 7 < Count -> Count2 is 7;
         Count2 is Count
        ),
        waiting_days_get_this_week( Weekday, Today, Count2, This_week_days ),
        length( This_week_days, Num2 ),
        Count3 is Count2 - Num2,
        waiting_days_get_next_week( Count3, Weekday, Next_week_days ),
        append( This_week_days, Next_week_days, Days ).



waiting_days_get_this_week( [Today |Result ], Today, Count, Days ) :-
        !,
        waiting_days_get_main( Count, [Today | Result], Days ).

waiting_days_get_this_week( [_ | Result], Today, Num, Days ) :-
        waiting_days_get_this_week(Result, Today, Num, Days ).


waiting_days_get_main( 0, _, [] ) :- !.

waiting_days_get_main( _, [], [] ) :- !.

waiting_days_get_main( Count, [Day | Result], [Day |Result2 ] ) :-
        Count2 is Count - 1,
        waiting_days_get_main( Count2, Result, Result2 ).



waiting_days_get_next_week( 0, _, [] ) :- !.

waiting_days_get_next_week( Count, [First | Result], [First | Days] ) :-
        Count2 is Count - 1,
        waiting_days_get_next_week( Count2, Result, Days ).


write_city_list( City_list3 ) :-

        length( City_list3, Citys_number ),

        direct_check( Citys_number, City_list3, Middle ),

        write( City_list3 ), nl,

        ( Citys_number == 2 -> write( 'direct' ), nl, nl;
         write( 'indirect' ), nl,
         write( Middle ), nl, nl
        ), !.



flight(london,paris,monday).
flight(paris,barcelona,thursday).
flight(paris,madrid,sunday).
flight(madrid,lisbon,saturday).
flight(london,tokyo,monday).
flight(tokyo, paris, monday).
flight(london,barcelona,monday).
flight(london,lisbon,monday).
flight(lisbon,barcelona,monday).
flight(tokyo,london,monday).
/*班机城市(伦敦,巴塞罗那,星期一)*/
工作日([星期日、星期一、星期二、星期三、星期四、星期五、星期六])。
等待天数(3)。/*获取一周中的指定日期。例如,3天星期一->星期一、星期二、星期三*/
航班城市(出发、到达、日期):-
连接(出发、到达、日期,[])。
连接(出发、到达、日期、城市列表):-
航班(起飞、到达、航班日),
非(成员(离任、城市名单)),
等待天数(天,天),
成员(航班日,天),
%       !,
追加([到达、离开]、城市列表、城市列表2),
反向(城市列表2,城市列表3),
编写城市列表(城市列表3),
失败。
连接(出发、到达、日期、城市列表):-
航班(起飞,X,航班日),
/*防止无限循环*/
非(成员(离任、城市名单)),
等待天数(天,天),
成员(航班日,天),
追加([出发]、城市列表、城市列表2),
连接(X、到达、航班日、城市列表2)。
直接支票(2,,[]):-!。
直接检查(城市编号,结果,中间):-
2<城市编号!,
中间(结果,中间)。
直接检查(u,u,u):-失败。
中得([[u],]):-!。
中间结果([第一个结果],[第一个结果2]):-
中间得到(结果,结果2)。
等待天数(今天,天):-
工作日(工作日),
等待天数(计数),
(7Count2为7;
Count2是Count
),
本周等待天数(工作日,今天,计数2,本周天数),
长度(本周天数,单位m2),
Count3是Count2-Num2,
等待日数下周数(计数3,工作日,下周数),
追加(本周、下周、天)。
本周等待天数([今日结果]、今日、计数、天数):-
!,
等待天数(计数[今天的结果],天)。
本周等待天数([[u124;结果],今天,天数):-
本周等待天数(结果、今天、天数)。
等待天数(0,[]):-!。
等待天数获取主(u,[],[]):-!。
等待天数(计数,[日结果],[日结果2]):-
Count2是Count-1,
等待天数(Count2,Result,Result2)。
等待天数下个星期(0,,[]):-!。
下周等待天数(计算[第一个结果],[第一个结果]):-
Count2是Count-1,
下周等待天数(计数2,结果,天数)。
填写城市列表(城市列表3):-
长度(城市列表3,城市编号),
直接检查(城市编号,城市列表3,中间),
书写(城市列表3),nl,
(Citys_number==2->write('direct')、nl、nl;
写(‘间接’),nl,
写(中间),nl,nl
), !.
航班(伦敦、巴黎,星期一)。
航班(巴黎,巴塞罗那,星期四)。
航班(巴黎,马德里,星期日)。
航班(马德里、里斯本,周六)。
航班(伦敦,东京,星期一)。
航班(东京,巴黎,星期一)。
航班(伦敦,巴塞罗那,星期一)。
航班(伦敦、里斯本,星期一)。
航班(里斯本,巴塞罗那,星期一)。
航班(东京,伦敦,星期一)。

我创建了一个使用天的简单程序。 在示例程序中,我假设三天

等待天数(3)。/*获取一周中指定的日期。例如,从周一开始的3天->周一、周二、周三*/

请调整等待天数。 我还做了其他更正

我用SWI-Prolog和LPA-Prolog检查了以下程序

/* flight_city(london,barcelona, monday). */

weekday( [sunday, monday, tuesday, wednesday, thursday, friday, saturday] ).
waiting_days( 3 ).   /* acquire the specified day of the week.  For example 3 day monday -> monday, tuesday, wednesday */


flight_city( Departure, Arrive, Day ) :-
        connection(Departure, Arrive, Day, []).

connection(Departure, Arrive, Day, City_list) :-
        flight(Departure, Arrive, Flight_Day),

        not( member( Departure, City_list ) ),

        waiting_days_get( Day, Days ),

        member( Flight_Day, Days ),
%       !,
        append( [Arrive, Departure], City_list, City_list2 ),
        reverse( City_list2, City_list3 ),

        write_city_list( City_list3 ),

        fail.

connection(Departure,Arrive, Day, City_list ) :-
        flight(Departure,X,Flight_Day),

        /* Prevention of an infinite loop */
        not( member( Departure, City_list ) ),

        waiting_days_get( Day, Days ),

        member( Flight_Day, Days ),

        append( [Departure], City_list, City_list2 ),

        connection(X, Arrive, Flight_Day, City_list2 ).


direct_check( 2, _, [] ) :- !.

direct_check( Citys_number, [_ | Result], Middle ) :-
        2 < Citys_number, !,
        middle_get( Result, Middle ).

direct_check( _, _, _ ) :- fail.


middle_get( [_], [] ) :- !.

middle_get( [First | Result], [First | Result2] ) :-
        middle_get( Result, Result2 ).


waiting_days_get( Today, Days ) :-
        weekday( Weekday ),
        waiting_days( Count ),
        ( 7 < Count -> Count2 is 7;
         Count2 is Count
        ),
        waiting_days_get_this_week( Weekday, Today, Count2, This_week_days ),
        length( This_week_days, Num2 ),
        Count3 is Count2 - Num2,
        waiting_days_get_next_week( Count3, Weekday, Next_week_days ),
        append( This_week_days, Next_week_days, Days ).



waiting_days_get_this_week( [Today |Result ], Today, Count, Days ) :-
        !,
        waiting_days_get_main( Count, [Today | Result], Days ).

waiting_days_get_this_week( [_ | Result], Today, Num, Days ) :-
        waiting_days_get_this_week(Result, Today, Num, Days ).


waiting_days_get_main( 0, _, [] ) :- !.

waiting_days_get_main( _, [], [] ) :- !.

waiting_days_get_main( Count, [Day | Result], [Day |Result2 ] ) :-
        Count2 is Count - 1,
        waiting_days_get_main( Count2, Result, Result2 ).



waiting_days_get_next_week( 0, _, [] ) :- !.

waiting_days_get_next_week( Count, [First | Result], [First | Days] ) :-
        Count2 is Count - 1,
        waiting_days_get_next_week( Count2, Result, Days ).


write_city_list( City_list3 ) :-

        length( City_list3, Citys_number ),

        direct_check( Citys_number, City_list3, Middle ),

        write( City_list3 ), nl,

        ( Citys_number == 2 -> write( 'direct' ), nl, nl;
         write( 'indirect' ), nl,
         write( Middle ), nl, nl
        ), !.



flight(london,paris,monday).
flight(paris,barcelona,thursday).
flight(paris,madrid,sunday).
flight(madrid,lisbon,saturday).
flight(london,tokyo,monday).
flight(tokyo, paris, monday).
flight(london,barcelona,monday).
flight(london,lisbon,monday).
flight(lisbon,barcelona,monday).
flight(tokyo,london,monday).
/*班机城市(伦敦,巴塞罗那,星期一)*/
工作日([星期日、星期一、星期二、星期三、星期四、星期五、星期六])。
等待天数(3)。/*获取一周中的指定日期。例如,3天星期一->星期一、星期二、星期三*/
航班城市(出发、到达、日期):-
连接(出发、到达、日期,[])。
连接(出发、到达、日期、城市列表):-
航班(起飞、到达、航班日),
非(成员(离任、城市名单)),
等待天数(天,天),
成员(航班日,天),
%       !,
追加([到达、离开]、城市列表、城市列表2),
反向(城市列表2,城市列表3),
编写城市列表(城市列表3),
失败。
连接(出发、到达、日期、城市列表):-
航班(起飞,X,航班日),
/*防止无限循环*/
非(成员(离任、城市名单)),
等待天数(天,天),
成员(航班日,天),
追加([出发]、城市列表、城市列表2),
连接(X、到达、航班日、城市列表2)。
直接支票(2,,[]):-!。
直接检查(城市编号,结果,中间):-
2<城市编号!,
中间(结果,中间)。
直接检查(u,u,u):-失败。
中得([[u],]):-!。
中间结果([第一个结果],[第一个结果2]