1

I am attempting to traverse a graph I have constructed in prolog. The Graph is represent as a list of transitions of the form: next(FromState, ToState, Symbol) where FromState and ToState are nodes of the graph that are represented as: state(Number, IrrelevantVariable). Symbol can take many values but I am interested in only transitions with epsilon as the symbol. Given a group of StartStates I need to see what transitions have FromState = StartState and have Symbol = epsilon. If these two conditions are true I will add ToState to the end StartStates and add FromState to a list of visited nodes. I am having trouble doing so and my current program is not working for some reason. Any ideas why it isnt working? One of the issue seems to be when I use the member predicate to see if I have visited the state at the Head of the list it ends up unifying to make the member predicate true instead of actually checking Visited for Head on the first call of espsilon_closure_helper3

epsilon_closure_helper3([], [Transitions], Visited).

epsilon_closure_helper3([Head|Tail], Transitions, Visited) :-
  member(Head, Visited)
  ->
  epsilon_closure_helper2(Tail, Transitions, Visited)
  ;
  epsilon_closure_helper2(Head, Transitions, ClosureStates1),
  append(Tail, ClosureStates1, Tail1),
  sort(Tail1, Tail2),
  append(Vistited, [Head], Visited1),
  epsilon_closure_helper3(Tail2, Transitions, Visited1).


epsilon_closure_helper2(State, [], States) :-
  States = [State].

epsilon_closure_helper2(State, Transitions, States) :-
   Transitions = [Head|Tail],
   epsilon_closure_helper2(State, Tail, States1),
   Head = next(A, B, Symbol),
   (
   test_state(State, A, Symbol) -> append(States1, [B], States) ; 
   States = States1
   ).

  test_state(TargetState, State, Symbol) :-
    State = TargetState,
    Symbol = epsilon.

Sample Input: epsilon_closure_helper3([state(0, iv)], [next(state(0, iv), state(1, iv), epsilon), next(state(1, iv), state(2, iv), epsilon] Visited, Closure).

Output: Closure = [state(0, iv), state(1, iv), state(2, iv)]

Guy Coder
  • 24,501
  • 8
  • 71
  • 136
jewelltaylor9430
  • 109
  • 1
  • 15
  • 2
    What's the question? – Daniel Lyons Mar 06 '19 at 15:30
  • @DanielLyons My program is not working as of now. Any ideas why? – jewelltaylor9430 Mar 06 '19 at 17:13
  • @DanielLysons Any Idea how I can fix the issue with the member predicate to stop it from unifying with the Visited list on the first iteration of the recursion? I added a bit of an explanation above. – jewelltaylor9430 Mar 06 '19 at 17:29
  • Does your input and output have to be exactly the same as you have it in your question because it is an assignment, or can it be changed? I pretty sure I understand the assignment from what you wrote, but your structures I find a bit confusing. – Guy Coder Mar 06 '19 at 18:16
  • Of interest: Rosetta Code - [Floyd-Warshall_algorithm](https://rosettacode.org/wiki/Floyd-Warshall_algorithm#Prolog) in Prolog. – Guy Coder Mar 06 '19 at 18:55

1 Answers1

1

I know the structure is not the same as given in the question, but I also know that you are a student and need to understand and learn the code, so here is a solution that is not using the same structures as yours, but should help you learn and finish your assignment.

The graph is from this page.

transistion(a,b,0).
transistion(a,c,0).
transistion(a,a,1).
transistion(a,b,epsilon).
transistion(b,b,1).
transistion(b,c,epsilon).
transistion(c,c,0).
transistion(c,c,1).

epsilon_closure(End_state,States) :-
    epsilon_closure(End_state,[],States).

epsilon_closure(End_state,States0,States) :-
    bagof([Start,End,Transistion],transistion(Start,End,Transistion),Transitions),
    epsilon_closure_rec(End_state,Transitions,States0,States), !.

epsilon_closure_rec(End,[[Start_state,End,epsilon]|Transitions],States0,States) :-
    \+ memberchk(Start_state,States0),
    epsilon_closure(Start_state,States0,States1),
    epsilon_closure_rec(End,Transitions,States1,States).
epsilon_closure_rec(End,[[_,_,_]|Transitions],States0,States) :-
    epsilon_closure_rec(End,Transitions,States0,States).
% A state is an epsilon transition to itself
epsilon_closure_rec(End_state,[],States0,[End_state|States0]).

Notice that the code does not have any append/3, sort/2, =/2 or ->/2.

Example runs:

?- epsilon_closure(a,States).
States = [a].

?- epsilon_closure(b,States).
States = [b, a].

?- epsilon_closure(c,States).
States = [c, b, a].
Guy Coder
  • 24,501
  • 8
  • 71
  • 136
  • While I haven't tried it, the code could probably be further optimized by changing bagof like `bagof(Start,transistion(Start,End_state,epsilon),Starts)` and then refactoring from there. – Guy Coder Mar 06 '19 at 20:40
  • @jewelltaylor9430 If you figure these out on your own then you should post them as an additional answer and to 1) help others who find this question, 2) earn points for yourself. You get 5 points for an up-vote on a question, but get 10 points for an up-vote on an answer. – Guy Coder Mar 06 '19 at 22:35
  • @jewelltaylor9430 Another thing you can do is post your code to [Code Review](https://codereview.stackexchange.com/) and get pointers on what changes you can make. – Guy Coder Mar 06 '19 at 22:40
  • Unfortunately, since its school related I don't want other students to be able to see my answer a potentially copy it – jewelltaylor9430 Mar 07 '19 at 22:14
  • @jewelltaylor9430 Understood, but they can see my answer already. You should still post it in a few months. – Guy Coder Mar 07 '19 at 22:34