天天看点

comp3411辅导assignment2

文章目录

  • ​​1 内容分析​​
  • ​​1.1​​
  • ​​1.2 模拟机器人​​
  • ​​1.2.1 代码使用​​
  • ​​1.1.4 test1成功,深度优先​​
  • ​​1.1.3 test2失败,也就是说,深度优先失败的原因​​
  • ​​1.1.4 test3 id search iggs​​
  • ​​1.2 题目详情​​
  • ​​1.3 代码解析​​
  • ​​inter_construction​​
  • ​​Intra-construction.​​
  • ​​ass2 详情​​

1 内容分析

1.1

这道题很简单

将lists中的所有内容加和。

1.2 模拟机器人

首先看看这道题是要干什么。

用老师给的代码解决书上的一道题。

首先看要解决的这道题的题意:

是绕墙走。

comp3411辅导assignment2

代码里是绕垃圾走。

​​

​注意可以用write输出,如何输出结构体里的变量。​

​ 这里要解诀3个问题:

  1. plan的思路是什么?
  2. id_plan的思路又是什么?
  3. 为什么test1成功而test2失败?
  4. 为什么id_plan又能够成功?

plan的思路很简单,就是使用深度优先,假设有一个可以通过某动作到达的中间状态,然后就枚举这个动作。

5. id_plan()其实就是迭代式的深度优先,融合了深度优先和广度优先的区别,append(Plan,,)这个用法很神奇,因为第2个和第3个变量为空,其实也就意味着Plan可以是任意长度,所以在id_plan里的append这句,依次认为Plan是空列表,一个元素的列表,2,3,4,5,6,…个元素的列表,然后去plan中深度优先,所以就设定了深度。当比如6条路还找不到时,就返回到上一层,把6条路的所有可能路径都遍历一遍。

6. test2失败需要仔细观察test1和test2的不同之处,其实在后期,test2的所有路径都是选择的path,机器人把篮子推来推去!陷入了循环,路径一直延长,最后爆栈。这里和Prolog如何选择多个可选项的某一个也有关系,总而言之,prolog每次就选push。上一条路径和这条路径陷入了同一种可以选push的情况。

7. 因为id_plan限制了深度。这里就要说说迭代试相比单纯的深度优先的优势了。

1.2.1 代码使用

关于lists的使用:

% double_digit :- 1 is 1. % =:= is  全是数字,或者是数字的表达式,用=:=,

% is_even(X) :- Y is X//2, X is 2 * Y. %10 // 2 = 5, 5*2 == 10

% is_even(X) :- Y is mod(X, 2), 0 is Y. %10 // 2 = 5, 5*2 == 10

% is_even(X) :- Y is mod(X, 2), Y is 0. %10 // 2 = 5, 5*2 == 10


% query 里,如果有变量,则用is,并且变量在前,因为要给变量赋值。只能是  变量:=表达式,不能是表达式:=变量。
% 代码里,变量和变量相比较,可以是is也可以是=:=
% 代码里,变量和非变量相比较,可以是is也可以是=:=

% List1 :- [a,b,c].

% lists的表示,[] 
% 库函数,member()    length  reverse  | append

% Get the length of a list
% length([1,2,3], X).

% Find out if a value is in a list with member
% List1 = [a,b,c].
% member(a, List1). = yes

% We could also get all members of a list with a variable
% member(X, [a, b, c, d]).

% Reverse a list
% reverse([1,2,3,4,5], X).

% Concatenate 2 lists
% append([1,2,3], [4,5,6], X).      

1.1.4 test1成功,深度优先

