Compare commits

...

3 Commits

Author SHA1 Message Date
38642e593e Merge pull request '#21 -- Add rules generation' (#30) from 21-generate-rules into master
All checks were successful
CI fuzzy controller / container-test-job (push) Successful in 1m5s
Reviewed-on: #30
2025-03-19 16:48:08 +04:00
017ecf7cd5 #21 -- Fix rules generation
All checks were successful
CI fuzzy controller / container-test-job (push) Successful in 1m3s
2025-03-15 22:22:12 +04:00
17759d3d83 #21 -- Add rules generation
All checks were successful
CI fuzzy controller / container-test-job (push) Successful in 1m4s
2025-03-15 12:49:49 +04:00
11 changed files with 148 additions and 12 deletions

View File

@ -9,6 +9,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.ulstu.fc.project.service.ProjectRulesService;
import ru.ulstu.fc.rule.model.FuzzyRule;
import ru.ulstu.fc.rule.model.dto.FuzzyRuleDataDto;
import ru.ulstu.fc.rule.model.dto.FuzzyRuleDto;
import ru.ulstu.fc.rule.service.FuzzyRuleParseService;
import ru.ulstu.fc.rule.service.FuzzyRuleService;
@ -53,7 +54,12 @@ public class FuzzyRuleRestController {
}
@PostMapping("parse/{projectId}")
public void parseRule(@PathVariable("projectId") Integer projectId, String data) {
fuzzyRuleParseService.parseFuzzyRules(data, projectId);
public List<FuzzyRule> parseRule(@PathVariable("projectId") Integer projectId, String data) {
return fuzzyRuleParseService.parseFuzzyRules(data, projectId);
}
@PostMapping("generate-rules/{projectId}")
public void generateRules(@PathVariable("projectId") Integer projectId, FuzzyRuleDataDto fuzzyRuleDataDto) {
fuzzyRuleParseService.generateRules(projectId, fuzzyRuleDataDto);
}
}

View File

@ -20,9 +20,11 @@ public class FuzzyTermForm {
}
public FuzzyTermForm(Integer id, Integer projectId, Integer variableId) {
this.projectId = projectId;
this.variableId = variableId;
this.id = id;
this(id, projectId, variableId, null);
}
public FuzzyTermForm(Integer projectId, Integer variableId, String description, Double value) {
this(null, projectId, variableId, new FuzzyTerm(description, value));
}
public FuzzyTermForm(Integer id, Integer projectId, Integer variableId, FuzzyTerm fuzzyTerm) {

View File

@ -0,0 +1,22 @@
package ru.ulstu.fc.rule.model.dto;
public class FuzzyRuleDataDto {
private String[] fuzzyTerms;
private int window = 3;
public String[] getFuzzyTerms() {
return fuzzyTerms;
}
public void setFuzzyTerms(String[] fuzzyTerms) {
this.fuzzyTerms = fuzzyTerms;
}
public int getWindow() {
return window;
}
public void setWindow(int window) {
this.window = window;
}
}

View File

@ -20,6 +20,11 @@ public class FuzzyRuleDto {
this.projectId = projectId;
}
public FuzzyRuleDto(Integer projectId, String content) {
this.projectId = projectId;
this.content = content;
}
public FuzzyRuleDto(FuzzyRule fuzzyRule) {
this.id = fuzzyRule.getId();
this.projectId = fuzzyRule.getProject().getId();

View File

@ -1,6 +1,9 @@
package ru.ulstu.fc.rule.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.fc.project.model.Project;
import ru.ulstu.fc.rule.model.FuzzyRule;
@ -9,4 +12,8 @@ import java.util.List;
public interface FuzzyRuleRepository extends JpaRepository<FuzzyRule, Integer> {
List<FuzzyRule> findByProject(Project project);
@Query("DELETE FROM FuzzyRule fr WHERE fr.project.id = :projectId")
@Modifying
void deleteAllByProjectId(@Param("projectId") Integer projectId);
}

View File

@ -1,6 +1,7 @@
package ru.ulstu.fc.rule.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.fc.rule.model.FuzzyTerm;
@ -10,4 +11,8 @@ public interface FuzzyTermRepository extends JpaRepository<FuzzyTerm, Integer> {
@Query("SELECT v FROM Variable v LEFT JOIN v.fuzzyTerms ft WHERE ft = :fuzzyTerm")
Variable findByFuzzyTerm(@Param("fuzzyTerm") FuzzyTerm fuzzyTerm);
@Query("DELETE FROM FuzzyTerm ft WHERE ft in (SELECT v.fuzzyTerms FROM Variable v WHERE v.project.id = :projectId)")
@Modifying
void deleteAllByProjectId(@Param("projectId") Integer projectId);
}

View File

@ -1,6 +1,7 @@
package ru.ulstu.fc.rule.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import ru.ulstu.fc.project.model.Project;
@ -19,4 +20,8 @@ public interface VariableRepository extends JpaRepository<Variable, Integer> {
@Query("SELECT v FROM Variable v WHERE v.project = :project AND v.input = false")
List<Variable> getOutputByProject(@Param("project") Project project);
@Query("DELETE FROM Variable v WHERE v.project.id = :projectId")
@Modifying
void deleteAllByProjectId(@Param("projectId") Integer projectId);
}

View File

@ -2,12 +2,17 @@ package ru.ulstu.fc.rule.service;
import com.fuzzylite.Engine;
import com.fuzzylite.rule.Rule;
import jakarta.transaction.Transactional;
import org.springframework.stereotype.Service;
import ru.ulstu.fc.project.service.ProjectService;
import ru.ulstu.fc.rule.model.FuzzyRule;
import ru.ulstu.fc.rule.model.FuzzyTermForm;
import ru.ulstu.fc.rule.model.Variable;
import ru.ulstu.fc.rule.model.dto.FuzzyRuleDataDto;
import ru.ulstu.fc.rule.model.dto.FuzzyRuleDto;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
@ -22,17 +27,25 @@ public class FuzzyRuleParseService {
private final static String RU_IS_STATEMENT = "является";
private final static String RU_EQ_STATEMENT = "равно";
private final static String ENG_IS_STATEMENT = "is";
private final static String INPUT_VARIABLE_TEMPLATE_NAME = "fuzzyLevel";
private final static String OUTPUT_VARIABLE_TEMPLATE_NAME = "outputFuzzyLevel";
private final Engine fuzzyEngine;
private final VariableService variableService;
private final ProjectService projectService;
private final FuzzyTermService fuzzyTermService;
private final FuzzyRuleService fuzzyRuleService;
public FuzzyRuleParseService(Engine fuzzyEngine,
VariableService variableService,
ProjectService projectService) {
ProjectService projectService,
FuzzyTermService fuzzyTermService,
FuzzyRuleService fuzzyRuleService) {
this.fuzzyEngine = fuzzyEngine;
this.variableService = variableService;
this.projectService = projectService;
this.fuzzyTermService = fuzzyTermService;
this.fuzzyRuleService = fuzzyRuleService;
}
public List<Rule> parseRules(List<String> stringRules) {
@ -80,4 +93,61 @@ public class FuzzyRuleParseService {
.map(a -> new Variable(a.split(ENG_IS_STATEMENT)[0].trim()))
.toList();
}
@Transactional
public void generateRules(Integer projectId, FuzzyRuleDataDto fuzzyRuleDataDto) {
fuzzyTermService.clearTerms(projectId);
variableService.clearVariables(projectId);
fuzzyRuleService.clearRules(projectId);
createVariables(fuzzyRuleDataDto, projectId);
int ruleStartPos = 0;
List<String> terms = Arrays.stream(fuzzyRuleDataDto.getFuzzyTerms()).toList();
while (ruleStartPos + fuzzyRuleDataDto.getWindow() < terms.size()) {
StringBuilder stringRule = new StringBuilder("if ");
int antecedentStartPos = ruleStartPos;
int variableNum = 0;
int i = antecedentStartPos;
while (i < fuzzyRuleDataDto.getWindow() + antecedentStartPos) {
if (i > antecedentStartPos) {
stringRule.append(" and ");
}
stringRule
.append(INPUT_VARIABLE_TEMPLATE_NAME)
.append(variableNum)
.append(" is ")
.append(terms.get(i));
variableNum++;
i++;
}
stringRule
.append(" then ").append(OUTPUT_VARIABLE_TEMPLATE_NAME)
.append(" is ")
.append(terms.get(ruleStartPos + fuzzyRuleDataDto.getWindow()));
ruleStartPos++;
FuzzyRuleDto fuzzyRule = new FuzzyRuleDto(projectId, stringRule.toString());
fuzzyRuleService.save(fuzzyRule);
}
}
private void createVariables(FuzzyRuleDataDto fuzzyRuleDataDto, Integer projectId) {
List<String> uniqueTerms = new HashSet<>(Arrays.stream(fuzzyRuleDataDto.getFuzzyTerms()).toList()).stream().toList();
for (int i = 0; i < fuzzyRuleDataDto.getWindow(); i++) {
createVariable(INPUT_VARIABLE_TEMPLATE_NAME + i, true, projectId, uniqueTerms);
}
createVariable(OUTPUT_VARIABLE_TEMPLATE_NAME, false, projectId, uniqueTerms);
}
private void createVariable(String variableName, boolean isInput, Integer projectId, List<String> uniqueTerms) {
Variable variable = new Variable();
variable.setName(variableName);
variable.setInput(isInput);
variable = variableService.save(variable, projectId);
for (int j = 0; j < uniqueTerms.size(); j++) {
fuzzyTermService.save(new FuzzyTermForm(projectId, variable.getId(), uniqueTerms.get(j), Double.valueOf(j)));
}
}
}

View File

@ -10,11 +10,13 @@ import ru.ulstu.fc.rule.repository.FuzzyRuleRepository;
public class FuzzyRuleService {
private final FuzzyRuleRepository ruleRepository;
private final ProjectService projectService;
private final FuzzyRuleRepository fuzzyRuleRepository;
public FuzzyRuleService(FuzzyRuleRepository ruleRepository,
ProjectService projectService) {
ProjectService projectService, FuzzyRuleRepository fuzzyRuleRepository) {
this.ruleRepository = ruleRepository;
this.projectService = projectService;
this.fuzzyRuleRepository = fuzzyRuleRepository;
}
public FuzzyRule getById(Integer id) {
@ -29,15 +31,15 @@ public class FuzzyRuleService {
return new FuzzyRuleDto(getById(id));
}
public FuzzyRule save(FuzzyRuleDto ruleForm) {
public FuzzyRule save(FuzzyRuleDto fuzzyRuleDto) {
FuzzyRule rule;
if (ruleForm.getId() == null || ruleForm.getId() == 0) {
if (fuzzyRuleDto.getId() == null || fuzzyRuleDto.getId() == 0) {
rule = new FuzzyRule();
} else {
rule = getById(ruleForm.getId());
rule = getById(fuzzyRuleDto.getId());
}
rule.setProject(projectService.getById(ruleForm.getProjectId()));
rule.setContent(ruleForm.getContent());
rule.setProject(projectService.getById(fuzzyRuleDto.getProjectId()));
rule.setContent(fuzzyRuleDto.getContent());
return ruleRepository.save(rule);
}
@ -48,4 +50,8 @@ public class FuzzyRuleService {
public void checkIsCurrentUserFuzzyRuleWithThrow(FuzzyRule fuzzyRule) {
projectService.checkIsCurrentUserProjectWithThrow(fuzzyRule.getProject());
}
public void clearRules(Integer projectId) {
fuzzyRuleRepository.deleteAllByProjectId(projectId);
}
}

View File

@ -67,4 +67,8 @@ public class FuzzyTermService {
public void checkIsCurrentUserFuzzyTermWithThrow(FuzzyTerm fuzzyTerm) {
projectService.checkIsCurrentUserProjectWithThrow(fuzzyTermRepository.findByFuzzyTerm(fuzzyTerm).getProject());
}
public void clearTerms(Integer projectId) {
fuzzyTermRepository.deleteAllByProjectId(projectId);
}
}

View File

@ -85,4 +85,8 @@ public class VariableService {
.map(VariableDto::new)
.toList();
}
public void clearVariables(Integer projectId) {
variableRepository.deleteAllByProjectId(projectId);
}
}