! 9. Logical Expressions and Variables.			File: logical9.f90
!------------------------------------------------------------------------------!

PROGRAM logic
	IMPLICIT NONE

	! declarations
	REAL :: weight, one, ten, danger
	LOGICAL :: fat

	one = 1.0
	ten = 10.0
	danger = ((one/ten)**10)*(ten**10)

	! input
	PRINT *
	PRINT *, 'How much do you weigh (kg)?'
	PRINT *
	READ *, weight

	! assigning the value of a logical expression to a logical variable
	fat = weight > 75.0

	! output
	! printing the value of a logical expression
	PRINT *
	PRINT *, 'The statement'
	PRINT *
	PRINT *, '"You weigh less than 75kg" is ', weight < 75.0
	PRINT *
	PRINT *, 'while'
	PRINT *
	PRINT *, '"You weigh more than 75kg" is ', fat
	PRINT *

	! Danger: an example of roundoff error with REAL numbers	
	PRINT *, 'Expression ((1./10.)**10)*(10.**10) = 1 is ', danger == 1.0
	PRINT *

END PROGRAM logic


!! 1.	A logical variable can have only one of two values, .TRUE.  or  
!!	.FALSE.
!!
!!	A logical EXPRESSION likewise can take only these two logical values.
!!
!!	A logical expression consists of two arithmetic expressions (types
!!	INTEGER or REAL) on either side of a RELATIONAL OPERATOR.
!!
!!	Fortran has six relational operators:
!!
!!	Relational
!!	Operator	Expression		Value of the expression
!!	_________________________________________________________________
!!
!!	>   (.GT.)	a > b		True if a>b; false otherwise
!!	>=  (.GE.)	a >= b		True if a>=b; false otherwise
!!	<   (.LT.)	a < b		True if a<b; false otherwise
!!	<=  (.LE.)	a <= b		True if a<=b; false otherwise
!!	==  (.EQ.)	a == b		True if a=b; false otherwise
!!	/=  (.NE.)	a /= b		True if a is not equal to b;
!!						otherwise false
!!	The operands a,b must be of the same type.

!! 2. 	Exercises.
!!
!!	a) Given the integer variables 'year=1995' and 'index=7', real 
!!	variables 'atmass=2.054', 'pi=3.1415926' and 'weight=201.19999',
!!	determine the value of each of the following expressions. Check 
!!	your answers by writing test programs.
!!
!!		Expression				Value
!!		__________				_____
!!
!!	( 2.0 * pi ) /= 180.0				   ?
!!	200.0 <= ( weight - atmass )			   ?
!!	year > ( index * ( 20 + index )		 	   ?
!!	( index**4 ) /= ( year - 1900 )			   ?
!!	10.0 * atmass > weight			 	   ?
!!	(pi**index) >= (3.0*pi)				   ?
!!	(pi**2.0) == (pi*pi)				   ?
!!	(year - index) /= (index + 1977)		   ?
!!
!!	b) Suppose that 'year' and 'age' are integer variables. Which of the 
!!	following are legal Fortran expressions? Why?
!!
!!	year - (age == year) + age
!!	(year - age) == (year + age)
!!	(year - age == year) + age
!!	((year - age) == year) + age

!! 3.	Compound logical expressions
!!
!!	Suppose we wish to establish the truth or falsity of the statements
!!
!!	'It is raining today'  .AND.  'the temperature is below freezing'
!!
!!	'It is raining today'  .OR.   'the temperature is below freezing'
!!
!!	This is an example of a compound proposition which will have the value
!!	.TRUE. or .FALSE. . We can express the possible cases in the form of
!!	truth tables. These are quite straightforward when you become used to 
!!	them.
!!
!!	.AND. truth table:
!!
!!	Proposition A		Proposition B		Proposition A .AND. B
!!	______________		_____________		_____________________
!!
!!	true			true				true
!!	true			false				false
!!	false			true				false
!!	false			false				false
!!
!!	.OR. truth table:
!!
!!	Proposition A		Proposition B		Proposition A .OR. B
!!	______________		_____________		_____________________
!!
!!	true			true				true
!!	true			false				true
!!	false			true				true
!!	false			false				false
!!
!!	These are two examples of logical operators which take propositions as
!!	operands. Another operator, frequently used, is the .NOT. operator 
!!	whose truth table is obvious.
!!
!!	.NOT. truth table:
!!
!!	Proposition A		.NOT. A
!!	_____________		_______
!!
!!	true			false
!!	false			true
!!
!!	example: .NOT. (it is raining today)  is  (it is not raining today)
!!
!!	Fortran has in fact five LOGICAL OPERATORS. These can only operate 
!!	on logical values. They are listed below operating on the 
!!	logical expressions le1 and le2.
!!
!!	Operator	Usage		Value of the compound expression
!!	________________________________________________________________
!!
!!	.NOT.		.NOT. le1	logically opposite to value of le1
!!	.AND.		le1 .AND. le2	true only if le1 and le2 are both 
!!					true; otherwise false.
!!	.OR.		le1 .OR. le2	false only if le1 and le2 are both
!!					false; otherwise true.
!!	.EQV.		le1 .EQV. le2	true only if le1 and le2 are both 
!!					true or both false; otherwise false.
!!	.NEQV.		le1 .NEQV.le2	true only if le1 and le2 differ in 
!!					their logical values; otherwise false.
!!
!!	Logical expressions may involve both relational and logical operators,
!!	as well as the arithmetic operators. This can become complicated, so
!!	hang on to your hats! In such cases, it is best to clarify expressions
!!	using parentheses. However, if you do not, Fortran has an order of 
!!	precedence:
!!
!!	Order of precedence		Operation
!!	___________________		_________
!!
!!		1 (highest)		Parentheses
!!		2			Arithmetic operators
!!		3			Character operators (see later)
!!		4			Relational operators
!!		5			.NOT.
!!		6			.AND.
!!		7			.OR.
!!		8 (lowest)		.EQV. and .NEQV.
!!
!!	examples: if A is .TRUE. and B is .FALSE. then
!!
!!			(A .AND. .NOT. B)  has value  .TRUE.
!!			(3 .LT. 4 .OR. B)  has value  .TRUE.
!!			(.NOT. A .AND. B)  has value  .FALSE.
!!			(A .EQV. B)        has value  .FALSE.

!! 4.	Exercises (continued).
!!
!!	c) Suppose we have the declarations and initializations
!!
!!		LOGICAL :: done=.FALSE.
!!		INTEGER :: year=1996
!!
!!	State the value of each logical expression below. If the expression is
!!	illegal and won't compile, say so.
!!
!!		i)	(.NOT. done) .OR. (year < 2000)
!!		ii)	(.NOT. done) .AND. (year < 2000)
!!		iii)	.NOT. (year < 2000)
!!		iv)	year .NOT. < 2000
!!		v)	year < 2000 .AND. .NOT. done
!!		vi)	year .NE. 2000 .AND. 2100
!!		vii)	done .OR. (.NOT. done)
!!		viii)	done .AND. .NOT. done
!!
!!	Write and execute a program to check the validity of one of the above
!!	expressions. For example, for i),
!!
!!
!!		PROGRAM trial
!!			IMPLICIT NONE
!!
!!			LOGICAL :: done=.FALSE.
!!			INTEGER :: year=1996
!!
!!			PRINT *, (.NOT. done) .OR. (year < 2000)
!!
!!		END PROGRAM trial

!! 	END OF FILE: logical9.f