[trace]  ?- test1(X).
   Call: (8) test1(_3818) ? creep
   Call: (9) plan(state(door, corner, floor(middle)), state(_4030, _4032, in_basket), _3818) ? creep
   Call: (10) action(_4038, state(door, corner, floor(middle)), _4062) ? creep
   Exit: (10) action(go(door, _4046), state(door, corner, floor(middle)), state(_4046, corner, floor(middle))) ? creep
   Call: (10) plan(state(_4046, corner, floor(middle)), state(_4030, _4032, in_basket), _4040) ? creep
   Call: (11) action(_4058, state(_4046, corner, floor(middle)), _4082) ? creep
   Exit: (11) action(pickup, state(middle, corner, floor(middle)), state(middle, corner, held)) ? creep
   Call: (11) plan(state(middle, corner, held), state(_4030, _4032, in_basket), _4060) ? creep
   Call: (12) action(_4072, state(middle, corner, held), _4096) ? creep
   Exit: (12) action(go(middle, _4080), state(middle, corner, held), state(_4080, corner, held)) ? creep
   Call: (12) plan(state(_4080, corner, held), state(_4030, _4032, in_basket), _4074) ? creep
   Call: (13) action(_4092, state(_4080, corner, held), _4116) ? creep
   Exit: (13) action(drop, state(corner, corner, held), state(corner, corner, in_basket)) ? creep
   Call: (13) plan(state(corner, corner, in_basket), state(_4030, _4032, in_basket), _4094) ? creep
   Exit: (13) plan(state(corner, corner, in_basket), state(corner, corner, in_basket), []) ? creep
   Exit: (12) plan(state(corner, corner, held), state(corner, corner, in_basket), [drop]) ? creep
   Exit: (11) plan(state(middle, corner, held), state(corner, corner, in_basket), [go(middle, corner), drop]) ? creep
   Exit: (10) plan(state(middle, corner, floor(middle)), state(corner, corner, in_basket), [pickup, go(middle, corner), drop]) ? creep
   Exit: (9) plan(state(door, corner, floor(middle)), state(corner, corner, in_basket), [go(door, middle), pickup, go(middle, corner), drop]) ? creep
   Exit: (8) test1([go(door, middle), pickup, go(middle, corner), drop]) ? creep
X = [go(door, middle), pickup, go(middle, corner), drop] .      

1.1.3 test2失败,也就是说,深度优先失败的原因

最后会一直重复push操作。

test2 调用栈如下

