-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-pc.lp
153 lines (115 loc) · 4.26 KB
/
build-pc.lp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
%*
% Program that build a PC using given components.
%
% Takes into account the price, and a user defined 'rate'.
% Some preferences are also tunable, in order to get the perfect build.
%
% Parsing a website selling components in order to get names,
% prices and requirements/incompatibilities is not in the scope of that file.
%
% The file is divided into 5 parts:
% data: the raw data about components
% preferences: tunable preferences of user
% knowledge: domain knowledge about PC building
% expansion: transform data of 3 previous parts into data for the model
% model: the engine computing builds
%
% Each output model is a build that costs less than the maximal cost.
% Builds are sorted by increasing rating.
*%
#const max_cost=800.
%%%%%%%%%%%%%%%%
% DATA
%%%%%%%%%%%%%%%%
component(gpu,"A").
price(gpu,"A",330).
rate(gpu,"A",10).
% Another way to write down the info: type, name, price, rate.
component(gpu,"B",200,7).
component(gpu,"embedded graphic chipset",0,4).
% CPU C embeds a graphic card, that *may* be used.
require(gpu,"embedded graphic chipset",cpu,"C").
component(cpu,"A",400,10).
component(cpu,"B",150,6).
component(cpu,"C",250,6).
% CPU C embeds a graphic card.
require(cpu,"C",gpu,"embedded graphic chipset").
component(ram,"4Go",70,4).
component(ram,"8Go",130,7).
component(ram,"16Go",220,9).
component(hdd,"500Go",40,5).
component(hdd,"1To",50,7).
component(hdd,"2To",80,9).
component(ssd,"50Go",100,5).
component(ssd,"100Go",180,7).
component(motherboard,"full",140,8).
component(motherboard,"basic",70,5).
incompatible(motherboard,"basic",gpu,"embedded graphic chipset").
incompatible(motherboard,"basic",ram,"16Go").
component(cpufan,"big",100,8).
component(cpufan,"small",40,5).
require_one(cpufan,"small",cpu,("B";"C")). % the small fan isn't enough for the CPU A
component(case,"big&quiet",150,7).
component(case,"big",120,5).
component(case,"small&quiet",100,7).
component(case,"small",70,5).
% the two small cases are not compatible with many components.
incompatible(case,("small";"small&quiet"),gpu,"A").
incompatible(case,("small";"small&quiet"),motherboard,"full").
incompatible(case,("small";"small&quiet"),cpufan,"big").
%%%%%%%%%%%%%%%%
% PREFERENCES
%%%%%%%%%%%%%%%%
% SSD is not necessary.
optional(ssd).
% Set importances of various components (default is 5).
set_importance(gpu,10). % better have a good GPU
set_importance(motherboard,3).
set_importance(ssd,4).
%%%%%%%%%%%%%%%%
% KNOWLEDGE
%%%%%%%%%%%%%%%%
% CPU and motherboard must have the same bridge.
incompatible(cpu,CPU,motherboard,MB):- component(cpu,CPU) ; component(motherboard,MB) ;
bridge(cpu,CPU,CPU_Bridge) ; bridge(motherboard,MB,MB_Bridge) ;
MB_Bridge != CPU_Bridge.
%%%%%%%%%%%%%%%%
% EXPANSION
%%%%%%%%%%%%%%%%
% Extract components data.
component(O,Name):- component(O,Name,_,_).
price(O,Name,P):- component(O,Name,P,_).
rate(O,Name,R):- component(O,Name,_,R).
% By default, a component is necessary.
minimal_quantity(O,1):- component(O) ; not optional(O).
minimal_quantity(O,0):- component(O) ; optional(O).
% By default, all components are equivalent in importance.
importance(O,5):- component(O) ; not set_importance(O,_).
importance(O,I):- component(O) ; set_importance(O,I).
% Embedding is synonymous to symmetric requirement.
require(C1,N1,C2,N2):- embeds(C1,N1,C2,N2).
require(C2,N2,C1,N1):- embeds(C1,N1,C2,N2).
%%%%%%%%%%%%%%%%
% MODEL
%%%%%%%%%%%%%%%%
component(O):- component(O,_).
% Choose one of each components.
Q { use(O,X): component(O,X) } 1 :- component(O) ; minimal_quantity(O,Q).
% Requirements of a component must be in the config.
use(O2,N2):- use(O1,N1) ; require(O1,N1,O2,N2).
1 { use(O2,X): require_one(O1,N1,O2,X) } 1:- use(O1,N1) ; require_one(O1,N1,O2,_).
% Avoid any incompatibilities.
:- incompatible(O1,N1,O2,N2) ; use(O1,N1) ; use(O2,N2).
% Compute the total cost, rating and elements of the configuration.
total_cost(T):- T=#sum{C,O: use(O,I), price(O,I,C)}.
total_rate(T):- T=#sum{R*I,O: use(O,C), rate(O,C,R), importance(O,I)}.
total_size(T):- T={use(_,_)}.
% The total cost must be inferior to the maximal.
:- total_cost(T) ; T>max_cost.
% Maximize the overrall rating.
#maximize{S:total_rate(S)}.
#show.
#show use/2.
#show total_cost/1.
#show total_rate/1.
#show total_size/1.