How do I refactor this mess of if/else conditions so that it's more readable?
( Reverse_Path = [[]] -> Child = [c(New_Score,G1,Pos),P]
; otherwise -> Child = [c(New_Score,G1,Pos),P|Reverse_Path]
),
( memberchk(Child,NewAgenda) -> addChildren(Others,Reverse_Path,Current,NewAgenda,Target,Result)
; otherwise ->
( NewAgenda=[] -> BrandNewAgenda = [Child|NewAgenda]
; otherwise ->
(New_Score =< FP -> BrandNewAgenda = [Child|NewAgenda];
otherwise -> append(NewAgenda,[Child],BrandNewAgenda)
)
),
)).
-
\$\begingroup\$ What is the purpose of the code, apart from being a mess? \$\endgroup\$Roland Illig– Roland Illig2020年04月21日 05:00:02 +00:00Commented Apr 21, 2020 at 5:00
1 Answer 1
Generally speaking, you can resolve if/else logic by using multiple clauses for the same predicate, as multiple clauses implicitely represent 'or' or 'case', e.g.:
foo([[]], Child) :-
Child = [c(New_Score,G1,Pos),P].
foo(Reverse_Path, Child) :-
Child = [c(New_Score,G1,Pos),P|Reverse_Path].
bar(Reverse_Path, Child, NewAgenda, BrandNewAgenda) :-
memberchk(Child,NewAgenda),
addChildren(Others,Reverse_Path,Current,NewAgenda,Target,BrandNewAgenda).
bar(Reverse_Path, Child, [], BrandNewAgenda) :-
BrandNewAgenda = [Child].
bar(Reverse_Path, Child, NewAgenda, BrandNewAgenda) :-
New_Score =< FP,
BrandNewAgenda = [Child|NewAgenda].
bar(Reverse_Path, Child, NewAgenda, BrandNewAgenda) :-
append(NewAgenda, [Child], BrandNewAgenda).
main(Reverse_Path, BrandNewAgenda) :-
foo(Reverse_Path, Child),
bar(Reverse_Path, Child, [], BrandNewAgenda).
This is just a rough sketch, there are a lot of loose ends here like variables Others
, Target
or Result
(I guess you are juggling too many variables anyway), but I hope you get the gist of it:
- Decompose into multiple simpler predicates that encode alternatives through multiple clauses.
- Bind results to "out" variables in the clause head (like
Child
infoo/2
orBrandNewAgenda
inbar/4
). - Compose the smaller predicates in a "main" predicate that glues them togehter.