prolog语言实践---知识表示个人作业

We are given the following knowledge base of travel information:

byCar(auckland,hamilton).

byCar(hamilton,raglan).

byCar(valmont,saarbruecken).

byCar(valmont,metz).

byTrain(metz,frankfurt).

byTrain(saarbruecken,frankfurt).

byTrain(metz,paris).

byTrain(saarbruecken,paris).

byPlane(frankfurt,bangkok).

byPlane(frankfurt,singapore).

byPlane(paris,losAngeles).

byPlane(bangkok,auckland).

byPlane(losAngeles,auckland).

Write a predicate travel/2 which determines whether it is possible to travel from one place to another by ‘chaining together’ car, train, and plane journeys. For example, your program should answer ‘yes’ to the query travel(valmont,raglan).

% Travel predicate with two locations

travel(X, Y) :- byCar(X, Y).

travel(X, Y) :- byTrain(X, Y).

travel(X, Y) :- byPlane(X, Y).

travel(X, Y) :-

    (byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),

travel(Z, Y).        三个交通方式直接取并,然后再取交

So, by using travel/2 to query the above database, you can find out that it is possible to go from Vamont to Raglan. In case you are planning a travel, that’s already very good information, but what you would then really want to know is how exactly to get from Valmont to Raglan.

Write a predicate travel/3 which tells you how to travel from one place to another.

The program should, e.g., answer ‘yes’ to the query travel(valmont,paris,go(valmont,metz,go(metz,paris)))

and X = go(valmont,metz,go(metz,paris,go(paris,losAngeles))) to the query travel(valmont,losAngeles,X).

travel(X, Y,go(X,Y)) :- byCar(X, Y).

travel(X, Y,go(X,Y)) :- byTrain(X, Y).

travel(X, Y,go(X,Y)) :- byPlane(X, Y).

travel(X, Y,go(X,Z,Journey)) :-

    (byCar(X, Z) ; byTrain(X, Z) ; byPlane(X, Z)),

    travel(Z, Y,Journey).

*************找清楚递归规则很重要,同时注意,分号表示并,逗号表示交。

第二题:

1. Write a 3-place predicate combine1 which takes three lists as arguments and

combines the elements of the first two lists into the third as follows:

?- combine1([a,b,c],[1,2,3],X).

X = [a,1,b,2,c,3]

?- combine1([foo,bar,yip,yup],[glub,glab,glib,glob],Result).

Result = [foo,glub,bar,glab,yip,glib,yup,glob]

combine1([], [], []).

combine1([X|Xs], [Y|Ys], [X,Y|Zs]) :-

combine1(Xs, Ys, Zs).

2. Now write a 3-place predicate combine2 which takes three lists as arguments

and combines the elements of the first two lists into the third as follows:

?- combine2([a,b,c],[1,2,3],X).

X = [[a,1],[b,2],[c,3]]

?- combine2([foo,bar,yip,yup],[glub,glab,glib,glob],Result).

Result = [[foo,glub],[bar,glab],[yip,glib],[yup,glob]]

combine2([], [], []).

combine2([X|Xs], [Y|Ys], [[X,Y]|Zs]) :-

combine2(Xs, Ys, Zs).

3. Finally, write a 3-place predicate combine3 which takes three lists as arguments

and combines the elements of the first two lists into the third as follows:

?- combine3([a,b,c],[1,2,3],X).

X = [join(a,1),join(b,2),join(c,3)]

?- combine3([foo,bar,yip,yup],[glub,glab,glib,glob],R).

R = [join(foo,glub),join(bar,glab),join(yip,glib),join(yup,glob)]

combine3([], [], []).

combine3([X|Xs], [Y|Ys], [join(X,Y)|Zs]) :-

combine3(Xs, Ys, Zs).

第三题:

1. Write a predicate mysubset/2 that takes two lists (of constants) as arguments and

checks, whether the first list is a subset of the second.

% Base case: an empty list is a subset of any list

mysubset([], _).

% Check if the first element of the first list is in the second list

mysubset([X|Xs], Y) :-

    member(X, Y),       内置函数

mysubset(Xs, Y).

?-mysubset([a,b],[a,b,c]).

?-mysubset([d,e],[a,b,c]).

2. Write a predicate mysuperset/2 that takes two lists as arguments and checks,

whether the first list is a superset of the second.

% Base case: an empty list is a superset of any list

mysuperset(_, []).

% Check if the first element of the second list is in the first list

mysuperset(X, [Y|Ys]) :-

    member(Y, X),

