-
Notifications
You must be signed in to change notification settings - Fork 0
/
choose.sql
85 lines (84 loc) · 2.86 KB
/
choose.sql
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
-- --------------------------------------------------------------------------------
-- Routine DDL
-- Note: comments before and after the routine body will not be stored by the server
-- --------------------------------------------------------------------------------
DELIMITER $$
CREATE PROCEDURE `choose` (IN p INT,OUT q INT)
BEGIN
-- temporary tables
CREATE TEMPORARY TABLE filtered
LIKE seances;
CREATE TEMPORARY TABLE probs (
solution_id INT,
priori DOUBLE);
BEGIN
-- values
DECLARE done, inner_done BOOLEAN DEFAULT FALSE;
DECLARE h, p_sol, p DOUBLE;
DECLARE h_max DOUBLE DEFAULT 0;
DECLARE f_count INT;
-- containers
DECLARE q_id, sol_id, ans INT;
-- cursor
DECLARE cur_q CURSOR FOR
SELECT question_id FROM questions;
-- handler
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
-- action time
OPEN cur_q;
WHILE NOT done DO
FETCH cur_q INTO q_id;
-- filter seances
-- by presence of current question
DELETE FROM filtered;
SELECT IF( EXISTS(
SELECT seance_id FROM seance_log
WHERE question_id = q_id
), (SELECT * FROM seances
WHERE seance_id IN (
SELECT DISTINCT seance_id FROM seance_log
WHERE question_id = q_id
)), (SELECT * FROM seances));
SELECT COUNT(*) FROM filtered INTO f_count;
-- calculate solution probabilities
-- based on seance count in filtered table
BEGIN
DECLARE cur_s CURSOR FOR
SELECT solution_id FROM solutions;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET inner_done = TRUE;
DELETE FROM probs;
OPEN cur_s;
WHILE NOT inner_done DO
FETCH cur_s INTO sol_id;
INSERT INTO probs (solution_id, priori)
SELECT sol_id, count/f_count
FROM filtered
WHERE solution_id = sol_id;
END WHILE;
CLOSE cur_s;
SET inner_done = FALSE;
END;
-- calculate answer probability
-- based on aforementioned (and calculated) priori
-- and answer probability given that solution is right
SET ans = 0;
SET h = 0;
WHILE ans < 5 DO
SET ans = ans + 1;
SELECT SUM(count)*priori/f_count
FROM filtered INNER JOIN probs
ON filtered.seance_id = probs.seance_id
WHERE seance_id IN (
SELECT DISTINCT seance_id
FROM seance_log
WHERE answer = ans
) INTO p;
SET h = h - p * LOG(p);
END WHILE;
SELECT IF (h > h_max, q_id, q) INTO q;
SELECT IF (h > h_max, h, h_max) INTO h_max;
END WHILE;
CLOSE cur_q;
SELECT IF((SELECT p),(SELECT solution_id FROM probs ORDER BY priori DESC LIMIT 1),(SELECT q)) INTO q;
END;
END