Skip to content

Commit 77f2684

Browse files
committed
refactored
1 parent 3ea663e commit 77f2684

5 files changed

Lines changed: 28 additions & 55 deletions

File tree

PrismaDotnetApi/PrismaApi.Api/Controllers/SolversController.cs

Lines changed: 8 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -73,64 +73,30 @@ public async Task<ActionResult<ApiResponseDto>> GetSolutionWithEvidenceAsync([Fr
7373
}
7474

7575
[HttpPost("solvers/project/{projectId:guid}/policy_table")]
76-
public async Task<ActionResult<List<PolicyTableDecisionOutgoingDto>>> GetPolicyTableAsync([FromRoute] Guid projectId, [FromBody] EvidenceRequestDto? evidence = null, CancellationToken ct = default)
76+
public async Task<ActionResult<List<PolicyTableOutgoingDto>>> GetPolicyTableAsync([FromRoute] Guid projectId, [FromBody] EvidenceRequestDto? evidence = null, CancellationToken ct = default)
7777
{
7878
UserOutgoingDto user = HttpContext.GetLoadedUser();
7979
var fastApiResponse = await _fastApiService.SendInfluenceDiagramPolicyTableToFastApiAsync(projectId, $"/solvers/project/{projectId}/policy_table", evidence, user, ct);
8080
if (fastApiResponse.StatusCode == HttpStatusCode.OK)
8181
{
82-
if (string.IsNullOrEmpty(fastApiResponse.Content))
82+
Dictionary<string, List<PolicyTableStatesOutgoingDto>> response = [];
83+
if (!string.IsNullOrWhiteSpace(fastApiResponse.Content))
8384
{
84-
return Ok(new List<PolicyTableDecisionOutgoingDto>());
85-
}
86-
87-
var response = JsonSerializer.Deserialize<Dictionary<string, List<Dictionary<string, JsonElement>>>>(
88-
fastApiResponse.Content,
89-
new JsonSerializerOptions
90-
{
91-
PropertyNameCaseInsensitive = true
92-
}
93-
);
94-
95-
if (response is null)
96-
{
97-
return Ok(new List<PolicyTableDecisionOutgoingDto>());
85+
response = JsonSerializer.Deserialize<Dictionary<string, List<PolicyTableStatesOutgoingDto>>>(
86+
fastApiResponse.Content
87+
) ?? [];
9888
}
9989

10090
var result = response
101-
.Select(kvp => new PolicyTableDecisionOutgoingDto
91+
.Select(kvp => new PolicyTableOutgoingDto
10292
{
10393
DecisionId = kvp.Key,
104-
Rows = kvp.Value.Select(row =>
105-
{
106-
var states = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
107-
double value = 0;
108-
109-
foreach (var entry in row)
110-
{
111-
if (string.Equals(entry.Key, "value", StringComparison.OrdinalIgnoreCase))
112-
{
113-
value = entry.Value.ValueKind == JsonValueKind.Number
114-
? entry.Value.GetDouble()
115-
: double.Parse(entry.Value.ToString());
116-
continue;
117-
}
118-
119-
states[entry.Key] = entry.Value.ToString();
120-
}
121-
122-
return new PolicyTableRowOutgoingDto
123-
{
124-
States = states,
125-
Value = value
126-
};
127-
}).ToList()
94+
Rows = kvp.Value
12895
})
12996
.ToList();
13097

13198
return Ok(result);
13299
}
133-
134100
return StatusCode((int)fastApiResponse.StatusCode, fastApiResponse.Content);
135101
}
136102
}

PrismaDotnetApi/PrismaApi.Domain/Dtos/PolicyTableDtos.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,20 @@
22

33
namespace PrismaApi.Domain.Dtos;
44

5-
public class PolicyTableRowOutgoingDto
5+
public class PolicyTableStatesOutgoingDto
66
{
77
[JsonPropertyName("states")]
8-
public Dictionary<string, string> States { get; set; } = [];
8+
public List<string> States { get; set; } = [];
99

1010
[JsonPropertyName("value")]
1111
public double Value { get; set; }
1212
}
1313

14-
public class PolicyTableDecisionOutgoingDto
14+
public class PolicyTableOutgoingDto
1515
{
1616
[JsonPropertyName("decision_id")]
1717
public string DecisionId { get; set; } = string.Empty;
1818

1919
[JsonPropertyName("rows")]
20-
public List<PolicyTableRowOutgoingDto> Rows { get; set; } = [];
20+
public List<PolicyTableStatesOutgoingDto> Rows { get; set; } = [];
2121
}

PrismaFastApi/src/routes/solver_routes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ async def get_policy_table_for_project(
136136
evidence: Optional[EvidenceIncomingDto] = None,
137137
solver_service: SolverService = Depends(get_solver_service),
138138
lock_manager: ProjectQueueManager = Depends(get_project_lock_manager),
139-
) -> dict[str, list[dict[str, str | float]]]:
139+
) -> dict[str, list[dict[str, list[str] | int]]]:
140140
async with lock_manager.acquire_project_lock(project_id):
141141
evidence_state_ids = evidence.state_ids if evidence else None
142142
return await solver_service.get_policy_table(

PrismaFastApi/src/services/pyagrum_solver.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -493,22 +493,29 @@ def add_virtual_utilities(self, issues: list[IssueOutgoingDto]):
493493
def fill_utilities(self, issues: list[IssueOutgoingDto]):
494494
[self.fill_utility_table(x) for x in issues]
495495

496-
def get_policy_table(self, decision_issue_id: str) -> list[dict[str, str | float]]:
496+
def get_policy_table(self, decision_issue_id: str) -> list[dict[str, list[str] | int]]:
497497
ie = self.get_inference()
498498
optimal_decision_tensor = ie.optimalDecision(decision_issue_id) # type: ignore
499499
return self._parse_policy_tensor(optimal_decision_tensor)
500500

501-
def _parse_policy_tensor(self, optimal_decision_tensor: Any) -> list[dict[str, str | float]]:
501+
def _parse_policy_tensor(
502+
self, optimal_decision_tensor: Any
503+
) -> list[dict[str, list[str] | int]]:
504+
"""Flatten a policy tensor into row objects with ordered state labels and value.
505+
506+
Iterates every Instantiation of the tensor, collects each variable's current
507+
label into `states` (in tensor variable order), and reads the cell value for
508+
that assignment. Integer-like values are emitted as int for cleaner output.
509+
"""
502510
inst: Any = gum.Instantiation(optimal_decision_tensor)
503511
variables: list[Any] = list(inst.variablesSequence())
504-
parsed_rows: list[dict[str, str | float]] = []
512+
parsed_rows: list[dict[str, list[str] | int]] = []
505513

506514
inst.setFirst()
507515
while not inst.end():
508-
row: dict[str, str | float] = {
509-
str(variable): str(variable.label(inst.val(variable))) for variable in variables
510-
}
511-
row["value"] = float(optimal_decision_tensor.get(inst))
516+
states = [str(variable.label(inst.val(variable))) for variable in variables]
517+
value: int = int(float(optimal_decision_tensor.get(inst)))
518+
row: dict[str, list[str] | int] = {"states": states, "value": value}
512519
parsed_rows.append(row)
513520
inst.inc()
514521
return parsed_rows

PrismaFastApi/src/services/solver_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ async def get_policy_table(
295295
discrete_probabilities: list[DiscreteProbabilityOutgoingDto],
296296
discrete_utilities: list[DiscreteUtilityOutgoingDto],
297297
evidence: Optional[list[uuid.UUID]] = None,
298-
) -> dict[str, list[dict[str, str | float]]]:
298+
) -> dict[str, list[dict[str, list[str] | int]]]:
299299
solver = PyagrumSolver()
300300
ie = await solver.build_inference_engine(
301301
issues=issues,

0 commit comments

Comments
 (0)