[trace]  ?- test2(X).
   Call: (8) test2(_1084) ? creep
   Call: (9) plan(state(door, corner, floor(middle)), state(door, corner1, in_basket), _1084) ? creep
   Call: (10) action(_1304, state(door, corner, floor(middle)), _1328) ? creep
   Exit: (10) action(go(door, _1312), state(door, corner, floor(middle)), state(_1312, corner, floor(middle))) ? creep
   Call: (10) plan(state(_1312, corner, floor(middle)), state(door, corner1, in_basket), _1306) ? creep
   Call: (11) action(_1324, state(_1312, corner, floor(middle)), _1348) ? creep
   Exit: (11) action(pickup, state(middle, corner, floor(middle)), state(middle, corner, held)) ? creep
   Call: (11) plan(state(middle, corner, held), state(door, corner1, in_basket), _1326) ? creep
   Call: (12) action(_1338, state(middle, corner, held), _1362) ? creep
   Exit: (12) action(go(middle, _1346), state(middle, corner, held), state(_1346, corner, held)) ? creep
   Call: (12) plan(state(_1346, corner, held), state(door, corner1, in_basket), _1340) ? creep
   Call: (13) action(_1358, state(_1346, corner, held), _1382) ? creep
   Exit: (13) action(drop, state(corner, corner, held), state(corner, corner, in_basket)) ? creep
   Call: (13) plan(state(corner, corner, in_basket), state(door, corner1, in_basket), _1360) ? creep
   Call: (14) action(_1372, state(corner, corner, in_basket), _1396) ? creep
   Exit: (14) action(push(corner, _1380), state(corner, corner, in_basket), state(_1380, _1380, in_basket)) ? creep
   Call: (14) plan(state(_1380, _1380, in_basket), state(door, corner1, in_basket), _1374) ? creep
   Call: (15) action(_1392, state(_1380, _1380, in_basket), _1416) ? creep
   Exit: (15) action(push(_1380, _1400), state(_1380, _1380, in_basket), state(_1400, _1400, in_basket)) ? creep
   Call: (15) plan(state(_1400, _1400, in_basket), state(door, corner1, in_basket), _1394) ? creep
   Call: (16) action(_1412, state(_1400, _1400, in_basket), _1436) ? creep
   Exit: (16) action(push(_1400, _1420), state(_1400, _1400, in_basket), state(_1420, _1420, in_basket)) ? creep
   Call: (16) plan(state(_1420, _1420, in_basket), state(door, corner1, in_basket), _1414) ? creep
   Call: (17) action(_1432, state(_1420, _1420, in_basket), _1456) ? creep
   Exit: (17) action(push(_1420, _1440), state(_1420, _1420, in_basket), state(_1440, _1440, in_basket)) ? creep
   Call: (17) plan(state(_1440, _1440, in_basket), state(door, corner1, in_basket), _1434) ? creep
   Call: (18) action(_1452, state(_1440, _1440, in_basket), _1476) ? creep
   Exit: (18) action(push(_1440, _1460), state(_1440, _1440, in_basket), state(_1460, _1460, in_basket)) ? creep
   Call: (18) plan(state(_1460, _1460, in_basket), state(door, corner1, in_basket), _1454) ? creep
   Call: (19) action(_1472, state(_1460, _1460, in_basket), _1496) ? creep
   Exit: (19) action(push(_1460, _1480), state(_1460, _1460, in_basket), state(_1480, _1480, in_basket)) ? creep
   Call: (19) plan(state(_1480, _1480, in_basket), state(door, corner1, in_basket), _1474) ? creep
   Call: (20) action(_1492, state(_1480, _1480, in_basket), _1516) ? creep
   Exit: (20) action(push(_1480, _1500), state(_1480, _1480, in_basket), state(_1500, _1500, in_basket)) ? creep
   Call: (20) plan(state(_1500, _1500, in_basket), state(door, corner1, in_basket), _1494) ? creep
   Call: (21) action(_1512, state(_1500, _1500, in_basket), _1536) ? creep
   Exit: (21) action(push(_1500, _1520), state(_1500, _1500, in_basket), state(_1520, _1520, in_basket)) ? creep
   Call: (21) plan(state(_1520, _1520, in_basket), state(door, corner1, in_basket), _1514) ? creep
   Call: (22) action(_1532, state(_1520, _1520, in_basket), _1556) ? creep
   Exit: (22) action(push(_1520, _1540), state(_1520, _1520, in_basket), state(_1540, _1540, in_basket)) ? creep
   Call: (22) plan(state(_1540, _1540, in_basket), state(door, corner1, in_basket), _1534) ? creep
   Call: (23) action(_1552, state(_1540, _1540, in_basket), _1576) ? creep
   Exit: (23) action(push(_1540, _1560), state(_1540, _1540, in_basket), state(_1560, _1560, in_basket)) ? creep
   Call: (23) plan(state(_1560, _1560, in_basket), state(door, corner1, in_basket), _1554) ? creep
   Call: (24) action(_1572, state(_1560, _1560, in_basket), _1596) ? creep
   Exit: (24) action(push(_1560, _1580), state(_1560, _1560, in_basket), state(_1580, _1580, in_basket)) ? creep
   Call: (24) plan(state(_1580, _1580, in_basket), state(door, corner1, in_basket), _1574) ? creep
   Call: (25) action(_1592, state(_1580, _1580, in_basket), _1616) ? creep
   Exit: (25) action(push(_1580, _1600), state(_1580, _1580, in_basket), state(_1600, _1600, in_basket)) ? creep
   Call: (25) plan(state(_1600, _1600, in_basket), state(door, corner1, in_basket), _1594) ? creep
   Call: (26) action(_1612, state(_1600, _1600, in_basket), _1636) ? creep
   Exit: (26) action(push(_1600, _1620), state(_1600, _1600, in_basket), state(_1620, _1620, in_basket)) ? creep
   Call: (26) plan(state(_1620, _1620, in_basket), state(door, corner1, in_basket), _1614) ? creep
   Call: (27) action(_1632, state(_1620, _1620, in_basket), _1656) ? creep
   Exit: (27) action(push(_1620, _1640), state(_1620, _1620, in_basket), state(_1640, _1640, in_basket)) ? creep
   Call: (27) plan(state(_1640, _1640, in_basket), state(door, corner1, in_basket), _1634) ? creep
   Call: (28) action(_1652, state(_1640, _1640, in_basket), _1676) ? creep
   Exit: (28) action(push(_1640, _1660), state(_1640, _1640, in_basket), state(_1660, _1660, in_basket)) ? creep
   Call: (28) plan(state(_1660, _1660, in_basket), state(door, corner1, in_basket), _1654) ? creep
   Call: (29) action(_1672, state(_1660, _1660, in_basket), _1696) ? creep
   Exit: (29) action(push(_1660, _1680), state(_1660, _1660, in_basket), state(_1680, _1680, in_basket)) ? creep
   Call: (29) plan(state(_1680, _1680, in_basket), state(door, corner1, in_basket), _1674) ? creep
   Call: (30) action(_1692, state(_1680, _1680, in_basket), _1716) ? creep
   Exit: (30) action(push(_1680, _1700), state(_1680, _1680, in_basket), state(_1700, _1700, in_basket)) ? creep
   Call: (30) plan(state(_1700, _1700, in_basket), state(door, corner1, in_basket), _1694) ? creep
   Call: (31) action(_1712, state(_1700, _1700, in_basket), _1736) ? creep
   Exit: (31) action(push(_1700, _1720), state(_1700, _1700, in_basket), state(_1720, _1720, in_basket)) ? creep
   Call: (31) plan(state(_1720, _1720, in_basket), state(door, corner1, in_basket), _1714) ? creep
   Call: (32) action(_1732, state(_1720, _1720, in_basket), _1756) ? creep
   Exit: (32) action(push(_1720, _1740), state(_1720, _1720, in_basket), state(_1740, _1740, in_basket)) ? creep
   Call: (32) plan(state(_1740, _1740, in_basket), state(door, corner1, in_basket), _1734) ? creep
   Call: (33) action(_1752, state(_1740, _1740, in_basket), _1776) ? creep
   Exit: (33) action(push(_1740, _1760), state(_1740, _1740, in_basket), state(_1760, _1760, in_basket)) ? creep
   Call: (33) plan(state(_1760, _1760, in_basket), state(door, corner1, in_basket), _1754) ? creep
      

