/**
Newspaper headline checker
(To be written after projected date of end of world - which shall have not happened:)
Ceiba Tree Survives Alleged Apocalypse
e.g. build a fire
fold(+Length1, +Folds, -Mountain_folds, -Valley_folds)
(+ means input, - means output)
Fold/4 folds a card of certain length into a certain number of folds, forming a zig-zag shape.
Length1 is the length of the card.
Folds is the number of folds which will be made in the card.
Mountain_folds are the positions of the mountain folds.
Valley_folds is the positions of the valley folds.
For example, it folds a 0.1 m card in 9 places, when the following query is executed.
fold(0.1, 9, Mountain_folds, Valley_folds).
The leftmost fold is a mountain fold, which is a fold with the section on the left side ascending, and the section on the right side descending. A valley fold is the section on the left side descending, and the section on the right side ascending. The card has a mountain fold at 0.01 m, a valley fold at 0.02 m, a mountain fold at 0.03 m, a valley fold at 0.04 m and so on until the last mountain fold at 0.09 m. This is shown by the following output.
Mountain_folds = [0.01, 0.03, 0.05, 0.07, 0.09],
Valley_folds = [0.02, 0.04, 0.06, 0.08] ;
**/
fold(Length1,Folds,Mountain_folds,Valley_folds) :-
get_data(Length1, Folds, Length2, Length3, Length4, Length5),
fold(Length2,Length2,Length3,[],Mountain_folds),
fold(Length4,Length2,Length5,[],Valley_folds).
/**
get_data(+Length1, +Folds, -Length2, -Length3, -Length4, -Length5)
Get data/6 calculates the data needed to calculate the fold positions.
Length1 is the position of last fold calculated.
Folds is the number of folds which will be made in the card.
Length2 is the length of a section. It is also the length between the left side of the card and the first mountain fold.
Length3 is the length between the right-most mountain fold and the right edge of the card.
Length4 is the length between the left side of the card and the left-most valley fold.
Length5 is the length between the right-most valley fold and the right side of the card.
**/
get_data(Length1, Folds, Length2, Length3, Length4, Length5) :-
Sections is Folds + 1, %% Number of section the card will be folded into
Length2 is Length1 / Sections, %% Length of a section. It is also the length between the left side of the card and the first mountain fold
Length3 is Length1-Length2, %% Length between the right-most mountain fold and the right edge of the card
Length4 is 2 * Length2, %% Length between the left side of the card and the left-most valley fold
Length5 is Length1-Length4. %% Length between the right-most valley fold and the right side of the card
/**
fold(+Length1, +Length2, +Length3, +Folds1, -Folds2)
Fold/5 calculates the fold positions along the card, by multiplying the length between folds by two and adding it to the previous fold position, until the position of the last fold has been reached.
Length1 is the position of the previous fold calculated.
Length2 is the length between folds.
Length3 is the position of the last fold.
Folds1 are the previously calculated fold positions.
Folds2 are the positions of folds calculated.
**/
fold(Length, _, Length, Folds1, Folds2) :-
append(Folds1, [Length], Folds2), !.
fold(Length1, Length2, Length3, Folds1, Folds2) :-
Length4 is Length1 + (2 * Length2),
append(Folds1, [Length1], Folds3),
fold(Length4, Length2, Length3, Folds3, Folds2).
/**
Check Formula/4
Check Formula/4 checks a formula works with a set of values.
check_formula(Assignments, Formula_left_side, Formula_right_side, Result)
Check formula/4 checks the left side of the formula equals the right side of the formula with the values from the assignments substituted into them.
Assignments is the list of the variables and the values assigned to them.
Formula left side is the part of the formula on the left side of the equals sign.
Formula right side is the part of the formula on the right side of the equals sign.
Result equals 1 if the formula works, otherwise it equals 0.
check_formula([[c, 0.06], [a, 0.2], [b, 0.3]], c, a * b, Result).
Check formula/4 checks the formula c = a * b works with the values c = 0.06 m, a = 0.2 m and b = 0.3 m.
The result is 1, meaning the formula works, as shown by the following output.
Result = 1
**/
check_formula(Assignments, Formula_left_side, Formula_right_side, 1) :-
substitute(Assignments, Formula_left_side, Value),
substitute(Assignments, Formula_right_side, Value), !.
check_formula(_, _, _, 0).
/**
substitute(+Assignments, +Expr, -Value)
Substitute/3 substitutes the values for variables into Expr from Assignments, calculating Value.
Assignments is the list of the variables and the values assigned to them.
Expr is the current part of the formula.
Value is the value of the current part of the formula.
**/
substitute(Assignments, Expr1, Value1) :-
separate(Expr1, Expr2, Expr3, Operator),
substitute(Assignments, Expr2, Value2),
substitute(Assignments, Expr3, Value3),
evaluate(Value2, Value3, Operator, Value1).
substitute(Assignments, Expr, Value) :-
member([Expr, Value], Assignments).
separate(Expr1 / Expr2, Expr1, Expr2, /).
separate(Expr1 * Expr2, Expr1, Expr2, *).
separate(Expr1 + Expr2, Expr1, Expr2, +).
separate(Expr1 - Expr2, Expr1, Expr2, -).
evaluate(Value1, Value2, /, Value3) :-
Value3 is Value1 / Value2.
evaluate(Value1, Value2, *, Value3) :-
Value3 is Value1 * Value2.
evaluate(Value1, Value2, +, Value3) :-
Value3 is Value1 + Value2.
evaluate(Value1, Value2, -, Value3) :-
Value3 is Value1 - Value2.