Hi all, we're working at a product configurator and want to implement a few new features. I think one of them is a CSP. It consists of a database of products and some constraints between them. In the GUI we want to use comboboxes to display the content of the DB - each DB attribute in a separate combobox. The main task of the program will be to determine all remaining possibilities of values for the comboboxes when the user selects the content of some of theses boxes to be one specific value. When this is implemented, the bonus task will be to repair a wrong selection of values by the user: the program has to suggest another selection that differs in as little attributes as possible from the user-selection. In step 1 the programm can choose the attributes to change. In step 2 the user can point out the attributes that the programm may change. Because I'm fairly new to Prolog and ECLiPSe and because I couldn't find anything alike this in the standard examples I'm asking you if you know of either an example I have missed or (even better :-) ) a solution for this problem. So far I have implemented the DB as following: :- lib(ic). :-local struct( hdd(id, formfactor, capacity, sone) ). hdd{id:'HD1', formfactor:'2.5', capacity:200, sone:0.9}. hdd{id:'HD2', formfactor:'2.5', capacity:750, sone:3.0}. hdd{id:'HD3', formfactor:'2.5', capacity:500, sone:1.2}. hdd{id:'HD4', formfactor:'2.5', capacity:300, sone:1.5}. :-local struct( case(id, type, color, power, formfactor) ). case{id:'C1', type:'Big', color:'grey', power:500, formfactor:['ATX', 'microATX']}. case{id:'C2', type:'Midi', color:'grey', power:350, formfactor:['ATX', 'BTX']}. case{id:'C3', type:'Mini', color:'grey', power:200, formfactor:['microATX']}. :-local struct( motherboard(id, socket, ram, formfactor, slot) ). motherboard{id:'MB1', socket:'775', ram:32, formfactor:'ATX', slot:['PCI-E']}. motherboard{id:'MB2', socket:'AM2', ram:32, formfactor:'ATX', slot:['PCI-E']}. motherboard{id:'MB3', socket:'754', ram:8, formfactor:'microTX', slot:['AGP']}. motherboard{id:'MB4', socket:'478', ram:16, formfactor:'ATX', slot:['PCI-E', 'AGP']}. motherboard{id:'MB5', socket:'7', ram:4, formfactor:'BTX', slot:['AGP']}. :-local struct( cpu(id, type, manufacturer, freqmin, freqmax, socket, power) ). cpu{id:'C1', type:'Athlon64', manufacturer:'AMD', freqmin:1.8, freqmax:2.4, socket:'754', power:100}. cpu{id:'C2', type:'Athlon64', manufacturer:'AMD', freqmin:1.8, freqmax:2.6, socket:'939', power:115}. cpu{id:'C3', type:'Athlon64', manufacturer:'AMD', freqmin:2.0, freqmax:2.6, socket:'AM2', power:130}. cpu{id:'C4', type:'Turion64', manufacturer:'AMD', freqmin:1.6, freqmax:2.4, socket:'754', power:80}. cpu{id:'C5', type:'Core2Duo', manufacturer:'Intel', freqmin:1.8, freqmax:3.2, socket:'775', power:90}. cpu{id:'C6', type:'Pentium4', manufacturer:'Intel', freqmin:1.3, freqmax:2.0, socket:'775', power:120}. cpu{id:'C7', type:'Pentium4', manufacturer:'Intel', freqmin:1.3, freqmax:2.0, socket:'478', power:120}. :-local struct( gpu(id, slot, power, benchmark) ). gpu{id:'G1', slot:'AGP', power:125, benchmark:1000}. gpu{id:'G2', slot:'PCI-E', power:160, benchmark:1500}. gpu{id:'G3', slot:'PCI-E', power:250, benchmark:2000}. % The method to get one solution is (until now): main( HDD_ID, HDD_FORMFACTOR, HDD_CAPACITY, HDD_SONE, C_ID, C_TYPE, C_COLOR, C_POWER, C_FORMFACTOR, M_ID, M_SOCKET, M_RAM, M_FORMFACTOR, M_SLOT, CPU_ID, CPU_TYPE, CPU_MANUFACTURER, CPU_FREQMIN, CPU_FREQMAX, CPU_SOCKET, CPU_POWER, GPU_ID, GPU_SLOT, GPU_POWER, GPU_BENCHMARK ) :- %% structs hdd{id:HDD_ID, formfactor:HDD_FORMFACTOR, capacity:HDD_CAPACITY, sone:HDD_SONE}, case{id:C_ID, type:C_TYPE, color:C_COLOR, power:C_POWER, formfactor:C_FORMFACTOR}, motherboard{id:M_ID, socket:M_SOCKET, ram:M_RAM, formfactor:M_FORMFACTOR, slot:M_SLOT}, cpu{id:CPU_ID, type:CPU_TYPE, manufacturer:CPU_MANUFACTURER, freqmin:CPU_FREQMIN, freqmax:CPU_FREQMAX, socket:CPU_SOCKET, power:CPU_POWER}, gpu{id:GPU_ID, slot:GPU_SLOT, power:GPU_POWER, benchmark:GPU_BENCHMARK}, %% constraints (foreign keys for the DB) M_SOCKET = CPU_SOCKET, member(M_FORMFACTOR, C_FORMFACTOR), member(GPU_SLOT, M_SLOT), +(GPU_POWER, CPU_POWER, Temp1), /(Temp1, 1.4, Temp2), C_POWER >= Temp2, %% management constraints (the boss says, this has to be!!) constraint1(GPU_BENCHMARK, C_TYPE). constraint1(GPU_BENCHMARK, 'Big') :- GPU_BENCHMARK >= 2000. constraint1(GPU_BENCHMARK, _) :- GPU_BENCHMARK < 2000. With the main-method I get all solutions one by one. But I just need the remaining domains reduced by invalid domain values, but not all possible remaining solutions. This could be extracted by looping all solutions and listing all domain values that occur at least once (using findall/3 or setof/3 or something alike), but this works too slow. Based on this example I am interested in the following answers: 1. at start no initial values -> find all possible solutions one by one 2. at start some fine initial values -> find remaining domain values 3. at start some fine and some invalid values -> find solution by adjusting minimum invalid values 4. at start some required and some tentative values -> find solution by adjusting tentative values only So now I hope one of you can help me with this problem or at least can show me a direction where to search for a solution. Thanks, Tobias
This archive was generated by hypermail 2.2.0 : Thu Feb 02 2012 - 02:31:58 CET