1.1.4 test3 id search iggs

Plan: []

Plan: [_3910]

Plan: [_3910,_3922]

Plan: [_3910,_3922,_3934]

Plan: [_3910,_3922,_3934,_3946]

Plan: [_3910,_3922,_3934,_3946,_3958]

Plan: [_3910,_3922,_3934,_3946,_3958,_3970]

X = [go(door, middle), pickup, go(middle, corner), drop, push(corner, corner1), go(corner1, door)] .

这个使用append的操作,是如何实现iterative deepening planner呢?

% Iterative deepening planner
% Backtracking to "append" generates lists of increasing length
% Forces "plan" to ceate fixed length plans

id_plan(Start, Goal, Plan) :-
    append(Plan, _, _),
    % write('Plan: '), write(Plan), nl,
    plan(Start, Goal, Plan).      

1.2 题目详情

这题就不说了,其实主要就是给了一个代码,修改这个代码适合题目。

这个原本的代码,只需要修改action那里的代码,planner那里完全不用改就可以成功了。

1.3 代码解析

1.3代码比较多。

​​​:-op​​ :op是定义运算符的操作,具体用法如下:

:- op(Precedence, Type, Name).      

Precedence是介于 0 和 1200 之间的数字。在prolog内部,=的优先级是 700,+的优先级是 500,*优先级是400。如果我们自定义的运算符是600,那运算的时候,600大于500和400,​

​*​

​​和+就会后运算。

类型是指定运算符的类型和关联性。Type的外观有以下几种可能性:

中缀: xfx, xfy, yfx

前缀:fx, fy

后缀:xf, yf      

Name就简单了,单纯说明我们新定义的运算符的名字是什么。

inter_construction

