V4: Crypto Problem Generator and Solver - CSC 366 Home Page - Demo

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% File: crypto.pro
%%% Line: Crypto Generation and Solver
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Load other files

% load combosets.pro
:- consult('../combosets.pro').

% Load global variables ADT 
:- consult('../../a6/gv2.pro').

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Generating Cryptos

% Generate a random number N within the previously specified range
generateRandomCryptoNumber(N) :-
  random(0,16,N).

% Generate a random Crypto problem and add it to the KB
generateRandomCryptoProblem :-
  generateRandomCryptoNumber(N1),
  generateRandomCryptoNumber(N2),
  generateRandomCryptoNumber(N3),
  generateRandomCryptoNumber(N4),
  generateRandomCryptoNumber(N5),
  generateRandomCryptoNumber(GoalNum),
  addCryptoProblemToKB(N1,N2,N3,N4,N5,GoalNum).

% Add the Crypto problem to the KB when another already exists

addCryptoProblemToKB(N1,N2,N3,N4,N5,G) :-
  retract(problem(_,_)),
  assert(problem(numbers(N1,N2,N3,N4,N5),goal(G))).

% Add the Crypto problem when the KB is empty
addCryptoProblemToKB(N1,N2,N3,N4,N5,G) :-
  assert(problem(numbers(N1,N2,N3,N4,N5),goal(G))).

% Display the Crypto Problem present in the KB
displayProblem :-
problem(numbers(N1,N2,N3,N4,N5),goal(G)),
  write('Numbers = { '),
  write(N1),write( ', '),
  write(N2),write( ', '),
  write(N3),write( ', '),
  write(N4),write( ', '),
  write(N5),write( ' } Goal = '),
  write(G),nl.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Crypto Solver

% Crypto Order 2 Solver

crypto(N1,N2,Goal,ex(N1,+,N2)) :- Goal is ( N1 + N2 ).
crypto(N1,N2,Goal,ex(N1,*,N2)) :- Goal is ( N1 * N2 ).
crypto(N1,N2,Goal,ex(N1,-,N2)) :- Goal is ( N1 - N2 ).
crypto(N1,N2,Goal,ex(N2,-,N1)) :- Goal is ( N2 - N1 ).
crypto(N1,N2,Goal,ex(N1,/,N2)) :- N2 > 0, Goal is ( N1 / N2 ).
crypto(N1,N2,Goal,ex(N2,/,N1)) :- N1 > 0, Goal is ( N2 / N1 ).

% Crypto Order 3 Solver

crypto(N1,N2,N3,Goal,Expression) :-
  combos(set(N1,N2,N3),combo(A,B),extras(C)),
  crypto(A,B,SubGoal,SubGoalExpr),
  crypto(C,SubGoal,Goal,UltGoalExpr),
  substitute(SubGoalExpr,SubGoal,UltGoalExpr,Expression).

% Crypto Order 4 Solver

crypto(N1,N2,N3,N4,Goal,Expression) :-
  combos(set(N1,N2,N3,N4),combo(A,B),extras(C,D)),
  crypto(A,B,SubGoal,SubGoalExpr),
  crypto(C,D,SubGoal,Goal,UltGoalExpr),
  substitute(SubGoalExpr,SubGoal,UltGoalExpr,Expression).

% Crypto Order 5 Solver

crypto(N1,N2,N3,N4,N5,Goal,Expression) :-
  combos(set(N1,N2,N3,N4,N5),combo(A,B),extras(C,D,E)),
  crypto(A,B,SubGoal,SubGoalExpr),
  crypto(C,D,SubGoal,AlmostGoal,AlmostUltGoalExpr),
  crypto(E,AlmostGoal,Goal,UltGoalExpr),
  substitute(SubGoalExpr,SubGoal,AlmostUltGoalExpr,SubExpression),
  substitute(SubExpression,AlmostGoal,UltGoalExpr,Expression).

% Substitute Crypto Solution Expressions for Formatting

substitute(New,Old,ex(Old,O,Z),ex(New,O,Z)).
substitute(New,Old,ex(X,O,Old),ex(X,O,New)).
substitute(New,Old,ex(X,O,Z),ex(Q,O,Z)) :-
  substitute(New,Old,X,Q).
substitute(New,Old,ex(X,O,Z),ex(X,O,Q)) :-
  substitute(New,Old,Z,Q).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% NEW CODE

establishSpecificCryptoProblem(N1,N2,N3,N4,N5,G) :-
  addCryptoProblemToKB(N1,N2,N3,N4,N5,G).

solveProblemDecompositionally :- 
  getProblemFromKnowledgeBase(N1,N2,N3,N4,N5,G),
  crypto(N1,N2,N3,N4,N5,G,Expression),
  addCryptoSolutionToKB(Expression).

solveProblemDecompositionally :-
  write('No solution to this one!'),nl.

getProblemFromKnowledgeBase(N1,N2,N3,N4,N5,G) :-
  problem(numbers(N1,N2,N3,N4,N5),goal(G)).

addCryptoSolutionToKB(Expression) :-
  retract(solution(_)),
  assert(solution(Expression)).

addCryptoSolutionToKB(Expression) :-
  assert(solution(Expression)).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%Display Solution

displaySolution :-
  write('Solution: '),
  solution( S ),
  displayResult( S ),
  nl.
displaySolution.

displayResult(ex(A,O,B)) :-
  number(A),number(B),
  write('( '),write(A),write(' '),write(O),
  write(' '),write(B),write(' )').

displayResult(ex(A,O,B)) :-
  number(A), B = ex(A1,O1,B1),
  write('( '),write(A),write(' '),write(O),write(' '),
  displayResult(ex(A1,O1,B1)),write(' )').

displayResult(ex(A,O,B)) :-
  number(B), A = ex(A1,O1,B1),
  write('( '),displayResult(ex(A1,O1,B1)),write(' '),
  write(O),write(' '),write(B),write(' )').

displayResult(ex(A,O,B)) :-
  A = ex(A1,O1,B1), B = ex(A2,O2,B2),
  write('( '),displayResult(ex(A1,O1,B1)),write(' '),write(O),
  write(' '),displayResult(ex(A2,O2,B2)),write(' )').

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% Crypto Solver

solve(random) :-
  generateRandomCryptoProblem,
  displayProblem,
  solveProblemDecompositionally,
  displaySolution.

solve(numbers(N1,N2,N3,N4,N5),goal(G)) :-
  establishSpecificCryptoProblem(N1,N2,N3,N4,N5,G),
  displayProblem,
  solveProblemDecompositionally,
  displaySolution.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% DEMO

demo(0).
demo(N) :-
  solve(random),
  K is N - 1,
  demo(K).