mysuperset(X, Ys).

?-mysuperset([a,b,c],[a,b]).

?-mysuperset([a,b,c],[d,e]).

第四题:

Write a Prolog program to implement the predicate frequencies(L,M), which takes as input a list L and returns a list of pairs [x,n], where x is an element of L and n is the number of times x appears in L. Here are some sample runs in SWI Prolog:

?- frequencies([a,b,a,c,a,c,d,a],L).

L = [[a, 4], [b, 1], [c, 2], [d, 1]]

Yes

?- frequencies([],L).

L = []

Yes

frequencies([],[]).
frequencies([H|Y],L) :-
   frequencies(Y,L1),
check(H,L1,L).
 
check(H,[],[H,1]).
 
check(H,[[Y,K]|L],[[Y,K1]|L]):-
   H = Y,
K1 is K +1.
 
check(H,[[Y,K]|L],[[Y,K]|M]) :-
   H \== Y,
check(H,L,M).
 
check(H,[H,K],[H,K1]):- K1 is K +1.
 
check(H,[Y,K],[[Y,K]|[H,1]]) :-
   H \== Y.

  1. 基本情况:

    • frequencies([], []).
    • 如果输入列表为空,频率列表也为空。
  2. 递归情况:

    • frequencies([H | Y], L) :- frequencies(Y, L1), check(H, L1, L).
    • 递归处理列表的尾部 (Y) 并获取频率列表 (L1)。
    • 调用 check/3 谓词根据列表的头 (H) 更新频率列表 (L)。
  3. check/3 谓词:

    • check(H, [], [H, 1]).
      • 如果列表为空,创建一个新列表 [H, 1],表示 H 的频率为 1。
    • check(H, [[Y, K] | L], [[Y, K1] | L]) :- H = Y, K1 is K + 1.
      • 如果 H 等于频率列表的头部,通过将 K 增加 1 来更新频率为 K1
    • check(H, [[Y, K] | L], [[Y, K] | M]) :- H \== Y, check(H, L, M).
      • 如果 H 与频率列表的头不同,保留当前头部并递归检查列表的其余部分 (L)。
    • check(H, [H, K], [H, K1]) :- K1 is K + 1.
      • 如果频率列表只有一个元素 [H, K],通过将 K 增加 1 来更新频率为 K1
    • check(H, [Y, K], [[Y, K] | [H, 1]]) :- H \== Y.
      • 如果元素 H 与频率列表的头不同,创建一个新条目 [H, 1]

总体而言,这个 Prolog 程序计算列表中每个元素的频率,并返回一个包含对 [元素, 频率] 的列表。check/3 谓词负责根据当前正在处理的元素更新频率列表。

第五题:

Assume that a binary tree is represented in Prolog using the function term

  tree(X,LeftSubTree,RightSubTree)

where X is the element at any node and LeftSubTree and RightSubTree are the left sub-tree and the right sub-tree for the node respectively. The term nil is used when there is no left sub-tree or right-tree. For example, the following function term:

tree(20,tree(10,nil,nil),tree(40,tree(30,nil,nil),nil))

would represent the following binary (search) tree:

           20

          /  \

        10    40

             / 

            30 

Recall that a binary search tree is a binary tree in which all the elements in the left sub-tree of a node are less than the element at the node and all the elements in the right sub-tree of a node are greater than the element at the node. Assume that the binary search tree is being used to represent a set of numbers with no duplicates. Write Prolog programs for the following predicates:

  • smallest(X,T) is true if X is the smallest element in the binary search tree T.
  • member(X,T) is true if X is an element in the binary search tree T.
  • height(T,H) is true if H is the height of the binary search tree T where height is defined as the length of the longest path from root to leaf node.

Smallest/2:

排序树:

smallest([],[]).

smallest(X, tree(X, nil, nil)).

smallest(X, tree(_, Left, _)) :-

    smallest(X, Left).

排序树只需要沿着左边找就是最小值。

Member/2:

member(X, tree(X, _, _)).

member(X, tree(Root, Left, _)) :-

    X < Root,

    member(X, Left).

member(X, tree(Root, _, Right)) :-

    X > Root,

member(X, Right).

Height/2:

height(nil, 0).

height(tree(_, Left, Right), H1) :-

    height(Left, LH),

    height(Right, RH),

  height(LeftSubTree,HL),
   height(RightSubTree,HR),
   max(HL,HR,H),
​H1 is H +1.

max(HL,HR,HL):- HL >= HR.
max(HL,HR,HR):- HL < HR.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值