inter_construction(C1 <- B1, C2 <- B2, C1 <- Z1B, C2 <- Z2B, C <- B) :-
C1 \= C2,
intersection(B1, B2, B),
gensym(z, C),
subtract(B1, B, B11),
subtract(B2, B, B12),
append(B11, [C], Z1B),
append(B12, [C], Z2B).      
  1. The first line the program assumes that the first two arguments are given as

    propositional clauses. The remaining three arguments are the output clauses, as in the

    example above.

这句话的意思是说,我们建的这个函数,总共有5个参数,10个变量,其实真正用的时候,我们可以任意用原子值填充一些变量,那剩下的变量就会根据规则去推理。不过,我们实际用的时候,会填充前两个参数中的4个变量,推理剩下的3个参数中的6个变量。

实验,参数可以是多个变量:

%
test(X+Y, Z) :-
    Z is X+Y.
test(1+2,Z).
Z=3      
  1. intersection()
?- intersection([1,2],[1],X).
X = [1].      
  1. gensym
  2. subtract(list1,list2, target)

subtract()把list1中和list2含有的元素都删除掉。

  1. gensym(z,C)

    就是生成符号的意思。generate symbol,内置命令,z是base,第一次用gensym(z,C)就是用z1绑定C,[C]=z1

  2. append(B12, [C], Z2B),将B12和[C]的绑定,也就是z1结合在一起。

    subset(X, Y),

    where X is a subset of Y.

Intra-construction.

ass2 详情

COMP3411/9814 Artificial Intelligence

Term 1, 2022

DRAFT

Assignment 1 – Prolog and Machine Learning

Due: Week 10 - 10pm Friday 22 April

Marks: 20% of final assessment for COMP3411/9814 Artificial Intelligence

This assignment has two parts: Prolog programming and using a machine learning

toolkit. The first part will be submitted as a Prolog source file and the second part as a

PDF file.

Part 1 - Prolog

At the top of your ,ile, place a comment containing your full name, student

number and assignment name. You may add additional information like the date

the program was completed, etc. if you wish.

At the start of each Prolog predicate, write a comment describing the operation of

the predicate.

A signi,icant part of completing this assignment will be testing the code you write

to make sure that it works correctly. To do this, you will need to design test cases

that exercise every part of the code.

It is important to use exactly the names given below for your predicates,

otherwise the automated testing procedure will not be able to 9ind your

predicates and you will lose marks. Even the capitalisation of your predicate

names must be as given below.

This assignment will be marked on functionality in the first instance. However, you

should always adhere to good programming practices in regard to structure, style and

comments, as described in the Prolog Dictionary. Submissions which score very low in

the automarking will be examined by a human marker, and may be awarded a few

marks, provided the code is readable.

Your code must work under the version of SWI Prolog used on the Linux machines in

the UNSW School of Computer Science and Engineering. If you develop your code on

any other platform, it is your responsibility to re-test and, if necessary, correct your code

when you transfer it to a CSE Linux machine prior to submission.

Your code will be run on a few simple tests when you submit. So, it is a good idea to

submit early and often so that potential problems with your code can be detected early.

You will be notified at submission time if your code produces any compiler warnings.

Please ensure that your final submission does not produce any such warnings

(otherwise, marks will be deducted).

Question 1.1: List Processing (4 marks)

Write a predicate sumsq_even(Numbers, Sum) that sums the squares of only the

even numbers in a list of integers.

Example:

?- sumsq_even([1,3,5,2,-4,6,8,-7], Sum).

Sum = 120

The example computes 22 + (-4)(-4) + 66 + 88). The sum for an empty list should

be 0.

To decide if a number is even or odd, you can use the built-in Prolog operator

N mod M, which computes the remainder after dividing the whole number N by the

whole number M. Thus a number N is even if the goal 0 is N mod 2 succeeds.

Remember that arithmetic expressions like X + 1 and N mod M are only evaluated, in

Prolog, if they appear after the is operator. So 0 is N mod 2 works, but N mod 2 is 0

doesn’t work.

Question 1.2: Planning (5 marks)

Modify the simple planner from the week 5 lecture so that it can solve the planning

problem in the textbook, Poole and Mackworth Section 6.1. Here, there is a robot can

can move around an office building, pickup mail and deliver coffee.

Like the rubbish pickup problem, actions can be representation by a triple:

action(Action, State, NewState)

where the state of the world is represented by a quintuple:

state(RLoc, RHC, SWC, MW, RHM)

• RLoc - Robot Location,

• RHC - Robot Has Coffee,

• SMC - Sam Wants Coffee,

• MW - Mail Waiting,

• RCM - Robot Carrying Mail

You are required to replace the action specifications by a new set that specify the state

transitions for each of the actions:

• mc - move clockwise

• mcc - move counterclockwise

• puc - pickup coffee

• dc - deliver coffee

• pum - pickup mail

• dm - deliver mail.

Do not alter the planner code, only the action clauses should be replaced.

You should only need to write one clause for each action, however, you might need

some addition clauses to help with the mc and mcc actions. Think about how to

represent the room layout.

Your program should be able to satisfy queries such as:

?- id_plan(

state(lab, false, true, false, false),

state(_, _, false, _, ),

Plan).

Plan = [mc, mc, puc, mc, dc]

which asks the robot to get Sam coffee. Note that the values of the state variables, RHC,

SWC, MW, RHM are boolean and we’ve used the constants true and false, to represent

the boolean values. The initial state in this example has the robot in the lab, the robot

does not have any coffee, Sam wants coffee, there is no mail waiting and the robot does

not have any mail. The goal state is where the the Sam no longer wants coffee. Note that

the anonymous variable, ‘’, indicates that we don’t care what the other values are.

To test your action specifications, think about how you would ask the robot to pickup

mail. What about if Sam want coffee and there was mail waiting?

Do not leave any testing code on your submitted file.

Question 1.3: Inductive Logic Programming

Duce is a program devised by Muggleton [3] to perform learning on a set of

propositional clauses. The system includes 6 operators that transform pairs of clauses

into a new set of clauses. Your job is to write Prolog programs to implement 2 of the 6

operators. One is given as an example to get you started.

Inter-construction. This transformation takes two rules, with different heads, such as

x <- [b, c, d, e]

y <- [a, b, d, f]

and replaces them with rules

x <- [c, e, z]

y <- [a, f, z]

z <- [b, d]

i.e. we find the intersection of the bodies of the first two clauses, invent a new predicate

symbol, z, and create the clause z ← [b, d]. Create two new clauses which are the

original clauses rewritten to replace [b, d] by z.

To make processing the rules easier, we represent the body of the clause by a list and we

define the operator <- to mean “implied by” or “if’.

A Prolog program to implement inter-construction is given as an example to give you

hints about how to write the two operators.

:- op(300, xfx, <-).

inter_construction(C1 <- B1, C2 <- B2, C1 <- Z1B, C2 <- Z2B, C <- B) :-

C1 = C2,

intersection(B1, B2, B),

gensym(z, C),

subtract(B1, B, B11),

subtract(B2, B, B12),

append(B11, [C], Z1B),

append(B12, [C], Z2B).

First, we define <- as an operator that will allow us to use the notation x <- y. The

program uses Prolog built-in predicates to perform set operations on lists and to

generate new symbols.

  1. The first line the program assumes that the first two arguments are given as

    propositional clauses. The remaining three arguments are the output clauses, as in the

    example above.

  2. inter_construction operates on two clauses that gave different heads, i.e. C1 = C2.
  3. We then find the interaction of the bodies of the clauses and call it, B.
  4. gensym is a builtin predicate that creates a new name from a base name. So

    gensym(z, C) binds C to z1. Every subsequent call to gensym, with base z, will

    create names, z2, z3, …. Calling reset_gensym will restart the numbering sequence.

  5. At this point the last argument C <- B = z1<-[b, d] because C is bound to z1 and

    B is the intersection [b, d].

  6. The bodies Z1B and Z2B, are obtained by subtracting the intersection, B, from B1

    and B2 and appending the single element [C]. So we can run the program:

    ?- inter_construction(x <- [b, c, d, e], y <- [a, b, d, f], X, Y, Z).

    X = x<-[c, e, z1],

    Y = y<-[a, f, z1],

    Z = z1<-[b, d].

    obtaining the desired result.

    You will write programs for the other five operators, defined below. All of these

    programs can be created from the builtin predicates used in the inter-construction

    code. So all you have to do is work out how to combine them. The only other builtin

    predicate you may need is to test if one list is a subset of another with subset(X, Y),

    where X is a subset of Y.

    You can assume that the inputs will always be valid clauses and the lists will always be

    non-empty, i.e. with at least one element.

    Question 1.3 (a) (2 marks):

    Intra-construction. This transformation takes two rules, with the same head, such as

    x <- [b, c, d, e]

    x <- [a, b, d, f]

    and replaces the with rules

    x <- [b, d, z]

    z <- [c, e]

    z <- [a, f]

    That is, we merge the two, x, clauses, keeping the intersection and adding a new

    predicate, z, that distributes the differences to two new clauses.

    ?- intra_construction(x <- [b, c, d, e], x <- [a, b, d, f], X, Y, Z).

    X = x<-[b, d, z1],

    Y = z1<-[c, e],

    Z = z1<-[a, f].

    Question 1.3 (b) (2 marks):

    Absorption. This transformation takes two rules, with the different heads, such as

    x <- [a, b, c, d, e]

    y <- [a, b, c]

    and replaces the with rules

    x <- [y, d, e]

    y <- [a, b, c]

    Note that the second clause is unchanged. This operator checks to see if the body of one

    clause is a subset of the other. If it is, the common elements can be removed from the

    larger clause and replaced by the head of the smaller one.

    ?- absorption(x <- [a, b, c, d, e], y <- [a, b, c], X, Y).

    X = x<-[y, d, e],

    Y = y<-[a, b, c].

    Question 1.3 © (2 marks):

    Truncation. This is the simplest transformation. It takes two rules that have the same

    head and simply drops the differences to leave just one rule. For example

    x <- [a, b, c, d]

    x <- [a, c, j, k]

    are replaced by

    x <- [a, c]

    That is, the body of the new clause is just the intersection of the bodies of the input

    clauses.

    ?- truncation(x <- [a, b, c, d], x <- [a, c, j, k], X).

    X = x<-[a, c].

    The complete Duce algorithm performs a search, looking for combination of these

    operators that will lead to the greater compression over the database of examples. Here

    compression is measured by the reduction in the number of symbols in the database.

    You don’t have to worry about the search algorithm, just implement the operators, as

    above

    Part 2 - Machine Learning

    Question 2.1 (5 marks): Machine Learning

    For this question, you will the Weka machine learning toolkit to apply a variety of

    algorithms to a given dataset so that you can compare the results.

    Go to the Weka website and download the program and see the accompanying

    documentation for how to use it. There is much more on the Weka website and it also

    has online help.

    Use the data set Soybean Data Set that is provided as an example with Weka. The

    example data are in a directory called data, that is in Weka’s installation directory. On

    the Mac, this is in /Applications/weka-3.8.6.app/Contents/app/data. On Windows it is

    in C:\Program Files\Weka-3-8-6\data. On Linux, Weka creates a directory ~/wekafiles.

    You will try four learning algorithms:

    • J48 - decision tree learner

    • NaiveBayes - a naïve Bayes classifier

    • JRip - a rule learner

    • MultilayerPerceptron - a multilayer neural net algorithm

    Create a table based on the output:

    The last column is your subjective assessment of the readability of the output model.

    References

  7. Poole &Mackworth, Artificial Intelligence: Foundations of Computational

    Agents, Chapter 7, Supervised Machine Learning)

  8. ​​http://archive.ics.uci.edu/ml/datasets/Adult).​​
  9. Muggleton, S. (1987). Duce, An oracle based approach to constructive induction.

    Proceedings of the International Joint Conference on Artificial Intelligence, 287–

继续阅读